Since 2023 you could not import updates manually to WSUS. Microsoft offers you a script to download the updates from the update catalog when you provide the UpdateID to the script. The script defaults to localhost if you dont provide the WSUS server. For example:

.\ImportUpdateToWSUS.ps1 -UpdateId 12345678-90ab-cdef-1234-567890abcdef

But this script has a big issue for air-gapped enviroments – it still relies on the microsoft update catalog to download and import it to the WSUS server. But in the background the script just uses the ImportUpdateFromCatalogSite() powershell function. If you look at the parameters, you can parse the UpdateID but also “an array of the local paths where any files required by the update can be found.”

This means we can use the function with our locally downloaded .msu files and the UpdateID to import the updates manually in our air-gapped enviroment. In order to call the function we have to connect to the WSUS server first and choose the port number and if the WSUS is reachable over TLS (-UseSsl). Otherwise -UseSsl is not necessary.

$wsus = Get-WsusServer -Name <WSUS.networkhaven.org> -PortNumber <8531/8530> < -UseSsl >
$wsus.ImportUpdateFromCatalogSite(<Update-ID>, <Local-Path-to-MSU>)

Common issue – TLS#

Error message: “The request was aborted: Could not create SSL/TLS secure channel.”

Depending on where you want to execute the commands, the majority of the current windows servers have PowerShell 5.1 installed which is build on the .NET framework 4.x. These older versions defaults to TLS1.0 when making requests. With WSUS installed on windows server 2016 & 2019 you could run into issue where you have to force TLS1.1 & TLS1.2 for .NET4. You can use the following registry key:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
      "SystemDefaultTlsVersions" = dword:00000001
      "SchUseStrongCrypto" = dword:00000001

Best case: it will also be set for 32-bit applications.

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319]
      "SystemDefaultTlsVersions" = dword:00000001
      "SchUseStrongCrypto" = dword:00000001