You can install Servicing Stack Updates (SSU) for Windows Server 2016 and Windows Server 2019 using PowerShell, without downtime. Because they must be installed prior to your normal Windows Server security updates, you can install them anytime you want to during the day. Here’s a small PowerShell example to do so.

Servicing the Windows servicing stack

Keeping the servicing stack updated is crucial for the security of your Windows-based infrastructure. Unfortunately, it’s also becoming more of a challenge. This post helps you installing Windows servicing stack updates prior to Windows Updates, using PowerShell, and streamlines your workflow a bit.

But first, what exactly are Servicing stack updates, or SSU’s? Microsoft writes:

Servicing stack updates provide fixes to the servicing stack, the component that installs Windows updates. Additionally, it contains the “component-based servicing stack” (CBS), which is a key underlying component for several elements of Windows deployment, such as DISM, SFC, changing Windows features or roles, and repairing components. The CBS is a small component that typically does not have updates released every month.

Servicing stack updatesMicrosoft Docs

Protip: I mentioned Windows Component-Based Servicing and CBS log files in my blog post with 5 ways to clean up files and free up disk space in Windows Server.

This may interest you:   Windows Server 2019 - now available in preview

In my monthly Windows Updates routine, mostly using WSUS, I use the following PowerShell snippets to install Servicing Stack Updates manually in a loop.

First I approve all updates available and wait a moment for the updates to be downloaded to the WSUS client servers. In that moment of waiting, I write down the KB numbers for Server 2016 and Server 2019 Servicing Stack Updates (this month: KB4503537 for Server 2016 and KB4504369 for Server 2019.

Protip: ever wondered why Windows Server Update Services (WSUS) offers Flash updates for Windows Server? Here is how to uninstall and remove Adobe Flash Player in Windows Server.

The following step is to verify files are downloaded properly to the clients. Some parts can be further automated, but I always like to have a visual comfirmation of the results.

On one server I issue the following PowerShell Get-ChildItem cmdlet to search for the update-file and location in question:

PS C:\Users\janr> Get-ChildItem -Recurse C:\Windows\SoftwareDistribution\Download | ?{ $_.PSPath -like "*KB4503537*" }


    Directory: C:\Windows\SoftwareDistribution\Download\5781475735efb924887fcf8057a37977


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         6/3/2019   7:16 PM       12020671 Windows10.0-KB4503537-x64.cab

Knowing this, I can verify the file path on all servers in my domain network:

foreach( $server in (Get-ADComputer -Filter {(enabled -eq $True) -and (OperatingSystem -like "Windows Server 2016*")}).DNSHostName ) {
	write-output $server;
	invoke-command -computername $server -scriptblock {
		if( Test-Path( "C:\Windows\SoftwareDistribution\Download\5781475735efb924887fcf8057a37977\Windows10.0-KB4503537-x64.cab" )) {
			Write-Output "Servicing Stack Update KB4503537 present."
			# &DISM.exe /Online /Add-Package /PackagePath:C:\Windows\SoftwareDistribution\Download\5781475735efb924887fcf8057a37977\Windows10.0-KB4503537-x64.cab
		}
	}
}

Who can tell me how this folder name 5781475735efb924887fcf8057a37977 is generated?

This may interest you:   How to unzip a file in PowerShell

If all servers report the file is present, you can issue DISM to install the SSU’s .cab file:

foreach( $server in (Get-ADComputer -Filter {(enabled -eq $True) -and (OperatingSystem -like "Windows Server 2016*")}).DNSHostName ) {
	write-output $server;
	invoke-command -computername $server -scriptblock {
		if( Test-Path( "C:\Windows\SoftwareDistribution\Download\5781475735efb924887fcf8057a37977\Windows10.0-KB4503537-x64.cab" )) {
			&DISM.exe /Online /Add-Package /PackagePath:C:\Windows\SoftwareDistribution\Download\5781475735efb924887fcf8057a37977\Windows10.0-KB4503537-x64.cab
		}
	} -AsJob
}

Here I also used -AsJob to start the command async. Use Get-Job and Receive-Job to get information about running jobs. Change “Windows Server 2016*” to “Windows Server 2019*” to search for Server 2019 servers in your AD network.

The regular Windows Updates are installed, using WSUS and PowerShell module PSWindowsUpdate.You can install this with NuGet:

Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Confirm:$false -Force
Install-Module -Name PSWindowsUpdate -Confirm:$false -Force

buy me a coffee
Buy Me A Coffee