This script is intended to apply updates and hotfixes after the OS has been installed and is online. There are windows updates that cannot be installed offline, as described in this blog. For these updates, I have written a script that will apply the updates using wusa.exe. In order to properly install them, I recommend numbering the filenames so that the script will read them in the correct sequence. I added 01-, 02-, 03-, etc in front of the filename. The script now reads the files in that sequence. The script has been written so that it only reads msu files. You can download this script here.
#*******************************************************************************
# Author: Mick Pletcher
# Date: 01 January 2014
#
# Program: Online Windows Updates Installer
#*******************************************************************************
#Declare Local Memory
Set-Variable -Name File -Scope Local -Force
Function DeclareGlobalMemory {
Set-Variable -Name Files -Scope Global -Force
Set-Variable -Name RelativePath -Scope Global -Force
}
Function GlobalMemoryCleanup {
Remove-Variable -Name Files -Scope Global -Force
Remove-Variable -Name RelativePath -Scope Global -Force
}
Function RenameWindow ($Title) {
#Declare Local Memory
Set-Variable -Name a -Scope Local -Force
$a = (Get-Host).UI.RawUI
$a.WindowTitle = $Title
#Cleanup Local Memory
Remove-Variable -Name a -Scope Local -Force
}
Function GetRelativePath {
$Global:RelativePath=(split-path $SCRIPT:MyInvocation.MyCommand.Path -parent)+"\"
}
Function GetFiles {
$Global:Files = Get-ChildItem -Path $Global:RelativePath
}
Function CreateTempFolder ($FolderName) {
$FolderName = "c:\temp\"+$FolderName
New-Item -Path $FolderName -ItemType Directory -Force
}
Function RemoveTempFolder ($FolderName) {
$FolderName = "c:\temp\"+$FolderName
Remove-Item -Path $FolderName -Recurse -Force
}
Function ExtractCAB ($Name) {
#Declare Local Memory
Set-Variable -Name arguments -Scope Local -Force
Set-Variable -Name Dest -Scope Local -Force
Set-Variable -Name Source -Scope Local -Force
$Source = $Global:RelativePath+$Name
$Dest = "c:\temp\"+$Name.Substring(0,$Name.Length-4)
$arguments = "–F:*"+[char]32+$Source+[char]32+$Dest
Start-Process -FilePath "expand.exe" -ArgumentList $arguments -Wait -PassThru
#Cleanup Local Memory
Remove-Variable -Name arguments -Scope Local -Force
Remove-Variable -Name Dest -Scope Local -Force
Remove-Variable -Name Source -Scope Local -Force
}
#Function ApplyWindowsUpdate ($Name,$Directory) {
#
# #Declare Local Memory
# Set-Variable -Name arguments -Scope Local -Force
#
# $Name = $Name.Substring(0,$Name.Length-4)
# $Name = $Name+".cab"
# $arguments = "/Online /Add-Package /PackagePath:"+"c:\temp\"+$Directory+"\"+$Name
# Start-Process -FilePath "DISM.exe" -ArgumentList $arguments -Wait -PassThru
#
# #Cleanup Local Memory
# Remove-Variable -Name arguments -Scope Local -Force
#
#}
Function ApplyWindowsUpdate ($Name) {
#Declare Local Memory
Set-Variable -Name App -Scope Local -Force
Set-Variable -Name arguments -Scope Local -Force
Set-Variable -Name index -Scope Local -Force
Set-Variable -Name Result -Scope Local -Force
$App = $Name
$index = $App.IndexOf("-KB")+1
$App = $App.Substring(0,$App.Length-4)
$App = $App.Substring($index)
Write-Host "Installing"$App"....." -NoNewline
$arguments = $Global:RelativePath+$Name+[char]32+"/quiet /norestart"
$Result = (Start-Process -FilePath "wusa.exe" -ArgumentList $arguments -Wait -PassThru).ExitCode
If ($Result -eq "3010") {
Write-Host "Succeeded" -ForegroundColor Yellow
} else {
Write-Host "Failed with error code"$Result -ForegroundColor Red
}
#Cleanup Local Memory
Remove-Variable -Name App -Scope Local -Force
Remove-Variable -Name arguments -Scope Local -Force
Remove-Variable -Name index -Scope Local -Force
Remove-Variable -Name Result -Scope Local -Force
}
cls
RenameWindow "Windows Updates"
DeclareGlobalMemory
GetRelativePath
GetFiles
foreach ($File in $Files) {
if (($File.Attributes -ne "Directory") -and ($File.Name -like "*.msu")) {
ApplyWindowsUpdate $File.Name
}
}
GlobalMemoryCleanup
#Cleanup Local Memory
Remove-Variable -Name File -Scope Local -Force
That is very helpful, I am thinking to put that into our servers!
ReplyDeleteSave our time to install the updates into the servers, one by one!