Sql-Server

SMO、Powershell 和登錄失敗

  • August 22, 2019

背景

  • 在我目前的組織中,我們有一個執行 Powershell 腳本的 SQL 代理作業,最初基於Script All Server Level Objects to Recreate SQL Server

    • 這項工作編寫了一堆腳本,可以在我們需要進行災難恢復的情況下使用。
    • 我們的版本查詢一個單獨的數據庫,該數據庫列出了應該檢查的伺服器。
    • 在這份工作之前,我沒有使用過 Powershell,儘管我有過其他腳本編寫經驗(例如 Python)。
  • 我們還設置了所有伺服器,使用 SQL Server 代理在登錄失敗時向 DBA 發送電子郵件。

  • 我們的一個開發伺服器上有幾個數據庫,這些數據庫出於某些(對我而言)未知的業務目的而離線。

  • 當我們的 SQL 代理作業執行時,當涉及到該開發伺服器上的那些離線數據庫時,它總是會生成登錄失敗警報。我被要求查看是否有某種方法可以讓腳本跳過檢查離線數據庫以防止這些錯誤警報。

  • 我已經將警報的來源追溯到下面的函式。我相信這一點if($database.Status -eq 'Normal')是為了確保數據庫線上但它不起作用。

  • 基於其他一些線上閱讀,我嘗試用 替換if($database.Status -eq 'Normal')if ($database.IsAccessible)但在執行腳本時我仍然收到登錄失敗的警報電子郵件。

#Function to write out Database scripts
function ScriptOutDBObjects($serverObject, $objectType)
{
   foreach ($database in $srv.Databases)
   { 
       if($database.Status -eq 'Normal')
       {
           $objectPath = $scriptPath + $objectType +'\'
           if (!(Test-Path -Path $objectPath))
           {
               New-Item -ItemType Directory -Path $objectPath
           }
           $scriptingOptions.FileName = $objectPath + $database.Name.Replace(':','').Replace('\', '_') +'.sql'
           $database.Script($scriptingOptions)
       }
   }
}
  • 這項工作使用的是 Powershell 類型,但在本地電腦上執行 Powershell ISE 的程式碼時,我得到了相同的結果。

問題

Microsoft.SqlServer.Management.Smo會一直嘗試打開數據庫嗎?如果是這樣,是否有一些標誌或什麼我可以通過它使其不這樣做?

幾乎所有關於 Powershell/SMO 的問題的答案是少使用 SMO 對像模型,多使用 TSQL。例如

$dbs = Invoke-Sqlcmd "select name from sys.databases where state_desc = 'ONLINE'" 

foreach ($db in $dbs)
{
 $dbName = $db.Name
 #. . . 
}

做你正在做的事情的最好方法是使用dbatools——它是免費的、開源的、維護得很好並在很多地方使用——也經過了很好的測試。

如果我理解要點是,您正在做的事情是-simplifying disaster recovery with dbatools

如果您有更多問題,請回來。以上將幫助您實現目標,即為 DR 場景編寫整個配置或從伺服器中選擇的內容。

例如

# This will write hashed passwords to disk
Export-DbaLogin -SqlInstance workstation\sql2016 -Path C:\temp\logins.sql | Invoke-Item

引用自:https://dba.stackexchange.com/questions/245927