Script: Windows Update via Powershell

It’s been a while since the last time that I’ve posted something. Today I’ve been asked to create a solution for our customers so we can automatically search and install updates through a script. Unfortunately these customers didn’t want to use a WSUS server so we had to find another way to make sure all the required patches are installed. We will perform the Windows Update via Powershell .

The script is scheduled on a weekly basis which also notifies any users who are logged in to the computer or server. This is done by using Command Prompt.

If you want to change the type of updates the scripts searches for, you can use the following triggers behind ‘Get-WindowsUpdate’:

Trigger Comment
-AutoRebootAutomatically reboot. Using this within this script results in users not getting notified.
-AcceptAllReceive all updates.
-Microsoft UpdateInstall updates supplied by Microsoft Update.
-NotCategory “Drivers”Don’t download updates from Microsoft Update.

To use the Windows Update via Powershell script you need to make sure you’re using at least Powershell Version 3.0. This means this script is compatible from Windows 7 till Windows 10 and Windows Server 2008 till Windows Server 2019. Use the Microsoft page to find the latest version for your system.

####################################################################################################################
# Script: Windows Update via Powershell
# Auteur: Rick Stomps
# Versie: 1.0
# Function Check-PendingReboot: https://stackoverflow.com/questions/47867949/how-can-i-check-for-a-pending-reboot
####################################################################################################################

# Function to check pending reboot.
function Check-PendingReboot {
    if (Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending" -EA Ignore) { return $true }
    if (Get-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" -EA Ignore) { return $true }
    if (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name PendingFileRenameOperations -EA Ignore) { return $true }
    try { 
        $util = [wmiclass]"\\.\root\ccm\clientsdk:CCM_ClientUtilities"
        $status = $util.DetermineIfRebootPending()
        if (($status -ne $null) -and $status.RebootPending) {
            return $true
        }
    }
    catch { }

    return $false
}

# Change Execution Policy for this process to run the script.
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Unrestricted -Force

# Install the required packages.
Install-PackageProvider -Name NuGet -Force
Install-Module -Name PSWindowsUpdate -Force

# Import the required module.
Import-Module PSWindowsUpdate

# Look for all updates, download, install and don't reboot yet.
Get-WindowsUpdate -AcceptAll -Download -Install -IgnoreReboot

# Check if a pending reboot is found, notify users if that is the case. If none found just close the session.
$reboot = Check-PendingReboot

if($reboot -eq $true){
   write-host("Pending reboot found. Reboot..")
   cmd /c "msg * "Windows update has finished downloading and needs to reboot to install the required updates. Rebooting in 5 minutes..""
   cmd /c "Shutdown /r /f /t 300"
   Exit
   
}else {
   write-host("No Pending reboot. Shutting down PowerShell..")
   Exit
}

You can either schedule this script though the ‘task scheduler’ or use your management software to do so. Make sure the account you’re going to use to start the script has sufficient rights to go through Windows update, install the said updates and reboot the computer if necessary. To make sure this was the case I’ve created a separate service account in our customer domain with the sufficient rights.

If you have any question about the script please do not hesitate to contact me through the comments below.