Quick tip: Renew a certificate used by WSUS

I failed to update the certificate of a WSUS sever before it expired 😦
Here’s what error message I got when I tried to use the cmdlet: Get-WsusServer : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

Here’s what I did to replace my expired certificate by a valid one:

# Create a self signed certificate
$SelfSignedHT = @{
 DnsName = "$($env:COMPUTERNAME).myfqdn".ToLower()
 CertStoreLocation = "Cert:\LocalMachine\My"
New-SelfSignedCertificate @SelfSignedHT

# Retrieve it from its store
$cert = Get-ChildItem -Path Cert:\LocalMachine\My -SSLServerAuthentication | 
Where { $_.NotAfter -gt (Get-Date) }

# Export the public key
Export-Certificate -Cert $cert -Type CERT -FilePath "~/documents/cert.$($cert.Thumbprint).cer"

# Import the public key in the Root CA store
Import-Certificate -FilePath "~/documents/cert.$($cert.Thumbprint).cer" -CertStoreLocation Cert:\LocalMachine\Root

# View what certificate is being used (will show you the previous thumbprint)
(Get-WebBinding  -Protocol https).certificateHash

# Update it
(Get-WebBinding  -Protocol https).AddSslCertificate(

# Check that the new cert is being used
(Get-WebBinding  -Protocol https).certificateHash

I was able to use the Get-WsusServer immediately after switching to the valid new certificate in the same console where it previously failed 😀

Next step: distribute the exported public key to client computers using a GPO

Quick tip: What new products and classifications have been added in the past 30 days to WSUS?

Two days ago a PM.org list member asked the following question:

When you see the notice “X new products and Y new classifications have been added in the past 30 days”, how do you know which ones are new when you click on the link.

The only answer was a piece of PowerShell code 😀 that another list member pointed (here)

# Get new classifications
) | Select Title,Description, Releasenotes, arrivaldate

# Get what new products were added over the month
) |  
Select Title,Id,arrivaldate | 
ft -AutoSize


About KB4093118

The KB4093118 page has just been updated and states:


  • This update replaces update 4100480, Windows kernel update for CVE-2018-1038.
  • Resync is required to get newer revision of this KB for WSUS environment

What changed?

  • Before a WSUS sync:
  • (Get-WsusServer).SearchUpdates('2018-04 Security Monthly Quality Rollup for Windows 7 for x64-based Systems (KB4093118)') | 
    Select PublicationState,@{l='UpdateId';e={$_.Id.UpdateId}},
    @{l='RevisionNumber';e={$_.Id.RevisionNumber}},CreationDate,isApproved,isSuperseded | 
    ft -AutoSize

  • What’s the content of the patch
  • (Get-WsusServer).SearchUpdates('2018-04 Security Monthly Quality Rollup for Windows 7 for x64-based Systems (KB4093118)') |
    ForEach-Object {
     Select Name,Modified,Type,@{l='Size';e={'{0:N2} MB'-f($_.TotalBytes/1MB)}},
     @{l='SHA1Hash';e={-join ($_.Hash | ForEach-Object { '{0:X2}' -f $_ })}},

  • What was synchronized?
  • Using the code from this post,

    $SyncUpdates | Select Title,
    CreationDate,PublicationState,isApproved,isDeclined,isSuperseded,has* | 

  • After a WSUS sync:
  • What’s the content of the new patch
  • Notice that a file PCIClearStaleCache.exe has been added and the other files didn’t change (same hashes).

  • What has the new patch superseded?
  • Using this MSDN page to find out the UpdateRelationship value

    [Microsoft.UpdateServices.Administration.UpdateRelationship]::UpdatesSupersededByThisUpdate.value__ -eq 6

    It’s possible to list what this new patch has susperseded:

    (Get-WsusServer).SearchUpdates('2018-04 Security Monthly Quality Rollup for Windows 7 for x64-based Systems (KB4093118)') |
    Where-Object { -not($_.isSuperseded)} |
    ForEach-Object {
     $_ | Add-Member -MemberType ScriptProperty -Name UpdatesSupersededByThisUpdate -Value {
     } -Force -PassThru 
    } | Select -Expand UpdatesSupersededByThisUpdate

It seems for sure that Microsoft has added another binary in the new patch to address the NIC card issue:

Fingers crossed 🙄

Find file names and URL of Windows 10 feature updates on WSUS

This question about how to find file names for Windows 10 feature updates on WSUS was raised this morning or last night on the PM.org list because Windows 10 1709 (CB = Current branch) was declared “CBB”, current branch for business (sorry, this is the old wording). In other words, the 1709 branch went from Semi-Annual Channel (Targeted) deployment state to a broader one called just “Semi-Annual Channel” (SAC)….

If I’m not clear, here’s the official release cadence, names and explanation:

… this question was raised because a 4th ISO is also expected…

and another list member asked how to get this info.

Abbodii replied the following:

If you are interested in these XML files as well, here are the links:

In a business environment, you’re more likely to find a WSUS server and it appears that you can also get the file names (ESD images) and their source location using PowerShell like this:

'Feature update to Windows 10, version 1709, en-us'
) | 
ForEach-Object { 
 Write-Verbose "Looking at update id $($_.Id.UpdateId) revision: $($_.Id.RevisionNumber)" -Verbose
 $_.GetInstallableItems() | 
 ForEach-Object {
  $_.Files | 
  ForEach-Object {
    URI = $_.OriginUri.OriginalString
    FileName = $_.OriginUri.Segments[-1]
} | Select FileName

This also means that you can approve only one feature updates if you only have for example x64 based Windows 10 clients to target.
With the above code, you know the update id and you can now do:

$WXtargetgroup = (Get-WsusServer).GetComputerTargetGroups() |
Where Name -eq 'Windows 10 x64'

'Feature update to Windows 10, version 1709, en-us'
) | Where-Object { 
 $_.Id.UpdateId -eq '7c803efa-be06-4481-9f8c-889afb34faf8' 
} | 
ForEach-Object -Process {
 Write-Verbose -Message "Approving $($_.Title)" -Verbose        

Get the status of WSUS clients installing the September Cumulative Update

A few days ago, a PM.org list member asked the following question:

I’m trying to find out what the status is on clients installing the September Cumulative Update.

He also reported that he was using WID (Windows Internal Database) and not SQL. He was also struggling with the Microsoft Report Viewer and Microsoft System CLR Types for SQL Server.

I replied that he can achieve this using only #PowerShell and the WSUS API 😀 but my first try was:

$updateScope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
$updateScope.TextIncludes= '4038777'
(Get-WsusServer).GetUpdateApprovals($updateScope) | 
ForEach-Object {
 $tg = (Get-WsusServer).GetComputerTargetGroup($($_.ComputerTargetGroupId))
 Write-Verbose -Message "Dealing with approval type $($_.Action) on to target group '$($tg.Name)'" -Verbose
 $tg.GetComputerTargets($true) | 
 ForEach-Object {
  $computer = $_
   $State = $computer.GetUpdateInstallationSummary($updateScope)
    ComputerName = $_.FullDomainName ;
    Unknown = $( if($State.UnknownCount) { $true } else { $false} );
    NotApplicable = $( if($State.NotApplicableCount) { $true } else { $false } );
    NotInstalled = $( if($State.NotInstalledCount) { $true } else { $false } );
    Downloaded = $( if($State.DownloadedCount) { $true } else { $false } );
    Installed = $( if($State.InstalledCount) { $true } else { $false } );
    InstalledPendingReboot = $( if($State.InstalledPendingRebootCount) { $true } else { $false } );
    Failed = $( if($State.FailedCount) { $true } else { $false } );
} | ogv

Well, the above code did the job but performed very poorly. It took more than a minute to display the results for a hundred client computers.

I took the update scope approach with a custom text filter and I’ve been inspired by my previous blog post about WSUS reporting.

I wasn’t satisfied and I believed I took the wrong approach and that there should be one or more efficient ways to get the results.
So, the next morning, I gave it another try and found another way to skin the cat:

$kb = '4038777' | % { (Get-WsusServer).SearchUpdates($_) } | ? Title -match 'Windows 7 for x64-based ' |  ? { $_.IsLatestRevision }
(Get-WsusServer).GetComputerTargetGroups() | 
ForEach-Object {
 $kb.GetUpdateInstallationInfoPerComputerTarget($_)  | 
 ForEach-Object {
   Computer = (Get-WsusServer).GetComputerTarget($_.ComputerTargetId).FullDomainName
   State = $_.UpdateInstallationState
} | ogv

The above way performs much faster (max 8 seconds for the same 100 computers) and has less code 😎

WSUS (bundled or installable) child updates

This morning there was question on Patchmanagement.org about how to find if the following .Net Rollup update (4019112) has been installed.

The person approved 4019112 but noticed that the WMI Win32_QuickFixEngineering class didn’t list it.
Instead it contained the following updates KB4014504 and KB4014511 that are actually bundled inside the rollup 4019112

The person was also asking if there’s another way to find what child updates an update installs instead of what’s listed on its support page.

Yes, there is one. If you use the WSUS API GetInstallableItems method. It will list what child updates an update will install (more precisely, it will get the directly bundled, non-explicitly-deployable child updates of this update. Creates an installable item on behalf of this update if the update itself has files.)

(Get-WsusServer).SearchUpdates('4019112') |
Out-GridView -PassThru -Title 'Select an update'| 
ForEach-Object { 
} | ft -AutoSize

As you can see the KB4019112 (logically) bundles an update for every supported version of .Net.

Unfortunately, we couldn’t use the GetRelatedUpdates method and its enum UpdatesBundledByThisUpdate that should also list child updates that are bundled in this update.

# what's the numeric value of the UpdatesBundledByThisUpdate enum

(Get-WsusServer).SearchUpdates('4019112') | 
ForEach-Object {
 $_ | 
 Add-Member -MemberType ScriptProperty -Name UpdatesBundledByThisUpdate -Value {
 } -Force -PassThru
} | Select Title,UpdatesBundledByThisUpdate | 
Out-GridView -PassThru | Select -ExpandProperty UpdatesBundledByThisUpdate

As you can see, it doesn’t return anything. Why?


Well, because the above two searches also don’t return anything.
It means that these updates don’t exist as individual updates in WSUS.

To find out if the .Net rollup 4019112 has been installed on a target computer you can either:

# use the Get-HotFix cmdlet
Get-HotFix -Id 'kb4014504','kb4014508','kb4014511','kb4014514'
# or the  Get-WmiObject cmdlet
Get-WmiObject -Query 'Select * FROM Win32_QuickFixEngineering WHERE HotFixID = "KB4014504" OR HotfixID = "KB4014508" OR HotfixID = "KB4014511" OR HotFixID = "KB4014514"' 

Quick tip: disable WSUS approval rules

I stumbled upon the following article about WSUS and PowerShell a few weeks ago.
After seeing the second point, I realized, it’s nice to verify how “auto-approval” rules are configured but it would be better to know how to enable or disable these rules.

Here’s how to disable rules:

(Get-WsusServer).GetInstallApprovalRules() | 
Out-GridView -Passthru| 
ForEach-Object {
    $r = $_
    try {
        $_.Enabled = $false
        Write-Verbose "Successfully disabled $($_.Name)" -Verbose

    } catch {
        Write-Warning "Failed on rule $($r.Name) because $($_.Exception.Message)"

With the above code snippet, you first get the out-grid view where you can select rules and then click ok:

I selected the only rule I had and got the following result:

If you want to seem more articles about WSUS from my blog, you can use WSUS tag to list them all 🙂

WSUS synchronization report

The other day I wondered how to get the equivalent of this WSUS synchronization summary and its details.
More precisely I wanted to get the summary of what you see in the mmc snap-in under the synchronizations node:
and the details that you get when you right-click a synchronization and hit ‘Synchronization report’ but I got instead the following message telling me that the report viewer wasn’t installed

After a few minutes, I found the following MSDN page about Reporting Newly Synchronized Updates
I first looked at the GetUpdates method that has many ways to call it.
The msdn article proposes to use the 2nd one where you specify all the 5 arguments:

  • Microsoft.UpdateServices.Administration.ApprovedStates approvedStates,
  • datetime fromArrivalDate,
  • datetime toArrivalDate,
  • Microsoft.UpdateServices.Administration.UpdateCategoryCollection updateCategories,
  • Microsoft.UpdateServices.Administration.UpdateClassificationCollection updateClassifications

where both the updatecategories and updateclassifications are set to $null
I gave it a try but I couldn’t get reliable results 😦 even when the two collections (UpdateCategoryCollection and UpdateClassificationCollection) were properly defined and not set to null.
Forget that method, it’s too unpredictable.

I switched to the 3rd method where you just use a single updateScope object as argument instead of the above 5 arguments and finally got the expected reliability 😀

# Get the last sync info (start and end times)
$lastSync = (Get-WsusServer).GetSubscription().GetLastSynchronizationInfo()

# Create an updatescope object
$UpdateScope = New-Object -TypeName Microsoft.UpdateServices.Administration.UpdateScope

# Set the start time
$UpdateScope.FromArrivalDate = $lastSync.StartTime
# Set the end time
$UpdateScope.ToArrivalDate = $lastSync.EndTime

# Invoke the getupdates method using the update scope object
$SyncUpdates = (Get-WsusServer).GetUpdates($UpdateScope)

Now to get the summary, I just do

$SyncUpdates | 
Group-Object -Property publicationstate -NoElement

To view the details of what was synchronized I do:

$SyncUpdates | Out-GridView
# or 
$SyncUpdates | 
Select Title,SecurityBulletins,UpdateClassificationTitle,PublicationState | 
Sort PublicationState | 
Format-Table -AutoSize


Easy-peasy and as always PowerShell rocks 😎

Testing WSUS server operational status

During the summer, someone asked the following questionwsus-monitoring-question on the WSUS patchmanagement.org mailing list.

I replied and immediately thought that Pester would do the job and quickly showed how he could test if he can connect to the console.

I’ve actually more than a WSUS server to manage. So, I started separating the environmental configuration data from the pester tests code almost the same way Mike F. Robbins did in his recent post where he goes far beyond to what I did.

I think it’s a great idea and here’s what I did in my case to monitor my WSUS server operational status.

To get started, I copied the Pester module on my WSUS server, imported the module and did in the ISE:

# helper to create the required files and folder if not present
New-Fixture -Path  ~/Documents/Pester -Name Test-WSUS
# Put the config data into that file:
psEdit ~/Documents/Pester/Test-WSUS.ps1
# Put the pester code into that file:
psEdit ~/Documents/Pester/Test-WSUS.Tests.ps1

After the first 3 commands, here’s what the ISE console looked liked

The first file Test-WSUS.ps1 looks like this by default.
It will be used to store my configuration data.

The second file Test-WSUS.Tests.ps1 is where I’ll write the pester tests code

After editing the 1rst file Test-WSUS.ps1 like this:
pester-test-wsus-file (fake data in this case)

…and the 2nd file Test-WSUS.Tests.ps1 like this:

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"
Describe 'Testing WSUS server locally' {
Context 'Windows Features' {
BeforeAll {
$WindowsFeatures = Get-WindowsFeature
# 'Web-Server',
# 'Web-Common-Http',
# 'Web-Performance',
# 'Web-Security',
# 'Web-Mgmt-Tools',
# 'Web-Mgmt-Compat',
# 'UpdateServices',
# 'NET-Framework-45-Features',
# 'NET-WCF-Services45',
'WoW64-Support' | ForEach-Object {
$name = $_
It "Feature $($_) should be Installed" {
($WindowsFeatures | Where Name -eq $name).Installed | Should be $true
Context 'IIS' {
BeforeAll {
Import-Module Webadministration -ErrorAction SilentlyContinue
It 'Certiticate should be imported in the Cert:\localmachine\My' {
Test-Path -Path "Cert:\LocalMachine\my\$($ThumbPrint)" | Should Be $true
It 'Certificate should be valid' {
(dir -Path "Cert:\LocalMachine\my\$($ThumbPrint)").NotAfter.toString('dd/MM/yyyy HH:mm') | Should Be $CertExpiryDate
It 'Certiticate should be present in IIS' {
(dir -Path IIS:\SslBindings\!$($Port)).Thumbprint | should be "$($ThumbPrint)"
Context 'Services' {
It 'the WsusService service is in Automatic start mode' {
(Get-WmiObject -Query "Select * FROM Win32_service WHERE Name = 'WsusService'").StartMode | Should Be 'Auto'
It 'the WsusService service is running' {
(Get-Service -Name WsusService).Status | Should Be 'Running'
Context 'Firewall' {
Get-NetFirewallProfile | ForEach-Object {
It "Firewall profile $($_.Name) is Enabled" {
$_.Enabled | Should be $true
Get-NetFirewallRule -Name 'IIS-WebServerRole-HTTPS-In-TCP' | ForEach-Object {
It "Firewall rule $($_.Name) should be Enabled" {
$_.Enabled | Should be $true
It "Firewall rule $($_.Name) action should be Allow" {
$_.Action | Should be 'Allow'
Get-NetFirewallRule -Name 'IIS-WebServerRole-HTTP-In-TCP' | ForEach-Object {
It "Firewall rule $($_.Name) should be Enabled" {
$_.Enabled | Should be $true
It "Firewall rule $($_.Name) action should be Allow" {
$_.Action | Should be 'Allow'
Context 'Console connection' {
BeforeAll {
Add-Type -Path "$($env:ProgramFiles)\Update Services\Api\Microsoft.UpdateServices.Administration.dll"
It 'should connect to the console' {
{ [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer("$($FQDN)",$true,$Port) } | Should Not Throw
Context 'Configuration' {
BeforeAll {
$WSUSServer = Get-WsusServer
$DB = (Get-WsusServer).GetDatabaseConfiguration()
$WSUSConfig = (Get-WsusServer).GetConfiguration()
It 'Shoule be ready' {
((Get-WsusServer).GetConfiguration().GetUpdateServerConfigurationState()).value__ | Should be '0'
It 'BypassApiRemoting should be False' {
$WSUSServer.BypassApiRemoting | Should be $false
It 'IsConnectionSecureForApiRemoting should be True' {
$WSUSServer.IsConnectionSecureForApiRemoting | Should be $true
It 'IsServerLocal should be True' {
$WSUSServer.IsServerLocal | Should be $true
It "PortNumber should be $($Port)" {
$WSUSServer.PortNumber | Should be "$($Port)"
It 'PreferredCulture should be en' {
$WSUSServer.PreferredCulture | Should be 'en'
It "ServerName should be $($FQDN)" {
$WSUSServer.ServerName | Should be "$($FQDN)"
It 'UseSecureConnection should be True' {
$WSUSServer.UseSecureConnection | Should be 'True'
It "WebServiceUrl should be https://$($FQDN):$($Port)/ApiRemoting30/WebService.asmx" {
$WSUSServer.WebServiceUrl | Should be "https://$($FQDN):$($Port)/ApiRemoting30/WebService.asmx"
It 'Should use SUSDB' {
$DB.DatabaseName | Should be 'SUSDB'
It 'Should use a DB server named' {
$DB.ServerName | Should be 'MICROSOFT##WID'
It 'Should use a DB server named' {
$DB.IsUsingWindowsInternalDatabase | Should be $true
It 'Should use the Windows Auth mode' {
$DB.AuthenticationMode | Should be 'WindowsAuthentication'
It 'Should have data on D:\WSUS.Content\WsusContent' {
$WSUSConfig.LocalContentCachePath | Should be 'D:\WSUS.Content\WsusContent'
It 'Should sync from MU' {
$WSUSConfig.SyncFromMicrosoftUpdate | Should be $true
It 'Should use a proxy' {
$WSUSConfig.UseProxy | Should be $true
It "Proxy Should be set to $($Proxy)" {
$WSUSConfig.ProxyName | Should be "$($Proxy)"
It "Proxy port Should be set to $($ProxyPort)" {
$WSUSConfig.ProxyServerPort | Should be "$($ProxyPort)"
It 'Proxy use same proxy for SSL ' {
$WSUSConfig.UseSeparateProxyForSsl | Should be $false
It 'Should be targeting clients using Groups and GPO' {
$WSUSConfig.TargetingMode | Should be 'Client'
Context 'Products' {
BeforeAll {
$Categories = (Get-WsusServer).GetSubscription().GetUpdateCategories()
It 'Should have the Office 2010 product' {
($Categories| Where Id -eq '84f5f325-30d7-41c4-81d1-87a0e6535b66').Title | Should be 'Office 2010'
It 'Should have the Windows 7 product' {
($Categories| Where Id -eq 'bfe5b177-a086-47a0-b102-097e4fa1f807').Title | Should be 'Windows 7'
It 'Should have the Windows Defender product' {
($Categories| Where Id -eq '8c3fcc84-7410-4a95-8b89-a166a0190486').Title | Should be 'Windows Defender'
Context 'Classification' {
BeforeAll {
$Classifications = (Get-WsusServer).GetSubscription().GetUpdateClassifications()
It 'Should have enabled the Critical Updates' {
($Classifications | Where Id -eq 'e6cf1350-c01b-414d-a61f-263d14d133b4').Title | Should be 'Critical Updates'
It 'Should have enabled the Definition Updates' {
($Classifications | Where Id -eq 'e0789628-ce08-4437-be74-2495b842f43b').Title | Should be 'Definition Updates'
It 'Should have enabled the Feature Packs' {
($Classifications | Where Id -eq 'b54e7d24-7add-428f-8b75-90a396fa584f').Title | Should be 'Feature Packs'
It 'Should have enabled the Security Updates' {
($Classifications | Where Id -eq '0fa1201d-4330-4fa8-8ae9-b877473b6441').Title | Should be 'Security Updates'
It 'Should have enabled the Service Packs' {
($Classifications | Where Id -eq '68c5b0a3-d1a6-4553-ae49-01d3a7827828').Title | Should be 'Service Packs'
It 'Should have enabled the Update Rollups' {
($Classifications | Where Id -eq '28bc880e-0592-4cbf-8f95-c79b17911d5f').Title | Should be 'Update Rollups'
It 'Should have enabled the Updates' {
($Classifications | Where Id -eq 'cd5ffd1e-e932-4e3a-bf74-18bf0b1bbd83').Title | Should be 'Updates'
Context 'Languages' {
It 'should only sync English language' {
(Get-WsusServer).GetConfiguration().GetEnabledUpdateLanguages() | Should be 'en'
Context 'Sync schedule' {
It 'Should sync manually' {
(Get-WsusServer).GetSubscription().SynchronizeAutomatically | Should be $false
Context 'Auto approval rules' {
It 'Should not have automatic approval rules' {
((Get-WsusServer).GetInstallApprovalRules() | Where Name -eq 'Default Automatic Approval Rule').Enabled | Should be $false
Context 'Computer target groups' {
It 'Should have a Windows 7 x64 target group' {
((Get-WsusServer).GetComputerTargetGroups() | Where Name -eq 'Windows 7 x64').Name | should be 'Windows 7 x64'

…I’m actually ready to assess the operational readiness of my WSUS configuration by using the following cmdlet:

Invoke-Pester -Script ~/Documents/Pester/Test-WSUS.Tests.ps1


I still feel like a Pester newbie but no doubt that Pester rocks 😎

Import the convenience update into WSUS

My WSUS server runs on a Windows Core edition where I don’t have Internet Explorer installed.

Whatif I want to import the Convenience rollup update for Windows 7 SP1 and Windows Server 2008 R2 SP1 from the catalog?

Here’s the way to go:

On a client computer with a GUI, launch internet explorer with high privileges to be able to install the ActiveX.

$HT = @{
 FilePath = 'C:\Program Files (x86)\Internet Explorer\iexplore.exe' ;
 ArgumentList = 'http://catalog.update.microsoft.com/v7/site/Search.aspx?q=KB3125574' ;
 Verb = 'Runas'
Start-Process @HT


Install the ActiveX, add the update to the basket, view your basket, download, browse…
Move the file onto the WSUS server…and check if the file is digitally signed

Get-AuthenticodeSignature -FilePath ~\downloads\Catalog\*\*.msu

The WSUS API has an ImportUpdateFromCatalogSite, documented here on msdn.

I’m missing the UpdateID. Where do I find this Id?

It appears that if you click on the link highlighted below…


…you get on a page where you’ve more details about the update.


The updateId actually appears in the address bar. 😀

Now, to import the update into WSUS, I do:

$MSUfile = 'C:\Users\administrator\Downloads\Catalog\Update for Windows 7 for x64-based Systems (KB3125574)\AMD64-all-windows6.1-kb3125574-v4-x64_2dafb1d203c8964239af3048b5dd4b1264cd93b9.msu'
# Find the imported file
(Get-WsusServer).SearchUpdates('3125574') | fl *

The convenience update has been successfully imported and can now be approved.