Create the Ultimate Smart PowerShell Update Script with Email Notifications and Error Handling
William Yeack

I wanted to create a smart PowerShell Script for updating our servers that was both ready to be executed manually as well as ready to be added as an automated task.  Additionally, I wanted notifications to be generated whenever the script was run with details about the results, just in case we needed to debug any issues in the future.  This is what I came up with:

⁠# Basic Variables$HostName = $env:COMPUTERNAME$HostTime = get-date -Format hh:mm$HostDate = get-date -format D# SMTP Variables$SMTPSender             = ""$SMTPRecipient          = "";$SMTPMessage            = New-Object System.Net.Mail.mailmessage $SMTPSender, $SMTPRecipient$SMTPMessage.IsBodyHTML = $true$SMTPMessage.Subject    = $HostName + " Update Report"$SMTPClient             = new-Object Net.Mail.SmtpClient("", 587)$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("SMTPUser", "SMTPPassword" )# CHECK PENDING RESTART#  If the server already has a pending restart it should be done#  before installing additional updates.if ((New-Object -ComObject Microsoft.Update.SystemInfo).RebootRequired){	$SMTPMessage.Body = "$($HostDate)<br/>$($HostTime)<br/>$($HostName) has a pending restart that must be completed before installing new updats."	$SMTPClient.Send($SMTPMessage)    Restart-Computer -Force}else{	# SEARCH UPDATES	#  This will find new updates to install.	$UpdateResults = (New-Object -ComObject Microsoft.Update.Searcher).Search("IsInstalled=0 and Type='Software'").Updates	# CHECK UPDATE COUNT	#  If there are no updates and you attempt to call	#  download, an exception is thrown.	if ($UpdateResults.Count -eq 0)	{		$SMTPMessage.Body = "$($HostDate)<br/>$($HostTime)<br/>$($HostName) has checked for updates but coult not find any."		$SMTPClient.Send($SMTPMessage)	}	else	{		# DOWNLOAD UPDATES		#  Attempt to download updates, writing progress as it goes.		$UpdateDownloader = (New-Object -ComObject Microsoft.Update.Session).CreateUpdateDownloader()		$UpdateDownloader.Updates = $UpdateResults		write-progress -Activity 'Updating' -Status "Downloading $($UpdateDownloader.Updates.count) updates"		$UpdateDownloader.Download()		# INSTALL UPDATES		#  Installs the updates that have been downloaded.		$UpdateInstaller = New-Object -ComObject Microsoft.Update.Installer		$UpdateInstaller.Updates = $UpdateResults		$UpdateResult = $UpdateInstaller.Install()		if ($UpdateResult.rebootRequired) 		{			$SMTPMessage.Body = "$($HostDate)<br/>$($HostTime)<br/>$($HostName) has installed all available updates and will now reboot."			$SMTPClient.Send($SMTPMessage)			Restart-Computer -Force		}		else		{				$SMTPMessage.Body = "$($HostDate)<br/>$($HostTime)<br/>$($HostName) has installed all available updates and no reboot is required."			$SMTPClient.Send($SMTPMessage)		}	}}

If you are okay with less control over how your updates work (and don't need notifications), you can use a pre-existing library using the following script:

⁠Set-ExecutionPolicy RemoteSigned -ForceInstall-PackageProvider -Name NuGet -ForceSet-PSRepository -Name "PSGallery" -InstallationPolicy TrustedInstall-Module PSWindowsUpdateImport-Module PSWindowsUpdateAdd-WUServiceManager -ServiceID 7971f918-a847-4430-9279-4a52d1efe18d -Confirm:$falseGet-WUInstall -AcceptAll -Install -AutoReboot

Finally, if this is an automated task, set your Action to start a program (PowerShell.exe) with the following arguments:


Happy scripting!

Other resources:

Install Updates and Reboot with PowerShell


Use PowerShell to Install Windows Update and Restart

To add a comment, please Register or Login.