James's profile"Funner" is not a word.BlogListsNetwork Tools Help

James

"Funner" is not a word.

August 15

Powershell and Windows Update (No forms)

This is a re-working of a previous script I wrote to install updates on your computer. This version does not use WinForms.
 
######################################################################################################################################
# Windows Update through Powershell (No Forms) v1.0 ######################################################################################################################################
clear-host
Write-host "Starting Update Process..." -foregroundcolor blue
Write-host ""
$UpdateSession = New-Object -com Microsoft.Update.Session
$UpdateSearcher = $UpdateSession.CreateupdateSearcher()
$SearchResult =  $UpdateSearcher.Search("IsAssigned=1 and IsHidden=0 and IsInstalled=0")
$UpdateLowNumber = 0
$UpdateHighNumber = 1
$NumberofUpdates = $searchResult.Updates.Count
while ($UpdateHighNumber -le $NumberofUpdates) {
$UpdatesToDownload = New-Object -com Microsoft.Update.UpdateColl
$Update = $searchResult.Updates.Item($UpdateLowNumber)
if ($Update.EulaAccepted -eq 0) {$Update.AcceptEula()}
[void]$UpdatesToDownload.Add($Update)
$Downloader = $UpdateSession.CreateUpdateDownloader()
$Downloader.Updates = $UpdatesToDownload
[void]$Downloader.Download()
$UpdatesToInstall = New-Object -com Microsoft.Update.UpdateColl
[void]$UpdatesToInstall.Add($Update)
$Title = $update.Title
$KBArticleIDs = $update.KBArticleIDs
$SecurityBulletinIDs = $update.SecurityBulletinIDs
$MsrcSeverity = $update.MsrcSeverity
$LastDeploymentChangeTime = $update.LastDeploymentChangeTime
$MoreInfoUrls = $update.MoreInfoUrls
Write-host "Installing Update $UpdateHighNumber of $NumberofUpdates"
Write-host "Title: $Title"
if ($KBArticleIDs -ne "") {Write-host "KBID: $KBArticleIDs"}
if ($SecurityBulletinIDs -ne "") {write-host "Security Bulletin: $SecurityBulletinIDs"}
if ($MsrcSeverity -eq "Critical") {Write-host "Rating: $MsrcSeverity" -foregroundcolor red} else {Write-host "Rating: $MsrcSeverity"}
if ($LastDeploymentChangeTime -ne "") {Write-host "Dated: $LastDeploymentChangeTime"}
if ($MoreInfoUrls -ne "") {Write-host "$MoreInfoUrls"}
$Installer = $UpdateSession.CreateUpdateInstaller()
$Installer.Updates = $UpdatesToInstall
$InstallationResult = $Installer.Install()
Write-host "--------------------------------------------"
if ($InstallationResult.ResultCode -eq "2") {Write-host "  Installation Succeeded" -foregroundcolor green}  else {Write-host "  INSTALLATION FAILED, check event log for details" -foregroundcolor red}
if ($InstallationResult.RebootRequired -eq "False") {Write-host "  Reboot not required" -foregroundcolor green} else {Write-host "  REBOOT REQUIRED" -foregroundcolor red}
Write-host "--------------------------------------------"
Write-host ""
Write-host ""
$Title = ""
$KBArticleIDs =  ""
$SecurityBulletinIDs =  ""
$MsrcSeverity =  ""
$LastDeploymentChangeTime =  ""
$MoreInfoUrls =  ""
$UpdateLowNumber = $UpdateLowNumber + 1
$UpdateHighNumber = $UpdateHighNumber + 1
if ($ProgressValue -lt $NumberofUpdates) {$ProgressValue = $ProgressValue + 1}
}
$ComputerStatus = New-Object -com Microsoft.Update.SystemInfo
 if ($ComputerStatus.RebootRequired -eq 1) {cmd /c $env:WinDir\System32\Shutdown.exe -r -f -t 10 -c "Patching Complete."}

 
April 22

WSUS 3.0 and Powershell

I installed WSUS 3.0 a few months back and given the size of the environment and the hardware I had at my disposal, it made perfect sense at that time to implement WSUS 3.0 on Windows Server 2003, Standard Edition (64-bit).

While the installation went without a hitch and clients reported in as I would expect, I turned to the WSUS API Samples to further automate a few tasks. To my dismay, I discovered that these binaries were written in 32-bit and could not properly query a 64-bit implementation of WSUS 3.0.

A little research lead me to the WSUS Team Blog where I was searching for a roadmap on 64-bit versions of the WSUS API Samples, when I uncovered some sample scripts for Powershell written by the WSUS team. Sweet!

With a little modification and testing of the samples, I have managed to build something that suits my needs from WSUS in terms of reports. These scripts also work in 32-bit versions of WSUS 3.0 and with WSUS 3.01 SP1.

What's Required:
WSUS 3.0 or higher 32-bit or 64-bit
.NET Framework 2.0 or higher
Powershell v1.0
A directory on your %SystemDrive% called, "Scripts"

What to be aware of:
Modify the following values as needed
$SmtpClient.Host = "YOURMAILSERVER.YOURDOMAIN.COM"
$MailMessage.from = "YOU@YOURDOMAIN.COM"
$MailMessage.To.add("SOMEONE@YOURDOMAIN.COM,SOMEONE@YOURDOMAIN.COM")
Uncomment out and modify the following variable if needed
# $MailMessage.Bcc.add(SOMEONE@YOURDOMAIN.COM)

What to do:
Paste the following code into a Powershell window, or save it as a Powershell file and execute it. This script will email the information as a 'csv' file attachment.

######################################################################################################################################
# Windows Update through Powershell v1.0
######################################################################################################################################

$ReportDate = Get-Date

Set-Content $ENV:SystemDrive\Scripts\MissingUpdatesBrief.csv """Server"",""Patches Needed"""

[reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | out-null

if (!$wsus) {
        $wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer();
}

$ComputerScope = new-object Microsoft.UpdateServices.Administration.ComputerTargetScope;
$ComputerScope.IncludedInstallationStates = [Microsoft.UpdateServices.Administration.UpdateInstallationStates]::NotInstalled;

$UpdateScope = new-object Microsoft.UpdateServices.Administration.UpdateScope;
$UpdateScope.IncludedInstallationStates = [Microsoft.UpdateServices.Administration.UpdateInstallationStates]::NotInstalled;

$Computers = $wsus.GetComputerTargets($ComputerScope);

$Computers | ForEach-Object {
$WsusComputerName = $_.FullDomainName
$UpdatesForReboot = $_.GetUpdateInstallationInfoPerUpdate($UpdateScope);
$UpdatesForReboot | foreach-object {
$NeededUpdate = $wsus.GetUpdate($_.UpdateId);
$WsusUpdateCount = $UpdatesForReboot.Count
}
Write-Output """$WsusComputerName"",""$WsusUpdateCount""" | Out-File $ENV:SystemDrive\Scripts\MissingUpdatesBrief.csv -encoding ASCII -append -width 512

}

$ReportSorted = import-csv $ENV:SystemDrive\Scripts\MissingUpdatesBrief.csv | Sort Server
$ReportSorted | export-csv $ENV:SystemDrive\Scripts\MissingUpdatesBrief.csv -notype -force

$SmtpClient = new-object system.net.mail.smtpClient
$MailMessage = New-Object system.net.mail.MailMessage
$SmtpClient.Host = "YOURMAILSERVER.YOURDOMAIN.COM"
$MailMessage.from = "YOU@YOURDOMAIN.COM"
$MailMessage.To.add("SOMEONE@YOURDOMAIN.COM,SOMEONE@YOURDOMAIN.COM")
# $MailMessage.Bcc.add("SOMEONE@YOURDOMAIN.COM")
$MailMessage.Subject = "Computer Status Brief Report"

$MailMessage.Body = "
<html><body>
<dl>
  <dd>
    <em>Please find the attached report detailing the status of all servers requiring updates.<br>
    <br>
        Servers that are up to date will not be listed on this report.
    <br>
    <br>
    <br>
    <br>
    <br>
        Report time: $ReportDate
    <em>
  </dd>
</dl>
</body></html>
"

$MailMessage.priority = "high"
$MailMessage.IsBodyHtml = 1
$MailMessage.Attachments.Add("$ENV:SystemDrive\Scripts\MissingUpdatesBrief.csv")
$Smtpclient.Send($MailMessage)

exit

 

del.icio.us Tags: ,

Technorati Tags: ,
September 29

Powershell and the Windows Update API

 
Microsoft published example code to use Windows Scripting Host in order to apply updates leveraging the Windows Update API. Having nothing better to do, I decided to port this code over to Powershell and pretty it up a bit with Winforms. This works with Windows Update, but it definitely works better with a WSUS server and clients configured to use that server.
 
What's Required:
Windows XP or higher
.NET Framework 2.0 or higher
Powershell v1.0
A directory on your %SystemDrive% called, "Scripts"
A JPG file in the "Scripts" directory called, "Example.JPG"
 
What to be aware of:
After applying updates, the computer will be restarted if any of the patches require a reboot. Watch out for the Internet Explorer 7 package. You might want to have Internet Explorer 7 installed prior to running this program, even though it is not required.
 
What to do:
Paste the following code into a Powershell window, or save it as a Powershell file and execute it.
 
###################################################################################################################################### # Windows Update through Powershell v1.0
######################################################################################################################################
$UpdateSession = New-Object -com Microsoft.Update.Session
$UpdateSearcher = $UpdateSession.CreateupdateSearcher()
$SearchResult = $UpdateSearcher.Search("IsAssigned=1 and IsHidden=0 and IsInstalled=0")
$UpdateLowNumber = 0
$UpdateHighNumber = 1
$NumberofUpdates = $searchResult.Updates.Count
[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$Form2 = New-Object Windows.Forms.Form
$Form2.ControlBox = 0
$Form2.MinimizeBox = 0
$Form2.MaximizeBox = 0
$Form2.ShowInTaskbar = 0
$Form2.FormBorderStyle = "FixedToolWindow"
$Form2.ShowIcon = 0
$Form2.Width = 1024
$Form2.Height = 768
$Form2.TopLevel = 1
$Form2.TopMost = 1
$Form2.StartPosition = "Manual"
$Form2.Location = "1,1"
$Form2.Opacity = 1.00
$Form2.Visible = 0
$Form2.Enabled = 0
$PercentDisplay1 = New-Object System.Windows.Forms.RichTextBox
$PercentDisplay1.Location = "20,705"
$PercentDisplay1.Width = 115
$PercentDisplay1.Height = 20
$PatchDisplay1 = New-Object System.Windows.Forms.RichTextBox
$PatchDisplay1.Location = "145,705"
$PatchDisplay1.Width = 855
$PatchDisplay1.Height = 20
$PictureBox1 = New-Object Windows.Forms.PictureBox
$PictureBox1.Width = 1024
$PictureBox1.Height = 768
$PictureBox1.Image = [System.Drawing.Image]::FromFile("$env:SystemDrive\Scripts\Example.JPG")
$PictureBox1.SizeMode = "StretchImage"
$PictureBox1.BorderStyle = "None"
$ProgressBar2 = New-Object Windows.Forms.ProgressBar
$ProgressBar2.Location = "20,735"
$ProgressBar2.Height = 20
$ProgressBar2.Width = 980
$ProgressBar2.Minimum = 1
$ProgressBar2.Maximum = $NumberofUpdates
$ProgressBar2.Style = 1
$ProgressBar2.ImeMode = 1
$Form2.Controls.Add($ProgressBar2)
$Form2.Controls.Add($PercentDisplay1)
$Form2.Controls.Add($PatchDisplay1)
$Form2.Controls.Add($PictureBox1)
while ($UpdateHighNumber -le $NumberofUpdates) {
$UpdatesToDownload = New-Object -com Microsoft.Update.UpdateColl
$Update = $searchResult.Updates.Item($UpdateLowNumber)
if ($Update.EulaAccepted -eq 0) {$Update.AcceptEula()}
$UpdatesToDownload.Add($Update)
$Downloader = $UpdateSession.CreateUpdateDownloader()
$Downloader.Updates = $UpdatesToDownload
$Downloader.Download()
$UpdatesToInstall = New-Object -com Microsoft.Update.UpdateColl
$UpdatesToInstall.Add($Update)
$ProgressBarPercent = 100 / ($ProgressBar2.Maximum / $ProgressBar2.Value)
$ProgressBarConvertedPercent = [INT]$ProgressBarPercent
$PercentDisplay1.Text = "$ProgressBarConvertedPercent% Complete"
$PatchDisplay1.Text = $update.Title
$Form2.Show()
$Form2.Refresh()
$Form2.BringToFront()
$Installer = $UpdateSession.CreateUpdateInstaller()
$Installer.Updates = $UpdatesToInstall
$InstallationResult = $Installer.Install()
$InstallationResult.ResultCode
$InstallationResult.RebootRequired
$UpdateLowNumber = $UpdateLowNumber + 1
$UpdateHighNumber = $UpdateHighNumber + 1
if ($ProgressBar2.Value -lt $ProgressBar2.Maximum) {$ProgressBar2.Value = $ProgressBar2.Value + 1}
}
$Form2.Close()
$ComputerStatus = New-Object -com Microsoft.Update.SystemInfo
if ($ComputerStatus.RebootRequired -eq 1) {cmd /c $env:WinDir\System32\Shutdown.exe -r -f -t 10 -c "Patching Complete."} 
 
 

 

Weather

Loading...