ps/Modules/Alkami.PowerShell.Services/Public/Test-AreCriticalNagJobsRunning.ps1
2023-05-30 22:51:22 -07:00

94 lines
3.8 KiB
PowerShell

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
}
}