Sql-Server

使用 PowerShell 發現所有正在執行的 SQL Server 實例的最有效方法是什麼?

  • November 28, 2018

我的任務是發現在我們的域中執行的所有 SQL Server 實例。在某些情況下,每台伺服器有多個實例。我見過兩種不同的 PowerShell 方法來查找這些實例,但似乎都沒有找到所有實例。

  1. 使用 WMI
       $srvr = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer $computerName
   $instances = $srvr | ForEach-Object {$_.ServerInstances} | Select @{Name="fullName";Expression={$computerName +"\"+ $_.Name}}   
   return $instances

2)使用遠端系統資料庫(與 Get-SQLInstance 1一樣)

我遇到的最大問題是,並非我所知道的所有伺服器都使用 SQL Server WMI 提供程序執行,也不是所有伺服器都允許遠端註冊。有第三種方法嗎?我可以使用遠端桌面訪問所有伺服器,但我正在查看大約 30 台機器,並且希望盡可能避免手動步驟。這僅適用於 SQL Server 2008 及更高版本,雖然很高興了解其他 SQL Server 服務 (SSIS/SSAS/SSRS),但我主要關注的是 SQL Server 本身。

如果您想要一些對未來有用的東西,我可能會避免嘗試搜尋系統資料庫。多年來,SQL Server 的配置單元發生了一些變化,要跟上它可能會很麻煩。

使用 的方法SqlDataSourceEnumerator有時很不穩定,儘管我會使用它,但沒有具體證據表明實例在網路上。我相信它也取決於 SQL 瀏覽器服務,大多數時候我發現它被禁用了。

我將利用 WMI 類win32_ServiceGet-Service我使用它是因為它提供了比cmdlet更多的有關服務的資訊。

我通常將所有內容都編寫為函式,因為您實際上可以使用它來對服務進行日常檢查或驗證以進行故障排除。

function Get-ServiceStatus ([string[]]$server)
{
foreach ($s in $server)
{
  if(Test-Connection $s -Count 2 -Quiet)
  {
   Get-WmiObject win32_Service -Computer $s |
    where {$_.DisplayName -match "SQL Server"} | 
    select SystemName, DisplayName, Name, State, Status, StartMode, StartName
  }
}
}

這比我通常使用的要多一點,但以防其他人遇到並想要使用它。Test-Connection等同於ping myserver在 DOS 提示符下,標誌-Quiet只是讓它返回truefalse. 這將預設為 4 ping,因此設置-Count 2只會讓它執行兩次。

該變數[string[]]$server是一種用於聲明$server將接受伺服器名稱數組的方法。因此,此函式的範例呼叫可能類似於:

Get-ServiceStatus -server (Get-Content C:\temp\MyServerList.txt)

要麼

$servers = 'MyServer1','MyServer2','MyServer3'
Get-ServiceStatus -server $servers

編輯

值得注意的評論是上述確實取決於提供的伺服器列表。如果我沒有提供該列表,您還有其他一些選擇。

  • 如果我在 Active Directory 環境中,我可以使用 PowerShell 中的ActiveDirectory模組通過 cmdlet 拉取域中所有伺服器的列表Get-ADComputer。警告一句,但請確保您-Filter在大型域上使用良好的。
  • 我還簡單地對網路進行了 IP 掃描(經批准),該網路為我提供了發現埠 1433 開放的 IP 地址。我將獲取該 IP 列表並利用Get-ADComputer它來查找域電腦名稱,然後將其傳遞給上面的函式

例子:

Import-Module ActiveDirectory
$sList = $ipList | Select -ExpandProperty IP
$results = foreach ($i in $sList) { 
Get-ADComputer -Filter 'IPv4Address -eq $i' -Properties * | Select Name}
Get-ServiceStatus -server $results

編輯

建議的編輯使用Write-Verbose並添加 try/catch 塊,雖然這可能很有用,並且在大多數情況下是程式碼練習,我將把它留給想要使用此功能的人來添加額外的程式碼或功能。只是試圖提供一個基本的例子。我確實將SystemName屬性添加到輸出中以包含實際的伺服器名稱返回資訊,在其他功能上執行此操作通常不會一次將其用於多個伺服器,所以它讓我忘記了。

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