function Test-AreCriticalNagJobsRunning { <# .SYNOPSIS Checks Running Nag Jobs and returns whether or not it's safe to restart it. #> [CmdletBinding()] [OutputType([System.Boolean])] Param( [Parameter(Mandatory = $false)] [Alias("Minutes")] [int]$threshold = 5, [Parameter(Mandatory = $false)] [Alias("ConnectionString")] [string]$masterConnectionString ) $logLead = (Get-LogLeadName); $utcNow = (Get-Date).ToUniversalTime() Write-Verbose ("$logLead : utcNow is {0}" -f $utcNow) $utcNowTicks = $utcNow.Ticks Write-Verbose ("$logLead : utcNowTicks is {0}" -f $utcNowTicks) $utcThreshold = (Get-Date).ToUniversalTime().AddMinutes($threshold) Write-Verbose ("$logLead : utcThreshold is {0}" -f $utcThreshold) $utcThresholdTicks = $utcThreshold.Ticks Write-Verbose ("$logLead : utcThresholdTicks is {0}" -f $utcThresholdTicks) ## NAG_FIRED_TRIGGERS contains triggers in progress, and NAG_TRIGGERS contains scheduled triggers ## This query will return those within the threshold or which are currently firing $resourcesPath = Join-Path $PSScriptRoot "Resources" $triggerQueryPath = Join-Path $resourcesPath "TriggerQuery.sql" $triggerQuery = Get-Content $triggerQueryPath -Raw Write-Verbose ("$logLead : Checking for running jobs and jobs scheduled to run before {0}" -f $utcThreshold.ToLocalTime()) if (!$masterConnectionString) { $masterConnectionString = Get-MasterConnectionString } $conStrBuilder = New-Object System.Data.SqlClient.SqlConnectionStringBuilder($masterConnectionString) $conn = New-Object System.Data.SqlClient.SqlConnection $conn.ConnectionString = $conStrBuilder.ToString() $cmd = New-Object System.Data.SqlClient.SqlCommand($triggerQuery, $conn) $cmd.Parameters.Add("@now", $utcNowTicks) | Out-Null $cmd.Parameters.Add("@threshold", $utcThresholdTicks) | Out-Null try { $conn.Open() $sqlReader = $cmd.ExecuteReader() if ($sqlReader.HasRows) { while ($sqlReader.Read()) { $fireTime = $sqlReader.GetInt64(0) Write-Verbose ("$logLead : Fire ticks is {0}" -f $fireTime) $scheduledTime = $sqlReader.GetInt64(1) Write-Verbose ("$logLead : Scheduled ticks is {0}" -f $scheduledTime) $jobName = $sqlReader.GetString(2) if ($scheduledTime -gt 0 -or $fireTime -gt 0) { # This trigger/job is scheduled to execute within the threshold $friendlyTime = (New-Object System.DateTime($fireTime)).ToLocalTime().ToString("MM-dd-yyyy hh:mm:ss") $friendlyDateTime = [System.DateTime]::Parse($friendlyTime) if ($friendlyDateTime -gt (Get-Date)) { # This trigger/job is currently executing # This scheduledTime variable is the original scheduled execution time, so the names can be a bit confusing $friendlyTime = (New-Object System.DateTime($scheduledTime)).ToLocalTime().ToString("MM-dd-yyyy hh:mm:ss") Write-Warning ("$logLead : <{0}> began run at {1}" -f $jobName, $friendlyTime) } else { Write-Warning ("$logLead : <{0}> is scheduled to run at {1}" -f $jobName, $friendlyTime) } } } } else { # No records found, we're good to recycle Write-Verbose "$logLead : No tasks running and none scheduled before the cutoff threshold" return $true } } finally { # Cleanup the System.Data.SqlClient objects if ($conn.State -ne [System.Data.ConnectionState]::Closed) { $conn.Close() } $conn = $null } }