Sunday, 8 August 2010

OS patching - is the patch installed and if so, does it still need reboot?

#Description: This powershell script allows you to check the list of servers for: Server OS, SP, specific patch installed and if reboot is pending
#Purpose: To ensure the patch has been applied successfully for list of computers
#Designed to be run from commandline, output written into Excel sheet
#Tested with: Windows 2000, 2003, 2008
#Last edit by: MsMiller on 08/08/2010

$erroractionpreference = 'silentlycontinue'
#edit the KB patch number and the path to your server list
$kb = 'KB2286198'
$colComputers = get-content "c:\scripts\inputs\serverlist.txt"

#reg key to check
$key="SOFTWARE\Microsoft\Updates\UpdateExeVolatile"


#start excel
$a = New-Object -comobject Excel.Application
$a.visible = $True
$b = $a.Workbooks.Add()
$c = $b.Worksheets.Item(1)
$c.Cells.Item(1,1) = "IP address"
$c.Cells.Item(1,2) = "Ping"
$c.Cells.Item(1,3) = "Name"
$c.Cells.Item(1,4) = "Exception"
$c.Cells.Item(1,5) = "OS"
$c.Cells.Item(1,6) = "SP"
$c.Cells.Item(1,7) = "$kb Installed"
$c.Cells.Item(1,8) = "Requires Reboot"
$d = $c.UsedRange
$d.Interior.ColorIndex = 19
$d.Font.ColorIndex = 11
$d.Font.Bold = $True
$d.EntireColumn.AutoFit($True)
$intRow = 2

foreach ($strComputer in $colComputers)
{
#clear errors & variables
$error.psbase.clear()
$ping,$Reply,$obj,$obj_os,$checkkb,$regKey,$checkKey,$flags= $null
$c.Cells.Item($intRow, 1) = $strComputer
#try ping
 $ping = new-object System.Net.NetworkInformation.Ping
 $Reply = $ping.send($strComputer)
 if ($Reply.status –ne “Success”)
  {
   $c.Cells.Item($intRow, 2) = “Offline”
   $intRow = $intRow + 1
  }
 else
  {
   $c.Cells.Item($intRow, 2) = “Online”
#try to get Windows name
   $obj = gwmi win32_computersystem  -computername $strComputer
   $c.Cells.Item($intRow, 3) = $obj.name
   if ($error.count -ne 0)
   {
#give exception msg on error
    $c.Cells.Item($intRow, 4) = $error[0].exception.message
   }
   else
   {
#check OS & SP versions
    $obj_os = gwmi win32_operatingsystem -computer $strComputer
    $c.Cells.Item($intRow, 5) = $obj_os.caption
    $c.Cells.Item($intRow, 6) = $obj_os.csdversion
#check patch & reboot
    $checkkb = get-wmiobject Win32_QuickFixEngineering -computer $strComputer | where-object {$_.hotfixid -eq $kb} | select-object hotfixid
        if ($checkkb.hotfixid -eq $kb)
     {
     $c.Cells.Item($intRow, 7) = “Installed”
     $regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $strComputer)
     $checkKey = $regKey.OpenSubKey($key)
     if ($checkKey -ne $Null)
      {
      $flag = $checkKey.GetValue("Flags")
       if ($flag -eq 0)
        {
        $c.Cells.Item($intRow, 8) = “NO(withflag)”
        }
       else
        {
        $c.Cells.Item($intRow, 8) = “YES”
        }
      }
     else
      {
      $c.Cells.Item($intRow, 8) = “NO”
      }
     }
    else
     {
     $c.Cells.Item($intRow, 7) = “NOT Installed”
     }
   }
  $intRow = $intRow + 1
  }
 }