2013-04-30 112 views
2

我有一個奇怪的問題,大概只有100次出現。我有一個使用SQL的SMO庫進行數據庫備份的PowerShell腳本。下面是我用來解決該問題的相關代碼剪斷:PowerShell變量賦值隨機失敗

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null 
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | out-null 
$now = get-date 
######################################## 
$server = new-object Microsoft.SqlServer.Management.Smo.Server 
$server.ConnectionContext.StatementTimeout = 86400 # Allow backups to take up to 24 hours per database 
$databases = $server.Databases 
$script:totalsteps = $databases.count 
######################################## 
if($script:totalsteps -eq $null -or $script:totalsteps -eq 0) { 
    $body = "Backup start:" + $now.tostring("yyyy-MM-dd hh:mm:ss tt") + "`r`n" + 
     "Error: " + (get-date).tostring("yyyy-MM-dd hh:mm:ss tt") + "`r`n" + 
     "`$script:totalsteps: " + $script:totalsteps + "`r`n" + 
     "`$databases.count: " + $databases.count + "`r`n" + 
     "`$databases: " + $databases + "`r`n" + 
     "`$server: " + $server 
    send-mailmessage -from "[email protected]" -to "[email protected]" -subject "Server Null: $server" -smtpserver "mail.example.com" -body $body 
} 

的問題是,曾經在一段時間的if語句評價真實,我得到的是看起來的電子郵件,如:

Backup start: 2013-04-30 07:50:58 AM 
Error: 2013-04-30 08:02:19 AM 
$script:totalsteps: 
$databases.count: 4 
$databases: [master] [model] [msdb] [tempdb] 
$server: [serverA] 

值得注意的是,腳本開始時間與錯誤時間大約是11分鐘,這有點奇怪。我現在唯一的猜測是,服務器承受了很大的壓力,因此PowerShell默默地失敗了變量賦值,並且繼續前進。

99的100次if語句是錯誤的,我沒有收到電子郵件。我不明白爲什麼$script:totalsteps作業沒有100%的時間工作。有任何想法嗎?還有什麼可以嘗試解決此問題?

UPDATE

爲了測試懶惰評價理論,我已經改變了代碼爲:

System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null 
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | out-null 
$now = get-date 
######################################## 
$server = new-object Microsoft.SqlServer.Management.Smo.Server 
$server.ConnectionContext.StatementTimeout = 86400 # Allow backups to take up to 24 hours per database 
$databases = $server.Databases 
$script:totalsteps = $databases.count 
############ NEW NEW NEW NEW ########### 
if($script:totalsteps -eq $null -or $script:totalsteps -eq 0) 
{ 
    $script:totalsteps = $databases.count * 4 
    send-mailmessage -from "[email protected]" -to "[email protected]" -subject "Server Null: $server" -smtpserver "mail.example.com" -body "FIRST ATTEMPT" 
} 
######################################## 
if($script:totalsteps -eq $null -or $script:totalsteps -eq 0) 
{ 
    $body = "Backup start:" + $now.tostring("yyyy-MM-dd hh:mm:ss tt") + "`r`n" + 
     "Error: " + (get-date).tostring("yyyy-MM-dd hh:mm:ss tt") + "`r`n" + 
     "`$script:totalsteps: " + $script:totalsteps + "`r`n" + 
     "`$databases.count: " + $databases.count + "`r`n" + 
     "`$databases: " + $databases + "`r`n" + 
     "`$server: " + $server 
    send-mailmessage -from "[email protected]" -to "[email protected]" -subject "Server Null: $server" -smtpserver "mail.example.com" -body $body 
} 
+0

只是猜測這裏,但因爲任務是在'$ databases'變量的第一次訪問。我相信這些評估是懶惰的,所以當它試圖枚舉數據庫時可能會超時,因爲它首先需要打開一個連接。之後,您已經提取了數據,因此當您第二次使用該數據時可用。雖然有點難以驗證。 – carlpett 2013-04-30 13:45:46

+2

我會建議沿着'$ Error'變量發送郵件,它可能實際上包含原因 – carlpett 2013-04-30 13:46:28

+0

好的想法。一位同事建議在分配和if語句之間增加一個睡眠,所以我已經做到了。我還在電子郵件中添加了$ error變量。我敢打賭你第一次懶惰的評估是正確的。我可能會嘗試在if語句中重新分配變量以查看是否修復了它。但是,在我看到我剛剛做出的改變證明是否有用之後,我會嘗試一下。我將在第二天或第二天更新。 – 2013-04-30 14:51:58

回答

2

只是猜測這裏,但由於分配是在第一次訪問$databases變量:我相信對它們的評估是懶惰的,所以當它試圖枚舉數據庫時可能會超時,因爲它首先需要打開一個連接。之後,您已經提取了數據,因此當您第二次使用該數據時可用。雖然有點難以驗證。

我建議連同您的電子郵件$Error變量中發送爲好,它實際上可能包含的原因