Some WSUS Products now have duplicate titles (i.e. Windows Server 2019)

blueblade 26 Reputation points
2021-01-25T21:06:12.183+00:00

Microsoft is putting different products in that have the same title now!?

I have a script to automatically configure WSUS servers, including setting the products, languages, and classifications.

I noticed it started having this error about the product already being enabled for Windows Server 2019. The script log shows it trying to enable the same product twice. I thought it was a mistake at first but then I noticed, there are now actually 2 different products with the same title, and nearly the same description. One of them is OS patches, the other is under a category of "Developer Tools, Runtimes, and Redistributables"
Script-wise, it's almost impossible to tell them apart, to know which is which. I want to tell it to enable "Windows Server 2019" but then it also enables the developer tools version of it too.

They do have a unique ID, but these are not user friendly to obtain, remember, or specify, plus it is still hard to know which "Windows Server 2019" is which.
In PowerShell, run:
Get-WsusProduct -TitleIncludes "Windows Server 2019"
You will notice 2 different products with exact same title of "Windows Server 2019"
Their description doesn't help either. One has a description of "Category for Windows Server 2019" and the other says "Windows Server 2019 (RS5 Server) and above"

Can the "Developer Tools, Runtimes, and Redistributables" have it's title/description updated to add "Developer Tools, Runtimes and Redistributables" and otherwise make it unique and/or easy to distinguish from the WS2019 OS patch category and avoid confusion?
Commands in scripts like:
Get-WsusProduct | Where {$_.Product.Title -eq "Windows Server 2019"} | Set-WsusProduct
Now no longer work and enable both products. Argh!

This is the case for several duplicate products if you Group the output of Get-WsusProduct by their product.title:
Count Name


2 Azure Connected Machine Agent
2 Device Health
2 Microsoft Advanced Threat Analytics
2 Silverlight
2 Virtual Server
2 Visual Studio 2010 Tools for Office Runtime
2 Windows 10 Creators Update and Later Servicing Drivers
2 Windows 10, version 1903 and later
2 Windows Admin Center
3 Windows Live
2 Windows Server 2016
2 Windows Server 2019
2 Windows Server, version 1903 and later

What a pain...

Windows for business | Windows Server | User experience | Other
0 comments No comments
{count} votes

4 answers

Sort by: Most helpful
  1. abbodi86 4,036 Reputation points
    2021-01-26T19:05:32.13+00:00

    You can differentiate the two products based on Parent Category
    then incorporate IDs for comparison

    [void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
    $wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer()
    $DesiredProducts = ($wsus.GetUpdateCategories() | Where {$_.Title -EQ "Windows"}).GetSubcategories() | Where {$_.Title -EQ "Windows Server 2019"} | Select Title, ID
    Write-Host "Desired products to be enabled:`n $($DesiredProducts.Title)"
    
    $Wsus = Get-WsusServer
    $Subscription = $Wsus.GetSubscription()
    $EnabledProducts = $Subscription.GetUpdateCategories() | Select Title, ID
    Write-Host "The following products are currently enabled: $($EnabledProducts.Title -Join '; ')"
    
    $Differences = @(compare $EnabledProducts $DesiredProducts -Property Title, ID)
    If ($Differences.Count -gt 0) {
        # product list doesn't match- Show the differences, then correct them
        $DiffTable = $Differences | Select @{Name="Product";Expression={$_.Title}} , @{Name="Difference";Expression={If($_.SideIndicator -eq "<=") {"Extra Product"} Else {"Missing Product"}}} | Format-Table | Out-String
        Write-Host "Diffrerences between Current Product settings and Desired product settings:`n$DiffTable" -ForegroundColor Cyan
        foreach ($Difference in $Differences) {
             $ProductTitle = $Difference.Title
             $ProductID = $Difference.ID.Guid
             $ProductObj = Get-WsusProduct | where {$_.Product.ID -eq $ProductID}
             If (-not ([bool] $ProductObj)) {
                 Write-Error "Product '$ProductTitle' is not a product WSUS knows about.  You may need to perform a Category Synchronization to discover new product definitions."
             } Else {
                 If($Difference.SideIndicator -eq "<=") {
                     # Extra product - Disable it
                     Write-Host "Disabling extra product: '$ProductTitle'"
                     $ProductObj | Set-WsusProduct -Disable -Verbose
                 } Else {
                     # Missing product - Enable it
                     Write-Host "Enabling missing product: '$ProductTitle'"
                     $ProductObj | Set-WsusProduct -Verbose
                 }
             }
        }
    } Else {
         #Product list matches
         Write-Host "No WSUS product changes required." -ForegroundColor Green
    }
    
    1 person found this answer helpful.

  2. Rita Hu -MSFT 9,661 Reputation points
    2021-01-26T02:54:29.257+00:00

    Hi blueblade-8067,

    Thanks for your posting on Q&A.

    In order to help me research further, please consider providing the associated screenshot of the duplicate titles phenomenon and related error information.

    Thanks for your understanding and cooperation.

    Regards,
    Rita

    0 comments No comments

  3. blueblade 26 Reputation points
    2021-01-26T15:57:45.367+00:00

    No problem @Rita Hu -MSFT ; Attached are some screenshots of the duplicate products under different categories.
    60679-wsus-duplicate-products-1.png

    60608-wsus-duplicate-products-2.png

    My script doesn't actually error out, but performs the wrong operations due to duplicate titles. It accepts a list of products you want enabled in WSUS, compares that list to the currently enabled products, and then enables the missing products and disables the extra products.

    $DesiredProducts = @('Windows Server 2019')  
    Write-Host "Desired products to be enabled:`n $DesiredProducts"  
    $Wsus = Get-WsusServer  
    $Subscription = $Wsus.GetSubscription()  
    $EnabledProducts = @($Subscription.GetUpdateCategories() | foreach {$_.Title})  
    Write-Host "The following products are currently enabled: $($EnabledProducts -Join '; ')"  
    $Differences = @(compare $EnabledProducts $DesiredProducts)  
    If ($Differences.Count -gt 0) {  
        # product list doesn't match- Show the differences, then correct them  
        $DiffTable = $Differences | Select @{Name="Product";Expression={$_.InputObject}} `  
        , @{Name="Difference";Expression={If($_.SideIndicator -eq "<=") {"Extra Product"} Else {"Missing Product"}}} `  
        | Format-Table | Out-String  
        Write-Host "Diffrerences between Current Product settings and Desired product settings:`n$DiffTable" -ForegroundColor Cyan  
        foreach ($Difference in $Differences) {  
            $ProductTitle = $Difference.InputObject  
            $ProductObj = Get-WsusProduct | where {$_.Product.Title -eq $ProductTitle}  
            If (-not ([bool] $ProductObj)) {  
                Write-Error "Product '$ProductTitle' is not a product WSUS knows about.  You may need to perform a Category Synchronization to discover new product definitions."  
            } Else {  
                If($Difference.SideIndicator -eq "<=") {  
                    # Extra product - Disable it  
                    Write-Host "Disabling extra product: '$ProductTitle'"  
                    $ProductObj | Set-WsusProduct -Disable -Verbose  
                } Else {  
                    # Missing product - Enable it  
                    Write-Host "Enabling missing product: '$ProductTitle'"  
                    $ProductObj | Set-WsusProduct -Verbose  
                }  
            }  
        }  
    } Else {  
        #Product list matches  
        Write-Host "No WSUS product changes required." -ForegroundColor Green  
    }  
    

    The script always takes the wrong action-- it either sees Windows 2019 as missing and enables 2, or it sees Windows 2019 as extra and disables both.
    60609-wsus-duplicate-product-grief.png

    0 comments No comments

  4. Anders Haglund 6 Reputation points
    2021-02-04T09:06:33.957+00:00

    Sorry for hijacking the question, but I am struggling with my Ansible-modules for WSUS, and this duplicate title debacle has made me have to move over to working with "Id" in my parameters, ruining the human readability in YAML.

    Another reason for that, is the brilliant idea of using a dash thats not a dash in a category name: Windows Server Manager – Windows Server Update Services (WSUS) Dynamic Installer

    https://github.com/dsccommunity/UpdateServicesDsc/issues/47

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.