阿仁's Blog

使用 PowerShell 檢查 SQL Agent Job 狀態

| Comments

其實是接續著前一篇 使用 PowerShell 執行 SQL Server Job.

當我們現在可以用 PowerShell 來呼叫指定的 SQL Job 執行時,
接下來的問題就會是這個 :

那? 我如何利用 PowerShell 來得知指定的 SQL Job 做完了沒?

原理其實也蠻容易的。(江湖一點絕,說出來不值錢。)
我們同樣是利用 SMO 來做到。

來,直接看 Code。

#Setup SQL param

$SQLServerName = 'TestServer'
$JobName = 'TestJob'
$JobRunTimeOutSec = 60

#Load SMO

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null

$srv = New-Object Microsoft.SqlServer.Management.SMO.Server("$SQLServerName")
$job = $srv.jobserver.jobs["$JobName"] 

if ($job) { 
    Write-Host "Starting SQL Agent Job $($JobName) on Server $($SQLServerName) $(Get-Date -format 'yyyy-MM-dd HH:mm:ss')"

    $job.Start()      #Run SQL Job

    Start-Sleep -s 1  #Wait for Job running


    $JobRunSec = 0
    while ($job.CurrentRunStatus -ne "Idle") {
        Write-Host "$(Get-Date -format 'yyyy-MM-dd HH:mm:ss') job.CurrentRunStatus = " + $job.CurrentRunStatus
        Start-Sleep -s 1
        $JobRunSec = $JobRunSec + 1
        $job.Refresh() #Refresh the Job status


        #If Job Run over 60 Sec. force break

        if ($JobRunSec -ge $JobRunTimeOutSec) {
            throw "Job : $JobName Run over $JobRunTimeOutSec Sec. force break"
            break
        }
    }
}

Write-Host "Ending SQL Agent Job $($JobName) on Server $($SQLServerName) $(Get-Date -format 'yyyy-MM-dd HH:mm:ss')"

其實關鍵在 $job.CurrentRunStatus 這裡。
這裡所取得的就是目前對應 SQL Job 的 Status。
做法簡單講就是利用這個資訊來判斷。

寫一個 While Loop 來判斷指定的 SQL Job 是不是已經執行完畢,進入 Idle 狀態。
如果沒有,就等 1 秒鐘 Refresh() 再判斷一次。
直到 SQL Job 執行完畢,進入 Idle Status。

這邊我另外再宣告了一個 $JobRunTimeOutSec 變數,
用來記錄所指定的 Job 執行多久要做 TimeOut。
(因為你知道,迴圈很多時候都是 Bug 的來源阿。)

以上面的 Code 來看的話,
當執行時間超過 60 Sec. 時,
我會強制跳出迴圈,並 throw Error Message 出來。

Reference

https://docs.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.management.smo.agent.job?view=sqlserver-2016
https://docs.microsoft.com/zh-tw/dotnet/api/microsoft.sqlserver.management.smo.database.refresh?view=sqlserver-2016

Comments

comments powered by Disqus