fredag den 30. maj 2014

Windows Update with PowerShell

I’ve had a PowerShell script (rewritten from VBS) for a long time. It works and all, but once in a while when your testing stuff on fresh machines it would drive me nuts I couldn’t get a “status” like when your doing it though GUI.

Doing a progress bar while downloading is/was easy enough, but we all know it’s the installation that takes time, and that gave me a few issues. I finally figured out, I couldn’t re-use the installer, and sometimes it fails if you assign each update without first adding it to an “UpdateColl”. So, here it is (download link)

[CmdletBinding()]
Param
(
[switch]$skipReboot
)
Begin {
$Install = $true;
$EulaAccept = $true;

write-progress -id 1 -Activity "Windows Update" -Status "Initialising"
$UpdateSession = New-Object -ComObject 'Microsoft.Update.Session'
$UpdateSession.ClientApplicationID = 'Wingu Update Client'
}
Process {
write-progress -id 1 -Activity "Windows Update" -Status "Checking for available updates"
$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
$SearchResult = $UpdateSearcher.Search("IsInstalled=0 and Type='Software'") # and IsHidden=0
$UpdatesToDownload = New-Object -com Microsoft.Update.UpdateColl
foreach ($Update in $SearchResult.Updates)
{
[bool]$addThisUpdate = $false
if ($Update.InstallationBehavior.CanRequestUserInput)
{
#Write-Verbose "> Skipping: $($Update.Title) because it requires user input"
[bool]$addThisUpdate = $true
} else {
if (!($Update.EulaAccepted)) {
Write-Verbose "> Note: $($Update.Title) has a license agreement that must be accepted:"
$Update.AcceptEula() | Out-Null
[bool]$addThisUpdate = $true
} else {
[bool]$addThisUpdate = $true
}
}
if ([bool]$addThisUpdate) {
Write-Verbose "Adding: $($Update.Title)"
$UpdatesToDownload.Add($Update) | Out-Null
}
}
if ($UpdatesToDownload.Count -eq 0) {
Write-Verbose 'All applicable updates were skipped.'
return $false
}
$downloader = $updateSession.CreateUpdateDownloader()
foreach($update in $UpdatesToDownload) {
$counter += 1
write-progress -id 1 -Activity "Updating" -Status "Downloading $counter/$($UpdatesToDownload.count) updates"
if(!$update.IsDownloaded) {
write-progress -id 2 -ParentId 1 -Activity "Updating" -Status "Downloading $($update.Title) $([int]($update.MaxDownloadSize / 1MB))MB"
$updateCollection=New-Object -com Microsoft.Update.UpdateColl
$updateCollection.Add($Update) | Out-Null
$downloader.Updates = $updateCollection
$Result = $downloader.Download()
} else {
write-progress -id 2 -ParentId 1 -Activity "Updating" -Status "isready $($update.Title)"
}
}


$needreboot = $false
$updateSystemInfo = new-object -com Microsoft.Update.SystemInfo
if($updateSystemInfo.rebootRequired){ $needreboot = $true }
$counter = 0
foreach($update in $UpdatesToDownload) {
$counter += 1
write-progress -id 1 -Activity "Updating" -Status "Installing $counter/$($UpdatesToDownload.count) updates"
write-progress -id 2 -ParentId 1 -Activity "Updating" -Status "Installing $($update.Title)"
$updatesToInstall = New-object -com "Microsoft.Update.UpdateColl"
$updatesToInstall.Add($update) | out-null
$installer = $updateSession.CreateUpdateInstaller()
$updateCollection=New-Object -com Microsoft.Update.UpdateColl
$updateCollection.Add($Update) | Out-Null
if($installer.ForceQuiet -eq $false) { $installer.ForceQuiet=$true }
$installer.Updates = $updateCollection
$installationResult = $installer.Install()
if($installationResult.rebootRequired){ $needreboot = $true }
if($installationResult.HResult -eq 4) {
#$resultcode= @{0="Not Started"; 1="In Progress"; 2="Succeeded"; 3="Succeeded With Errors"; 4="Failed" ; 5="Aborted" }
Write-Warning "Failed installting $($update.Title) ResultCode $($installationResult.ResultCode) HResult $($installationResult.HResult)"
}
if($installationResult.HResult -eq 5) {
#$resultcode= @{0="Not Started"; 1="In Progress"; 2="Succeeded"; 3="Succeeded With Errors"; 4="Failed" ; 5="Aborted" }
Write-Warning "Aborted $($update.Title) ResultCode $($installationResult.ResultCode) HResult $($installationResult.HResult)"
}
}

if(!$needreboot) {
$arguments = @('/c wuauclt /reportnow')
Start-Process -FilePath "cmd.exe" -ArgumentList $arguments -Wait
}

if(!$skipReboot -and $needreboot){
write-progress -id 2 -ParentId 1 -Activity "Updating" -Status "Rebooting system"
Write-Warning "Reboot required"
Restart-Computer -Force
}
return $needreboot
}
End {
write-progress -id 1 -Activity "Updating" -Status "Windows Update Check Complete" -Completed
}

1 kommentar:

  1. Slot machines can be utilized for long intervals with out the worry of sporting out. The legs and partitions of these machines are strongly constructed for stability and a great rebound 더온카지노 for pucks. Many of the casino slot games are built around an action-packed bonus mechanic, and a few have a lock-and-spin function, offering breath-taking pleasure for the customers. Additionally, customers can opt for single, double or vertical screens as per their necessities. Game manufacturers continue to develop new types of machines with interesting twists on the classic recreation.

    SvarSlet