2014-01-14 25 views
0

我正在嘗試創建一個腳本以查看.txt文檔中的服務器列表,並查找該服務器上的SQL實例以及SQL Service Pack版本爲每個實例構建。腳本運行但不返回任何信息。我想我遇到了$ svcPack變量和查找所需數據的相應變量的問題。任何幫助將大大appriciated。謝謝。使用PowerShell查找SQL Server實例和Service Pack

# 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 = "[email protected]" 
     #$users = "[email protected]" # I use this for testing by uing my email address. 
     #$users = "[email protected]", "[email protected]", "[email protected]"; # 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 = "[email protected]" 
     $msg.Subject = "Environment Service Pack Report for $titledate" 
     $msg.IsBodyHTML = $true 
     $msg.Body = get-content $servicePackReport 
     $smtp.Send($msg) 
     $body = "" 
    } 
    } 
+1

哇...整個腳本。如果你能把問題簡化成最簡單的形式,你更有可能得到答案。也就是說,您在確定服務包時遇到問題。向我們展示試圖做到這一點的代碼。 –

+0

每個循環都是我遇到麻煩的地方,特別是$ svcPacks對象,$ versionBuild和$ versionName。他們沒有從服務器中獲取這些信息。 – Skunny11

回答

0

那麼,從它的外觀來看,這是一個小錯誤。在評估您的$ VersionBuild時,您沒有任何其他陳述。所以如果第一次評估失敗:

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服務器名稱,並且在該服務器上有多個實例; a single Smo.Server對象被返回,它基本上是空的。即拉動VersionString返回一個空字符串。

相反,如果運行相同的命令,除了爲每個實例放入完整的SQL服務器名稱+實例名稱,Smo.Server對象將返回正確的信息。

這是因爲Smo.Server對象使用SQL連接字符串連接到SQL服務器(請參閱ConnectionContext屬性),它一次只能連接到一個實例,並且不會通過您的實例枚舉正如你可能期待的那樣。

所以,而是採用Smo.Server對象的foreach循環,您需要:

  • 首先在使用幾個命令,採取計算機名和枚舉的SQL Server實例的名稱該框
  • 採取這些SQL Server實例,並然後做一個foreach循環這些名稱
  • 您可以使用這些SQL Server實例的名稱,讓您的Smo.Server對象
  • 然後你可以再從Smo.Server對象中抽取版本字符串。
+0

謝謝我繼續解決這些問題。我仍然無法得到它返回有關每個服務器的信息。你會碰巧知道我的$ svcPack對象是否正確設置以及我的$ versionBuild和$ versionName變量?它不會從服務器上獲取任何信息。 – Skunny11

+0

請參閱編輯以回答上面的問題。 – HAL9256

+0

你太棒了,完美的工作,而不是讓代碼獲取實例列表,我只是將一個列表導出到一個txt文件中,然後即時運行該列表中的代碼,加快了運行時間。謝謝! – Skunny11

相關問題