使用 SMO 从 SQL 服务器收集数据非常慢
Collecting data from SQL Server using SMO is very slow
我得到了这个 Powershell 脚本,它获取有关 SQL 服务器是否安装在主机上的信息,并获取 SQL 服务器版本和其他详细信息。
它从 txt 文件中获取主机列表并将信息保存到 DataTable
。
$data = New-Object ('System.Data.DataTable')
$data.Columns.Add('Host name') | Out-Null
$data.Columns.Add('Ip Address') | Out-Null
$data.Columns.Add('SQL Server Product Name') | Out-Null
$data.Columns.Add('SQL Server Edition') | Out-Null
$data.Columns.Add('SQL Server Version') | Out-Null
$data.Columns.Add('SQL Server Type') | Out-Null
$data.Columns.Add('SQL Server Status') | Out-Null
Get-Content .\servers.txt | ForEach {
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
$row = $data.NewRow()
$row['Host name'] = $_
try {
$row['Ip Address'] = [Net.Dns]::GetHostEntry($_).AddressList.IpAddressToString
}
catch [System.Net.Sockets.SocketException] {
$row['Ip Address'] = 'Offline'
}
If ($row['Ip Address'] -eq 'Offline') {
$row['SQL Server Product Name'] = 'N/A'
$row['SQL Server Edition'] = 'N/A'
$row['SQL Server Version'] = 'N/A'
$row['SQL Server Type'] = 'N/A'
$row['SQL Server Status'] = 'N/A'
}
else {
$smo = New-Object ('Microsoft.SqlServer.Management.Smo.Server') $_
$row['SQL Server Product Name'] = $smo.Product + ' ' + $smo.ProductLevel
$row['SQL Server Edition'] = $smo.Edition
$row['SQL Server Version'] = $smo.VersionString
$row['SQL Server Type'] = $smo.ServerType
$row['SQL Server Status'] = $smo.Status
}
$smo.ConnectionContext.Disconnect()
$data.Rows.Add($row)
}
$data | Format-Table -AutoSize
这个脚本的问题是它需要很长时间才能运行(113台服务器的列表需要一个多小时)。
有什么方法可以加快这个过程吗?
您可以 运行 您的脚本异步使用后台作业(您必须使用 3 个 cmdlet:start-job
、get-job
和 receive-job
)。
START A REMOTE JOB THAT RETURNS THE RESULTS TO THE LOCAL COMPUTER (ASJOB)
To start a background job on a remote computer that returns the command
results to the local computer, use the AsJob parameter of a cmdlet such
as the Invoke-Command cmdlet.
When you use the AsJob parameter, the job object is actually created on
the local computer even though the job runs on the remote computer. When
the job is completed, the results are returned to the local computer.
You can use the cmdlets that contain the Job noun (the Job cmdlets) to
manage any job created by any cmdlet. Many of the cmdlets that have
AsJob parameters do not use Windows PowerShell remoting, so
you can use them even on computers that are not configured for
remoting and that do not meet the requirements for remoting.
我得到了这个 Powershell 脚本,它获取有关 SQL 服务器是否安装在主机上的信息,并获取 SQL 服务器版本和其他详细信息。
它从 txt 文件中获取主机列表并将信息保存到 DataTable
。
$data = New-Object ('System.Data.DataTable')
$data.Columns.Add('Host name') | Out-Null
$data.Columns.Add('Ip Address') | Out-Null
$data.Columns.Add('SQL Server Product Name') | Out-Null
$data.Columns.Add('SQL Server Edition') | Out-Null
$data.Columns.Add('SQL Server Version') | Out-Null
$data.Columns.Add('SQL Server Type') | Out-Null
$data.Columns.Add('SQL Server Status') | Out-Null
Get-Content .\servers.txt | ForEach {
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
$row = $data.NewRow()
$row['Host name'] = $_
try {
$row['Ip Address'] = [Net.Dns]::GetHostEntry($_).AddressList.IpAddressToString
}
catch [System.Net.Sockets.SocketException] {
$row['Ip Address'] = 'Offline'
}
If ($row['Ip Address'] -eq 'Offline') {
$row['SQL Server Product Name'] = 'N/A'
$row['SQL Server Edition'] = 'N/A'
$row['SQL Server Version'] = 'N/A'
$row['SQL Server Type'] = 'N/A'
$row['SQL Server Status'] = 'N/A'
}
else {
$smo = New-Object ('Microsoft.SqlServer.Management.Smo.Server') $_
$row['SQL Server Product Name'] = $smo.Product + ' ' + $smo.ProductLevel
$row['SQL Server Edition'] = $smo.Edition
$row['SQL Server Version'] = $smo.VersionString
$row['SQL Server Type'] = $smo.ServerType
$row['SQL Server Status'] = $smo.Status
}
$smo.ConnectionContext.Disconnect()
$data.Rows.Add($row)
}
$data | Format-Table -AutoSize
这个脚本的问题是它需要很长时间才能运行(113台服务器的列表需要一个多小时)。
有什么方法可以加快这个过程吗?
您可以 运行 您的脚本异步使用后台作业(您必须使用 3 个 cmdlet:start-job
、get-job
和 receive-job
)。
START A REMOTE JOB THAT RETURNS THE RESULTS TO THE LOCAL COMPUTER (ASJOB)
To start a background job on a remote computer that returns the command
results to the local computer, use the AsJob parameter of a cmdlet such
as the Invoke-Command cmdlet.
When you use the AsJob parameter, the job object is actually created on
the local computer even though the job runs on the remote computer. When
the job is completed, the results are returned to the local computer.
You can use the cmdlets that contain the Job noun (the Job cmdlets) to
manage any job created by any cmdlet. Many of the cmdlets that have
AsJob parameters do not use Windows PowerShell remoting, so
you can use them even on computers that are not configured for
remoting and that do not meet the requirements for remoting.