我有一個按預期運行的 SQL 查詢,但是當我嘗試在 PowerShell 'Invoke-SqlCmd' 模塊中使用它時,輸出與查詢資料庫時不同。我注意到關于這個模塊有很多問題,但我找不到適用于我的案例的問題。
詢問:
$SQLServer = "localhost"
$query = "SELECT Groups.[Name] AS AGname FROM sys.dm_hadr_availability_group_states States INNER JOIN master.sys.availability_groups Groups ON States.group_id = Groups.group_id WHERE primary_replica = @@Servername"
$HAGName = Invoke-Sqlcmd -query $query -ServerInstance $SQLServer -Database 'database'
if ($HAGName = !$null) {
write-host "Availability group name is $HAGName"
exit 0
}
else {
write-host "Failed to retrieve High Availability group name = [$HAGName]"
exit 1
}
PowerShell 中的輸出: “可用性組名稱為 True”
就像我提到的,當直接查詢 SQL Server 時,我得到了正確的輸出。我嘗試使用“OutputAs”開關,但沒有幫助。
任何幫助將不勝感激。
uj5u.com熱心網友回復:
所有的指標都在問題的評論中,但讓我系統地分解一下:
!$null是始終$true在PowerShell中:!/-not,該邏輯非運算子強制轉換$null為布爾,并且由于[bool] $null是$false,! $null是$true。$HAGName = !$null,由于使用=了賦值運算子,因此賦值$true給變數$HAGName。- 要改為執行相等比較,使用
-eq,在平等的運營商。
- 要改為執行相等比較,使用
因此,$null -eq $HAGName是您打算使用的(將$null放在LHS 上,以確保穩健性 - 請參閱檔案)。
但是,鑒于 PowerShell 的隱式 to-Boolean 強制規則(請參閱此答案的底部部分),if ($HAGName) { ... }在這種情況下您可以簡化為。
因此,對您的代碼進行更符合PowerShell 慣用的重構是:
$SQLServer = 'localhost'
$query = 'SELECT Groups.[Name] AS AGname FROM sys.dm_hadr_availability_group_states States INNER JOIN master.sys.availability_groups Groups ON States.group_id = Groups.group_id WHERE primary_replica = @@Servername'
$HAGName = Invoke-Sqlcmd -Query $query -ServerInstance $SQLServer -Database database
if ($HAGName) {
Write-Verbose -Verbose "Availability group name is: "
# Output the System.Data.DataRow instance as-is,
# which also results in proper for-display formatting.
# If you just want the value of the .AGname property (column), use
# $HAGName.AGname instead.
$HAGName
exit 0
}
else {
Write-Warning "Failed to retrieve High Availability group name."
exit 1
}
筆記:
成功案例隱式地將結果輸出到成功輸出流。
Write-Host通常是使用錯誤的工具,除非目的是僅寫入顯示,繞過成功輸出流,并且能夠將輸出發送到其他命令,將其捕獲到變數中,或將其重定向到檔案。到輸出的值,使用它本身; 例如,$value代替Write-Host $value(或使用Write-Output $value,盡管很少需要);看到這個答案我使用了一個
Write-Verbose呼叫(默認情況下它的輸出是安靜的,在這里我曾經-Verbose強制它顯示)來提供可選的補充/狀態資訊。$HAGName現在(隱式)[System.Data.DataRow]按原樣輸出Invoke-SqlCmd呼叫回傳的實體,這也會導致正確的顯示格式 -在可擴展(插值字串)中使用時,此類實體不會有意義地字串化;他們無益地字串化到他們的型別名稱,即逐字。System.Data.DataRow- 但是,如果您訪問行的特定屬性(列),則其值可能會有意義地字串化,具體取決于其資料型別;在您的情況下:`“可用性組名稱是 $($HAGName.AGname)”
- 要在字串中包含通常的顯示格式 - 使用類似
"Availability group name is $($HAGName | Out-String)"
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/348794.html
