How to delete upgrades in WSUS


(Alternative title: "Help, I synched Upgrades before installing the patch!" 

This applies to anyone who missed KB 3095113 when it was offered as a hotfix, and subsequently enabled synching of Upgrades in their environment.  The upgrades that were downloaded happen to be from the Windows 10 1511 feature upgrade, but these steps could be modified to suit a similar purpose for a different set of content.)

In this scenario, WSUS has downloaded content that it cannot use.  Because parsing only happens once, and WSUS does not know what “Upgrades” are without having installed KB 3095113, it incorrectly identifies the upgrade as a regular update and saves it to the SUSDB as such.  In order to remedy this, you must perform the following sequence of steps on the WSUS servers as specified in the table below (where "USS" represents "upstream server"):

Action

Where to perform

1.       Disable the “Upgrades” classification

USS or Standalone WSUS

2.       Delete the previously synched upgrades

All WSUS (start with topmost server)

3.       Enable the “Upgrades” classification

USS or Standalone WSUS

4.       Perform full sync

USS or Standalone WSUS

Some workarounds propose that you delete these entries from the SUSDB via SQL queries, but we do not recommend directly modifying database content.  The supported way to remove update content is with PowerShell commands [from an elevated session] as described below.  Again, be sure that you perform the deletion step on the WSUS server that is highest in your hierarchy first, and then work your way down; otherwise, your deletions may be replaced by the USS on the next sync attempt. 

// disable Upgrades classification on local WSUS server

Get-WsusClassification | Where-Object -FilterScript {$_.Classification.Title -Eq “Upgrades”} | Set-WsusClassification -Disable  

// delete all update content on the current server belonging to the 1511 release

$s = Get-WsusServer

$s.SearchUpdates(“version 1511, 10586”) | foreach { $s.DeleteUpdate($_.Id.UpdateId) } 

// enable Upgrades classification

Get-WsusClassification | Where-Object -FilterScript {$_.Classification.Title -Eq “Upgrades”} | Set-WsusClassification 

// perform full sync

$sub = $s.GetSubscription()

$sub.StartSynchronization()

Comments (33)

  1. fr says:

    What if you have enabled the Upgrades classification on WSUS 3.2? The powershell commands wont work with this version. Can I just run them after migrating the DB to a newer WSUS server?

  2. fr: WSUS 3.2 does not support Upgrades, so it should not have this classification enabled. You can disable this classification through the WSUS UI, and then decline the upgrades, after which you can run Server Cleanup Wizard to remove them from your SUSDB.
    If you're planning to migrate to a new WSUS, then we recommend completing that migration before attempting to clean up your SUSDB, since these upgrades won't cause any issues if they show up in the new SUSDB. After the migration, you can use the PowerShell
    commands as described in this post.

  3. Giles says:

    This worked a treat on our server. Previously the downloads were getting to the client but then failing to install.

  4. Ruud de Vries says:

    Almost worked like a charm.
    Only got 1 error on the deleting action but the error message was informational enough that it indicates that the update was still applied.

    First I put it to NA for all computer groups.
    Then the deletion went fine.

  5. Greg P says:

    When running then uninstall scripts the curser just returns to "PS C:".
    I assume that all the processing has occurred without error or you would see such?

    1. Kasper Jensen says:

      Greg P: none of the commands have the -Verbose switch, so indeed they will be silent, and errors/warnings will only appear if something went wrong.

  6. Leo says:

    I'm getting this error, please help:
    Exception calling "DeleteUpdate" with "1" argument(s): "spDeleteRevision: cannot delete revisionid: 263047 because it
    is still deployed to a Non DSS Target Group
    spDeleteUpdate got error from spDeleteRevision
    spDeleteUpdateByUpdateID got error from spDeleteUpdate"
    At line:1 char:53
    + $s.SearchUpdates(“version 1511, 10586”) | foreach { $s.DeleteUpdate($_.Id.Update ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SqlException

    1. You must uninstall that update from all machines reporting to that WSUS before deleting it; otherwise, the SUSDB does not contain updates that its clients have installed, which is an inconsistent state.

      1. Allen says:

        Steve...

        I am receiving this same error, too.
        Is there a quick (Powershell) way of unapproving and uninstalling the updates from the clients that have it installed?

        1. Allen, the PowerShell cmdlets provide access to the Microsoft.UpdateServices.Administration namespace, inside which you'll find IUpdateApproval (https://msdn.microsoft.com/en-us/library/microsoft.updateservices.administration.iupdateapproval(v=vs.85).aspx). This is the interface that allows you to remove prior approvals.

  7. Kevin says:

    Hi

    I am running the commands how long should the delete all update content take to complete on average ? My power shell has been sat for 10 minutes and still hasn't gone back to PS command prompt indicating it has finished the task.

    1. Deleting all content can take a while, but just the Upgrades shouldn't take much time at all. How long did it end up taking you?

      1. Rich668 says:

        Hi I am having the same issue. When I run the command it has not finished and it has been running for over 12 hours and i can see CPU is using 25% with the cmd. Would you please provide how to make the cmd write to the Powershell window with Verbose. I have a feeling although I am using the cmd -verbose i may be using the syntax wrong.

  8. John 75 says:

    It seems to me that there could be another workaround to this issue. Consider the following scenario: Someone builds a new Server 2012 R2 downstream WSUS server. This new server completes its first sync before rebooting for KB3095113 installation. This results in this particular downstream server having the unusable feature upgrade content that we are concerned about. For the proposed workaround, why could you not uninstall and reinstall WSUS from the newly built problematic downstream server? When uninstalling WSUS, leave the WsusContent behind but delete the SUSDB. When reinstalling WSUS, use the same WsusContent as before. But this time, make sure we reboot the server after installing KB3095113 but before completing the first sync. This proposed 'workaround' only affects the problematic server rather than having to touch every single WSUS server in the environment as the article suggests.

    1. Every SUSDB that contains the unusable content will need to delete that content to make room for the correct update content. How you do that is up to you, but I think deleting updates via PowerShell on several servers is easier than reinstalling a single WSUS.

      1. John 75 says:

        Thanks for your feedback, Steve! When one has over 200+ downstream WSUS servers in their environment and not all are accessible at any given time, the uninstalling and reinstalling WSUS on a single server becomes a more desirable scenario.

  9. Johnny says:

    My company environment has an upstream server (server 2012) which was patched and 13 downstream replica servers (server 2012 R2)that were unpatched. Despite this we have enable the sync of Windows 10 updates/upgrades on the upstream server as we are running test on our Windows 10 SOE machines. Do we need to clean up WSUS now on the replica servers? or can we upgrade them with the hotfix and this should fix the problem?

    1. Johnny says:

      This has been rectified by installing some updates. The update view did not sync to the replica server but manually setup.

    2. Anywhere that received metadata that could not be parsed at the time needs to be cleaned up. If the replicas all copied this update, then my recommendation would be to delete it everywhere, and then sync it again at your top-level server.

  10. Michael M says:

    The powershell line to delete all the 1511 updates worked, and took about 2 minutes to complete.

    Does anyone know what needs to change to have it run against the 1607 upgrades I need to delete too?

    1. Deleting encrypted feature updates is slightly more complicated. Full coverage is provided in the new blog post: https://blogs.technet.microsoft.com/wsus/2016/09/21/resolving-error-0xc1800118/

  11. GOLFUSMC says:

    Update to fix script-
    I wanted to provide some additional scripting to help with this process. If you run this there is no type of logging to find out how long it will take.
    Get-WsusClassification | Where-Object -FilterScript {$_.Classification.Title -Eq “Upgrades”} | Set-WsusClassification -Disable

    # delete all update content on the current server belonging to the 1511 release

    $wsus = Get-WsusServer
    ($wsus.SearchUpdates(“Windows 10 Education, version 1511, 10586”)).Count
    $wsus.SearchUpdates(“Windows 10 Education, version 1511, 10586”) | foreach { Write-Host "Deleting $($_.Title)" -ForegroundColor Yellow; $wsus.DeleteUpdate($_.Id.UpdateId) }
    ($wsus.SearchUpdates(“Windows 10 Pro, version 1511, 10586”)).Count
    $wsus.SearchUpdates(“Windows 10 Pro, version 1511, 10586”) | foreach { Write-Host "Deleting $($_.Title)" -ForegroundColor Cyan; $wsus.DeleteUpdate($_.Id.UpdateId) }
    ($wsus.SearchUpdates(“Windows 10 Enterprise, version 1511, 10586”)).Count
    $wsus.SearchUpdates(“Windows 10 Enterprise, version 1511, 10586”) | foreach { Write-Host "Deleting $($_.Title)" -ForegroundColor Green; $wsus.DeleteUpdate($_.Id.UpdateId) }

    # delete all update content on the current server belonging to the 1607 release

    ($wsus.SearchUpdates(“Windows 10 Pro, version 1607”)).Count
    $wsus.SearchUpdates(“Windows 10 Pro, version 1607”) | foreach { Write-Host "Deleting $($_.Title)" -ForegroundColor Yellow; $wsus.DeleteUpdate($_.Id.UpdateId) }
    ($wsus.SearchUpdates(“Windows 10 Education, version 1607”)).Count
    $wsus.SearchUpdates(“Windows 10 Education, version 1607”) | foreach { Write-Host "Deleting $($_.Title)" -ForegroundColor Cyan; $wsus.DeleteUpdate($_.Id.UpdateId) }
    ($wsus.SearchUpdates(“Windows 10 Enterprise, version 1607”)).Count
    $wsus.SearchUpdates(“Windows 10 Enterprise, version 1607”) | foreach { Write-Host "Deleting $($_.Title) NON EN-US" -ForegroundColor Green; $wsus.DeleteUpdate($_.Id.UpdateId) }
    #($wsus.SearchUpdates(“Windows 10 Enterprise, version 1607”) | ? {$_.title -notlike "*en-us*"}).Count
    #$wsus.SearchUpdates(“Windows 10 Enterprise, version 1607”) | ? {$_.title -notlike "*en-us*"} | foreach { Write-Host "Deleting $($_.Title) NON EN-US" -ForegroundColor Green; $wsus.DeleteUpdate($_.Id.UpdateId) }

    # enable Upgrades classification

    Get-WsusClassification | Where-Object -FilterScript {$_.Classification.Title -Eq “Upgrades”} | Set-WsusClassification

    # perform full sync

    $sub = $s.GetSubscription()
    $sub.StartSynchronization()

    Good Luck and Keep PS Scripting
    -Gregory Hindman

    1. You absolute star, GOLFUSMC 🙂

  12. KO says:

    I’m getting the same error as Leo. I don't know how to uninstall these updates from the clients.
    wusa /uninstall /kb:95975 /quiet /norestart ??? doesn't work because it's the revision and not the kb number...heeeeeeeeeelp
    revisionid: 95975 //Replika Server
    revisionid: 96734 //Replika Server

    revisionid: 145766 //Upstream Server
    revisionid: 146557 //Upstream Server

    Ausnahme beim Aufrufen von "DeleteUpdate" mit 1 Argument(en): "spDeleteRevision: cannot delete revisionid: 95975 because it is still deployed to a Non DSS Target Group
    spDeleteUpdate got error from spDeleteRevision
    spDeleteUpdateByUpdateID got error from spDeleteUpdate"
    In xxxnew.ps1:8 Zeichen:129
    + ... undColor Cyan; $wsus.DeleteUpdate($_.Id.UpdateId) }
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SqlException

    1. KO says:

      aaaaaaaaaaaah i think i get it. i have to uninstall 1511 and 1607 update but how?
      Due to the issue i updated the clients throught media creation tool so uninstall is not possible...

      I deleted every computer from WSUS Console, but that didn't help.
      Is there a way to determine the client which is causing the error message?

      1. WSUS uses the language "approve for uninstall": https://technet.microsoft.com/en-us/library/hh826164.aspx. You could look in the WSUS console to determine which client(s) have installed the update.

  13. One additional point. If you're using SCCM, make sure to disable upgrades via SCCM rather than the the powershell above. If you don't, SCCM will re-enable it on its next sync and might put them all back again before the job to delete all the content has completed.

    1. Thanks for pointing this out, OffColour.

  14. Rick says:

    Attempted this on 2012 R2 running WSUS role, logged on as either domain admin or local server admin;
    The Get-Wsuserver command fails with the message, The request failed with HTTP status 403: Forbidden

    Domain Admins are a member of the group WSUS Administrators;
    I've tried the command using the options -name mywsusserver -portnumber 8530
    Same result

    Also, what is the correct search term for the 1607 version in the second line

    TIA

    1. Rick says:

      Additional info

      I've also tried the Get-WsusServer command using SSL and the 8531 port number.
      The connection is closed because the trust relationship could not be established.

      1. Is your WSUS part of a different forest, perhaps an untrusted one? What does your topology look like?

Skip to main content