PowerShell: Exchange 2010 Server Update & Restart

function stopExchange{
net stop msexchangeadtopology /y
net stop msexchangefba /y
net stop msftesql-exchange /y
net stop msexchangeis /y
net stop msexchangesa /y
net stop iisadmin /y
net stop w3svc /y
}

function startExchange{
net start w3svc /y
net start iisadmin /y
net start msexchangesa /y
net start msexchangeis /y
net start msftesql-exchange /y
net start msexchangefba /y
net start msexchangeadtopology /y
}

# Install Management Framework 5.1 for Windows 2008 PowerShell
function installManagementFramework51{
# Patch Windows 2008 & 2012 PowerShell to fix error: Install-Module : The term 'Install-Module' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
$managementFramework51Windows2008="https://www.microsoft.com/en-us/download/confirmation.aspx?id=54616&6B49FDFB-8E5B-4B07-BC31-15695C5A2143=1"
$managementFramework51Windows2008File="C:\Temp\Win7AndW2K8R2-KB3191566-x64.msu"
(New-Object System.Net.WebClient).DownloadFile($managementFramework51Windows2008, $managementFramework51Windows2008File)
wusa.exe -kb $managementFramework51Windows2008File /norestart /quiet
}

function setRegKey{
[CmdletBinding()]
Param(
[Parameter(Position=0, Mandatory=$True)]
[string]$path,

[Parameter(Position=1, Mandatory=$True)]
[string]$name,

[Parameter(Position=2, Mandatory=$True)]
[string]$value
)

Set-Itemproperty -path $path -Name $name -value $value
}

function checkRegKey{
[CmdletBinding()]
Param(
[Parameter(Position=0, Mandatory=$True)]
[string]$path,

[Parameter(Position=1, Mandatory=$True)]
[string]$name,

[Parameter(Position=2, Mandatory=$False)]
[string]$value=1
)

$val = Get-ItemProperty -Path $path -Name $key
if($val.$name -eq $value){return $True}
else{return $False}
}

function updateWindows{
# Set PowerShell Gallery as Trusted to bypass prompts
Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted

# Include the PowerShell Windows Update module
$checkModule=Get-Module -ListAvailable -Name PSWindowsUpdate
if(!($checkModule)){Install-Module PSWindowsUpdate -Confirm:$false;}

# Register the user of Windows Update Service if it has not been registered
$MicrosoftUpdateID="7971f918-a847-4430-9279-4a52d1efe18d"
$registered=(Get-WUServiceManager).ServiceID | Where-Object {$MicrosoftUpdateID -contains $_}
if (!($registered)){
Add-WUServiceManager -ServiceID $MicrosoftUpdateID -Confirm:$false
}

# Handling Windows Updates Server settings
# This registry settings means Windows Update Server is OFF
$wuPath="Registry::HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU"
$wuKey="UseWUServer"
$wuIsOn=checkRegKey -path $wuPath -name $wuKey -value 1

# This preemptively resolves error: Exception from HRESULT: 0x8024401C
if($wuIsOn){
# Turn WU Server OFF temporarily
setRegKey -path $wuPath -name $wuKey -value 0
restart-service wuauserv

# Perform Updates
Get-WUInstall -MicrosoftUpdate -AcceptAll -IgnoreUserInput -IgnoreReboot

# Turn Windows Update Server back to ON
#setRegKey -path $wuPath -name $wuKey -value 1
#restart-service wuauserv

"Windows Update sequence is completed.";
}
else{
# Perform Updates
Get-WUInstall -MicrosoftUpdate -AcceptAll -IgnoreUserInput -IgnoreReboot
"Windows Update sequence is completed.";
}
}

function diskCleanup{
"Performing Disk Cleanup..."
$HKLM = [UInt32] "0x80000002"
$strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches"
$strValueName = "StateFlags0065"
$subkeys = gci -Path HKLM:\$strKeyPath -Name
ForEach ($subkey in $subkeys) {
New-ItemProperty -Path HKLM:\$strKeyPath\$subkey -Name $strValueName -PropertyType DWord -Value 2 -ErrorAction SilentlyContinue| Out-Null
Start-Process cleanmgr -ArgumentList "/sagerun:65" -Wait -NoNewWindow -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
}
ForEach ($subkey in $subkeys) {
Remove-ItemProperty -Path HKLM:\$strKeyPath\$subkey -Name $strValueName | Out-Null
}
}

function cleanUpdatesCache{
net stop wuauserv
remove-item C:\Windows\SoftwareDistribution\Download\* -Force -Recurse -confirm:$False
net start wuauserv
}

function cleanWindows{
"Clear Windows Update Cache..."
Dism.exe /online /Cleanup-Image /StartComponentCleanup

"Delete files in Temp directory..."
del C:\Temp\*.* -Recurse -Force

"Prune Event Logs..."
wevtutil el | Foreach-Object {wevtutil cl "$_"}

diskCleanup;
cleanUpdatesCache;

}

"Run one of these commands:
1. InstallManagementFramework51
2. stopExchange
3. updateWindows
4. cleanWindows
5. restart-computer
6. startExchange";

Example Output:

PS C:\Windows\system32> C:\Users\kim_admin\Desktop\exchange-2010-server-update.ps1
Run one of these commands:
1. InstallManagementFramework51
2. stopExchange
3. updateWindows
4. cleanWindows
5. restart-computer
6. startExchange

PS C:\Windows\system32> updatewindows

ComputerName Status KB Size Title
------------ ------ -- ---- -----
USMAIL3 -D----- KB4503294 1GB 2019-06 Cumulative Update for Windows Server 2016 for x64-based Systems (KB4503294)
Windows Update sequence is completed.

Manually apply problematic Cumulative Patch

$KB="http://download.windowsupdate.com/c/msdownload/update/software/updt/2019/06/windows10.0-kb4503294-x64_ea815c82744b7a810fe9125460134467ff463795.msu"
$tempfile="C:\Temp\KB.msu"
New-Item -ItemType Directory -Force -Path C:\Temp
(new-object System.Net.WebClient).DownloadFile($KB,$tempfile)
wusa.exe -kb $tempfile /norestart /quiet

Leave a Reply

Your email address will not be published. Required fields are marked *