我正在尝试创建一个脚本来查看.txt文档中的服务器列表,并查找该服务器上的SQL实例以及每个实例的sql service pack版本构建。脚本运行但不返回任何信息。我认为我遇到了$ svcPack变量和找到所需数据的相应变量。任何帮助都会受到极大的关注。感谢。
# Continue even if there are errors
$ErrorActionPreference = "Continue";
# load the SQL SMO assembly
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null
# Sets the server versions
$vs2005sp4 = "9.00.5000";
$vs2008sp3 = "10.00.5500.0";
$vs2008r2sp2 = "10.50.4000.0";
# EMAIL PROPERTIES
# Set the recipients of the report.
$users = "test@test.com"
#$users = "You@company.com" # I use this for testing by uing my email address.
#$users = "you@company.com", "manager@company.com", "etc@company.com"; # can be sent to individuals.
# REPORT PROPERTIES
# Path to the report
$reportPath = "c:\Scripts\Reports\";
# Report name
$reportName = "ServicePackRpt_$(get-date -format ddMMyyyy).html";
# Path and Report name together
$servicePackReport = $reportPath + $reportName
#Set colors for table cell backgrounds
$redColor = "#FF0000"
$greenColor = "#34F01F"
$yellowColor = "#F0EC22"
$orangeColor = "#F2991D"
$whiteColor = "#FFFFFF"
# Count if any computers have low disk space. Do not send report if less than 1.
$i = 0;
# Get computer list to check disk space
$servers = Get-Content "c:\Scripts\InPutFiles\servers.txt";
$datetime = Get-Date -Format "MM-dd-yyyy_HHmmss";
# Remove the report if it has already been run today so it does not append to the existing report
If (Test-Path $servicePackReport)
{
Remove-Item $servicePackReport
}
# Cleanup old files..
$Daysback = "-7"
$CurrentDate = Get-Date;
$DateToDelete = $CurrentDate.AddDays($Daysback);
Get-ChildItem $reportPath | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item;
# Create and write HTML Header of report
$titleDate = get-date -uformat "%m-%d-%Y - %A"
$header = "
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>
<title>Service Pack Report</title>
<STYLE TYPE='text/css'>
<!--
td {
font-family: Tahoma;
font-size: 11px;
border-top: 1px solid #999999;
border-right: 1px solid #999999;
border-bottom: 1px solid #999999;
border-left: 1px solid #999999;
padding-top: 0px;
padding-right: 0px;
padding-bottom: 0px;
padding-left: 0px;
}
body {
margin-left: 5px;
margin-top: 5px;
margin-right: 0px;
margin-bottom: 10px;
table {
border: thin solid #000000;
}
-->
</style>
</head>
<body>
<table width='100%'>
<tr bgcolor='#CCCCCC'>
<td colspan='7' height='25' align='center'>
<font face='tahoma' color='#003399' size='4'><strong>DTG Environment Service Pack Report for $titledate</strong></font>
</td>
</tr>
</table>
"
Add-Content $servicePackReport $header
# Create and write Table header for report
$tableHeader = "
<table width='100%'><tbody>
<tr bgcolor=#CCCCCC>
<td width='10%' align='center'>Server</td>
<td width='15%' align='center'>Instance</td>
<td width='5%' align='center'>Version Build</td>
<td width='10%' align='center'>Version Name</td>
</tr>
"
Add-Content $servicePackReport $tableHeader
# Start processing disk space reports against a list of servers
foreach($computer in $servers)
{
#$svcPacks = Get-WmiObject -ComputerName $computer -Class win32_volume | Where-object {$_.label -ne $null} | Sort-Object -property "name"
#$svcPacks = Get-WmiObject -ComputerName $computer -Class "__NAMESPACE" -namespace "root\Microsoft\SqlServer\ReportServer"
$svcPacks = New-Object -typeName Microsoft.SqlServer.Management.Smo.Server($computer)
$computer = $computer.toupper()
foreach($packs in $svcPacks)
{
#$instanceID = $packs.Instance;
$versionBuild = $packs.VersionString;
$versionName = $packs.ProductLevel;
$color = $redColor;
# Set background color to green if service pack is 2008r2 SP2
if($versionBuild -eq $vs2008r2sp2)
{
$color = $greenColor
# Set background color to yellow if service pack is 2008 SP3
if($versionBuild -eq $vs2008sp3)
{
$color = $yellowColor
# Set background color to orange if service pack is 2005 SP4
if($versionBuild -eq $vs2005sp4)
{
$color = $orangeColor
# Create table data rows
#<td width='15%' align='center'>$instanceID</td>
$dataRow = "
<tr>
<td width='10%'>$computer</td>
<td width='5%' align='center'>$versionBuild</td>
<td width='10%' align='center'>$versionName</td>
</tr>
"
# If statement needed to remove label that were null
If ($versionID -ne 'null')
{
Add-Content $servicePackReport $dataRow;
Write-Host -ForegroundColor DarkYellow "$computer $deviceID service pack build = $versionBuild";
$i++
}
}
}
}
}
}
# Create table at end of report showing legend of colors for the critical and warning
$tableDescription = "
</table><br><table width='20%'>
<tr bgcolor='White'>
<td width='10%' align='center' bgcolor='#34F01F'>SQL Server 2008 R2 with SP2 - " + $vs2008r2sp2 +"</td>
<td width='10%' align='center' bgcolor='#F0EC22'>SQL Server 2008 with SP3 - " + $vs2008sp3 +"</td>
<td width='10%' align='center' bgcolor='#F2991D'>SQL Server 2005 with SP4 - " + $vs2005sp4 +"</td>
</tr>
"
Add-Content $servicePackReport $tableDescription
Add-Content $servicePackReport "</body></html>"
# Send Notification if alert $i is greater then 0
if ($i -gt 0)
{
foreach ($user in $users)
{
Write-Host "Sending Email notification to $user"
$smtpServer = "test.com"
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$msg = New-Object Net.Mail.MailMessage
$msg.To.Add($user)
$msg.From = "NoReply@test.com"
$msg.Subject = "Environment Service Pack Report for $titledate"
$msg.IsBodyHTML = $true
$msg.Body = get-content $servicePackReport
$smtp.Send($msg)
$body = ""
}
}
答案 0 :(得分:0)
嗯,从它的外观来看,这是一个小错误。在评估$ VersionBuild时,您没有任何 else 语句。所以,如果它没有通过第一次评估:
if($versionBuild -eq $vs2008r2sp2)
然后它将不会继续,并评估它是否可能是其他版本。
我要做的另一件事是在if语句中使用-eq
,而不是使用-match
并缩短版本字符串。这样,如果版本字符串与版本字符串不完全匹配,则更有可能匹配。例如您试图检查版本$vs2005sp4 = "9.00.5000";
,但VersionString属性将返回"9.00.5000.00"
,如果您使用-eq
不起作用,但如果您使用-match
它将工作
因此,添加else语句,缩短版本字符串,并使用-match
代码块将如下所示:
# Sets the server versions
$vs2005sp4 = "9.00.5000";
$vs2008sp3 = "10.00.5500";
$vs2008r2sp2 = "10.50.4000";
#...
# Set background color to green if service pack is 2008r2 SP2
if($versionBuild -match $vs2008r2sp2)
{
$color = $greenColor
}
else
{
# Set background color to yellow if service pack is 2008 SP3
if($versionBuild -match $vs2008sp3)
{
$color = $yellowColor
}
else
{
# Set background color to orange if service pack is 2005 SP4
if($versionBuild -match $vs2005sp4)
{
$color = $orangeColor
# Create table data rows
#<td width='15%' align='center'>$instanceID</td>
$dataRow = "
<tr>
<td width='10%'>$computer</td>
<td width='5%' align='center'>$versionBuild</td>
<td width='10%' align='center'>$versionName</td>
</tr>
"
}
else
{
# If statement needed to remove label that were null
If ($versionID -ne 'null')
{
Add-Content $servicePackReport $dataRow;
Write-Host -ForegroundColor DarkYellow "$computer $deviceID service pack build = $versionBuild";
$i++
}
}
}
}
- 编辑
要回答@ user1700796的问题,我认为@ user1700796遇到的真正问题是该脚本不适用于具有多个实例的SQL服务器。即当你得到Smo.Server对象时:
$svcPacks = New-Object -typeName Microsoft.SqlServer.Management.Smo.Server($computer)
其中$computer
是服务器名称,并且在该服务器上有多个实例;返回单个 Smo.Server对象,该对象基本上是空的。即拉出VersionString会返回一个空字符串。
如果相反,您运行相同的命令,除了为每个实例输入完整的SQL服务器名称+实例名称,然后Smo.Server对象返回正确的信息。
这是因为Smo.Server对象使用SQL连接字符串连接到SQL服务器(请参阅ConnectionContext
属性),并且它一次只能连接到单个实例,并且不会枚举通过您可能期望的实例。
因此,您需要:
,而不是在Smo.Server对象上使用foreach循环