使用SMO从SQL Server收集数据非常慢

时间:2015-02-11 19:39:15

标签: sql-server powershell smo

我得到了这个Powershell脚本,它可以获取有关SQL Server是否安装在主机上的信息,并获取SQL Server版本和其他详细信息。

它从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个服务器列表超过一个小时)。

有没有办法加快这个过程?

1 个答案:

答案 0 :(得分:1)

您可以使用后台作业异步运行脚本(您必须使用3个cmdlet:start-jobget-jobreceive-job)。

引自About_remote_jobs

  

启动远程工作,将结果返回给本地计算机(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.