ML
    • Recent
    • Categories
    • Tags
    • Popular
    • Users
    • Groups
    • Register
    • Login

    WSUS Help

    IT Discussion
    14
    69
    4.5k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      siringo
      last edited by

      Finally setup wsus on a 2016 server. All went well except I told it I wanted updates for Windows 7, which I've decided I don't want.

      I told it I want updates for Windows 10 and it's downloading updates for all flavours of Windows 10, we only run Pro. So far it's filled up the 200GBs I set aside for it only 3 days ago.

      I can uninstall wsus and start again, that's not a problem, is that the quickest and easiest way to get some of my 200GBs back and start over?

      And, how can I tell it I only want updates for W10 Pro?

      And, if anyone has a link to a 'I don't want to think too much' guide for setting up wsus, I'd be keen to take a look.

      Thanks for any help.

      P 1 Reply Last reply Reply Quote 1
      • N
        nadnerB
        last edited by

        How's your powershell?
        I use the script below to weed out the crapola, and it's possibly unnecessarily long, but I like to see how many of what update type gets toasted. Following that, it's a server clean up (WSUS options).

        $WsusServer = "<WSUS server>"
        
        $UseSSL = $true
        
        $PortNumber = 8531
        
        $TrialRun = 0
        
        # 1 = Yes
        
        # 0 = No
        
        
        
        # Deliver the results by email
        
        Function Mailer
        
            {
        
             $emailTo = "<Select a contestant>"
        
             $emailFrom = "<Don't be a secret squirrel>" 
        
             $subject="WSUS - Declined Updates" 
        
             $smtpserver="<mailserver>" 
        
             $smtp=new-object System.Net.Mail.SmtpClient($smtpServer)
        
             $Message = @" 
        
                                         
        
            $IA64_counted Itanium updates have been declined.
        
            $Office64_count MS Office 64-Bit updates have been declined.
        
            $sharepoint_counted SharePoint updates have been declined.
        
            $Windowsx86_counted Windows 7 & 10 x86 updates have been declined.
        
            $FarmDeploy_count Farm Deployment updates have been declined
        
         
        
            Thank you, 
        
            Your trusty WSUS server
        
        "@ 
        
             If ($TrialRun -eq 1)
        
                {
        
                    $Subject += " Trial Run"
        
                }
        
        
        
             #$smtp.Send($emailFrom, $emailTo, $subject, $message)
        
             Send-MailMessage -From $emailFrom -To $emailTo -Subject $subject -Body $message -SmtpServer $smtpserver
        
            }
        
        
        
        # Connect to the WSUS 3.0 interface.
        
        [reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | out-null
        
        $WsusServerAdminProxy = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer(); #$WsusServer,$UseSSL,$PortNumber
        
        
        
        # Searching in just the title of the update
        
        # Itanium/IA64
        
        $itanium = $WsusServerAdminProxy.GetUpdates() | ?{-not $_.IsDeclined -and $_.Title -match “ia64|itanium|itanium-based”}
        
        $IA64_counted = $itanium.count
        
            If ($itanium.count -lt 1)
        
                {
        
                    $IA64_counted = 0
        
                }
        
            If ($TrialRun -eq 0 -and $itanium.count -gt 0)
        
                {
        
                    $itanium  | %{$_.Decline()}
        
                }
        
        # MS Office 64-Bit
        
        $Office64 = $WsusServerAdminProxy.GetUpdates() | ?{-not $_.IsDeclined -and $_.Title -match “Excel|Lync|Office|Outlook|Powerpoint|Visio|word” -and $_.Title -match "64-bit"}
        
        $Office64_count = $Office64.count
        
            If ($Office64.count -lt 1)
        
                {
        
                    $Office64_count = 0
        
                }
        
            If ($TrialRun -eq 0 -and $Office64.count -gt 0)
        
                {
        
                    $Office64 | %{$_.Decline()}
        
                }
        
        # SharePoint
        
        $sharepoint = $WsusServerAdminProxy.GetUpdates() | ?{-not $_.IsDeclined -and $_.Title -match “SharePoint”}
        
        $sharepoint_counted = $sharepoint.count
        
            If ($sharepoint.count -lt 1)
        
                {
        
                    $sharepoint_counted = 0
        
                }
        
            If ($TrialRun -eq 0 -and $sharepoint.count -gt 0)
        
                {
        
                    $sharepoint | %{$_.Decline()}
        
                }
        
        #Windows 10
        
        $Windowsx86 = $WsusServerAdminProxy.GetUpdates() | ?{-not $_.IsDeclined -and $_.Title -match “Windows 10|Windows 7” -and $_.Title -match "x86-based|ARM64-based"}
        
        $Windowsx86_counted = $Windowsx86.count
        
            If ($Windowsx86.count -lt 1)
        
                {
        
                    $Windowsx86_counted = 0
        
                }
        
            If ($TrialRun -eq 0 -and $Windowsx86.count -gt 0)
        
                {
        
                    $Windowsx86 | %{$_.Decline()}
        
                }
        
        #Farm deployment includes Office & SharePoint
        
        $FarmDeploy = $WsusServerAdminProxy.GetUpdates() | ?{-not $_.IsDeclined -and $_.Title -match "farm-deployment"}
        
        $FarmDeploy_count = $FarmDeploy.count
        
            If ($FarmDeploy.count -lt 1)
        
                {
        
                    $FarmDeploy_count = 0
        
                }
        
            If ($TrialRun -eq 0 -and $FarmDeploy.count -gt 0)
        
                {
        
                    $FarmDeploy | %{$_.Decline()}
        
                }
        
             
        
        Mailer
        
        S 1 Reply Last reply Reply Quote 3
        • S
          siringo @nadnerB
          last edited by

          @nadnerb Thanks mate. I got impatient and just uninstalled the wsus & iis roles & reformatted the drive that held the wsus updates.
          I then reinstalled wsus & found that my wsus config remained. This may not be a big problem, I'm hoping that wsus will see I have no updates and will just go looking for updates that match my selections in the 'Products & Classifications' listing.

          1 Reply Last reply Reply Quote 0
          • S
            siringo
            last edited by

            Do you guys download all the Flash Player updates in your WSUS's?

            ObsolesceO 1 Reply Last reply Reply Quote 0
            • ObsolesceO
              Obsolesce @siringo
              last edited by

              @siringo said in WSUS Help:

              Do you guys download all the Flash Player updates in your WSUS's?

              Flash player is incredibly important to keep updated.

              S 1 Reply Last reply Reply Quote 0
              • S
                siringo @Obsolesce
                last edited by

                @obsolesce said in WSUS Help:

                @siringo said in WSUS Help:

                Do you guys download all the Flash Player updates in your WSUS's?

                Flash player is incredibly important to keep updated.

                OK, so that's a yes, thanks.

                I went through my updates manually and removed alot of garbage, got it down from 200GBs to 97GBs.

                I only want updates for W10 Pro x64 and 2016, does around 100GBs sound right for those 2 OSs or am I asking a pretty open ended question?

                DustinB3403D dbeatoD 2 Replies Last reply Reply Quote 0
                • DustinB3403D
                  DustinB3403 @siringo
                  last edited by

                  @siringo said in WSUS Help:

                  @obsolesce said in WSUS Help:

                  @siringo said in WSUS Help:

                  Do you guys download all the Flash Player updates in your WSUS's?

                  Flash player is incredibly important to keep updated.

                  OK, so that's a yes, thanks.

                  I went through my updates manually and removed alot of garbage, got it down from 200GBs to 97GBs.

                  I only want updates for W10 Pro x64 and 2016, does around 100GBs sound right for those 2 OSs or am I asking a pretty open ended question?

                  That sounds reasonable, you should also run the steps on this website or script it to be run via task scheduler to clean up any out of date updates.

                  https://technet.microsoft.com/en-us/library/bb432641.aspx

                  1 Reply Last reply Reply Quote 0
                  • dbeatoD
                    dbeato @siringo
                    last edited by

                    @siringo said in WSUS Help:

                    @obsolesce said in WSUS Help:

                    @siringo said in WSUS Help:

                    Do you guys download all the Flash Player updates in your WSUS's?

                    Flash player is incredibly important to keep updated.

                    OK, so that's a yes, thanks.

                    I went through my updates manually and removed alot of garbage, got it down from 200GBs to 97GBs.

                    I only want updates for W10 Pro x64 and 2016, does around 100GBs sound right for those 2 OSs or am I asking a pretty open ended question?

                    Windows 10 has the Updates for all versions as they apply to all Windows 10 of that Version , be it 1607, 1703, 1709 or 1803. You can see what I have selected on my WSUS Server below:
                    1_1533042806492_2018-07-31_09-13-06.png 0_1533042806491_2018-07-31_09-12-52.png
                    I have only 35 GB of WSUS Files used (I do monthly cleanups)
                    0_1533042902532_2018-07-31_09-13-58.png

                    ObsolesceO 1 Reply Last reply Reply Quote 1
                    • ObsolesceO
                      Obsolesce @dbeato
                      last edited by

                      @dbeato

                      0_1533048243638_ce1a7187-5b4b-4ecc-90fd-8fa3ffd3cfc7-image.png

                      0_1533048291512_80903472-d04f-4d0f-992e-e4c27e120a8f-image.png

                      0_1533048317766_9977b24e-c501-4bac-bc47-57a35ce8afdb-image.png

                      0_1533048361698_57ba01cd-e41a-41b5-8428-b5af4de61a88-image.png

                      0_1533048564427_d5247305-344c-4f9e-8913-933edf981ffd-image.png

                      1 Reply Last reply Reply Quote 1
                      • S
                        siringo
                        last edited by

                        Thanks guys that's a great help, much appreciated.

                        I'm installing my WSUS servers in preparation for when we move to W10. I can get office PCs setup OK, but people will wander in with different versions of W10 on laptops etc, so I'm setting up the WSUS servers to be able to offer updates for most builds.

                        Thanks again.

                        1 Reply Last reply Reply Quote 3
                        • P
                          pmoncho @siringo
                          last edited by

                          @siringo said in WSUS Help:

                          Finally setup wsus on a 2016 server. All went well except I told it I wanted updates for Windows 7, which I've decided I don't want.

                          I told it I want updates for Windows 10 and it's downloading updates for all flavours of Windows 10, we only run Pro. So far it's filled up the 200GBs I set aside for it only 3 days ago.

                          I can uninstall wsus and start again, that's not a problem, is that the quickest and easiest way to get some of my 200GBs back and start over?

                          And, how can I tell it I only want updates for W10 Pro?

                          And, if anyone has a link to a 'I don't want to think too much' guide for setting up wsus, I'd be keen to take a look.

                          Thanks for any help.

                          You may want to check out 🌶 for Clean-WSUS. Excellent script to help clean up WSUS.

                          JaredBuschJ S 2 Replies Last reply Reply Quote 0
                          • JaredBuschJ
                            JaredBusch @pmoncho
                            last edited by

                            @pmoncho said in WSUS Help:

                            @siringo said in WSUS Help:

                            Finally setup wsus on a 2016 server. All went well except I told it I wanted updates for Windows 7, which I've decided I don't want.

                            I told it I want updates for Windows 10 and it's downloading updates for all flavours of Windows 10, we only run Pro. So far it's filled up the 200GBs I set aside for it only 3 days ago.

                            I can uninstall wsus and start again, that's not a problem, is that the quickest and easiest way to get some of my 200GBs back and start over?

                            And, how can I tell it I only want updates for W10 Pro?

                            And, if anyone has a link to a 'I don't want to think too much' guide for setting up wsus, I'd be keen to take a look.

                            Thanks for any help.

                            You may want to check out 🌶 for Clean-WSUS. Excellent script to help clean up WSUS.

                            Except it is no longer available.

                            P 1 Reply Last reply Reply Quote 1
                            • S
                              siringo @pmoncho
                              last edited by

                              @pmoncho said in WSUS Help:

                              @siringo said in WSUS Help:

                              Finally setup wsus on a 2016 server. All went well except I told it I wanted updates for Windows 7, which I've decided I don't want.

                              I told it I want updates for Windows 10 and it's downloading updates for all flavours of Windows 10, we only run Pro. So far it's filled up the 200GBs I set aside for it only 3 days ago.

                              I can uninstall wsus and start again, that's not a problem, is that the quickest and easiest way to get some of my 200GBs back and start over?

                              And, how can I tell it I only want updates for W10 Pro?

                              And, if anyone has a link to a 'I don't want to think too much' guide for setting up wsus, I'd be keen to take a look.

                              Thanks for any help.

                              You may want to check out 🌶 for Clean-WSUS. Excellent script to help clean up WSUS.

                              Yep, I've looked at that. I may even subscribe to get the script as it's not a big $$$ outlay. I was prepared to pay $$$ for a WSUS alternative, but decided against it, so the small amount of $$$ for that script per annum is peanuts compared to what I was considering paying.

                              With W10 getting updates like we've never seen before for other versions of the OS, I reckon it's a good time to get WSUS sorted out and included in my knowledge base.

                              1 Reply Last reply Reply Quote 0
                              • ObsolesceO
                                Obsolesce
                                last edited by

                                I'd rather just move away from Windows, mainly because of their update issues.

                                black3dynamiteB S 2 Replies Last reply Reply Quote 0
                                • black3dynamiteB
                                  black3dynamite @Obsolesce
                                  last edited by

                                  @obsolesce said in WSUS Help:

                                  I'd rather just move away from Windows, mainly because of their update issues.

                                  I actually had to use a Windows 10 installer to upgrade a computer to version 1803.

                                  1 Reply Last reply Reply Quote 0
                                  • S
                                    siringo @Obsolesce
                                    last edited by

                                    @obsolesce said in WSUS Help:

                                    I'd rather just move away from Windows, mainly because of their update issues.

                                    Yep. Read just this morning that MS are working on some type of AI to work out if you're using your PC or not. Have you gone to get coffee or gone for a walk and if the AI thinks you're away for long enough it'll install updates & reboot your PC.

                                    Why not just do as they always had in the past and ask the user, do you want to install this now Y/N? & leave it up to the user.

                                    I know it's about patching because patching is a good thing and plug holes, increase security etc etc, but ....

                                    N 1 Reply Last reply Reply Quote 0
                                    • N
                                      nadnerB @siringo
                                      last edited by nadnerB

                                      @siringo said in WSUS Help:

                                      Why not just do as they always had in the past and ask the user, do you want to install this now Y/N? & leave it up to the user.

                                      I know it's about patching because patching is a good thing and plug holes, increase security etc etc, but ....

                                      The meatware has proved incompetent and unreliable reliably incompetent.

                                      EDIT: accuracy

                                      1 Reply Last reply Reply Quote 1
                                      • ObsolesceO
                                        Obsolesce
                                        last edited by

                                        If it would go as smoothly as Linux where you can let dnf automatic do it whenever and not kill your PC or server reliability , I'd use Windows more.

                                        1 Reply Last reply Reply Quote 0
                                        • S
                                          siringo
                                          last edited by siringo

                                          Stumbled across this script, I'm no powershell expert, my limit is spelling it correctly. Anyone want to have a look at this?

                                          From here:
                                          https://www.powershellgallery.com/packages/PSWsusSpringClean/0.4.0/Content/PSWsusSpringClean.psm1

                                          Function Invoke-WsusSpringClean {
                                          <#
                                          .SYNOPSIS
                                          Performs additional WSUS server clean-up beyond the capabilities of the built-in tools.
                                          .DESCRIPTION
                                          Adds the ability to decline numerous additional commonly unneeded updates as well as discover potentially incorrectly declined updates.
                                          .PARAMETER RunDefaultTasks
                                          Performs all clean-up tasks except for declining any unneeded updates as defined in the included update catalogue CSV file.

                                              You can disable one or more of the default clean-up tasks by setting the associated switch parameter to false (e.g. -CompressUpdates:$false). 
                                          
                                              You can perform a clean-up of unneeded updates by specifying the DeclineCategoriesInclude or DeclineCategoriesExclude parameter with your chosen categories. 
                                          
                                              Also note that this does not perform a server synchronisation before clean-up or find suspect declined updates. These tasks can be included via their respective parameters. 
                                              .PARAMETER SynchroniseServer 
                                              Perform a synchronisation against the upstream server before running cleanup. 
                                              .PARAMETER FindSuspectDeclines 
                                              Scan all declined updates for any that may have been inadvertently declined. 
                                          
                                              The returned suspect updates are those which: 
                                               - Are not superseded or expired 
                                               - Are not cluster or farm updates (if set to decline) 
                                               - Are not in the filtered list of updates to decline from the bundled catalogue 
                                              .PARAMETER DeclineClusterUpdates 
                                              Decline any updates which are exclusively for failover clustering installations. 
                                              .PARAMETER DeclineFarmUpdates 
                                              Decline any updates which are exclusively for farm deployment installations. 
                                              .PARAMETER DeclinePrereleaseUpdates 
                                              Decline any updates which are exclusively for pre-release products (e.g. betas). 
                                              .PARAMETER DeclineSecurityOnlyUpdates 
                                              Decline any Security Only updates. 
                                              .PARAMETER DeclineArchitectures 
                                              Array of update architectures to decline. 
                                          
                                              Valid options are: x64, ia64, arm64 
                                          
                                              We don't support declining x86 updates as there's no mechanism to determine which updates are x86 specific versus multi-architecture. 
                                              .PARAMETER DeclineCategoriesExclude 
                                              Array of update categories in the bundled updates catalogue to not decline. 
                                              .PARAMETER DeclineCategoriesInclude 
                                              Array of update categories in the bundled updates catalogue to decline. 
                                              .PARAMETER DeclineLanguagesExclude 
                                              Array of update language codes to not decline. 
                                              .PARAMETER DeclineLanguagesInclude 
                                              Array of update language codes to decline. 
                                              .PARAMETER CleanupObsoleteComputers 
                                              Specifies that the cmdlet deletes obsolete computers from the database. 
                                              .PARAMETER CleanupObsoleteUpdates 
                                              Specifies that the cmdlet deletes obsolete updates from the database. 
                                              .PARAMETER CleanupUnneededContentFiles 
                                              Specifies that the cmdlet deletes unneeded update files. 
                                              .PARAMETER CompressUpdates 
                                              Specifies that the cmdlet deletes obsolete revisions to updates from the database. 
                                              .PARAMETER DeclineExpiredUpdates 
                                              Specifies that the cmdlet declines expired updates. 
                                              .PARAMETER DeclineSupersededUpdates 
                                              Specifies that the cmdlet declines superseded updates. 
                                              .EXAMPLE 
                                              PS C:\>$SuspectDeclines = Invoke-WsusSpringClean -RunDefaultTasks -FindSuspectDeclines 
                                          
                                              Runs the default clean-up tasks & checks for declined updates that may not be intentional. 
                                              .EXAMPLE 
                                              PS C:\>Invoke-WsusSpringClean -DeclineCategoriesInclude @('Region - US', 'Superseded') 
                                          
                                              Declines all unneeded updates in the "Region - US" & "Superseded" categories. 
                                              .EXAMPLE 
                                              PS C:\>Invoke-WsusSpringClean -DeclineLanguagesExclude @('en-AU') 
                                          
                                              Declines all language specific updates excluding those for English (Australia). 
                                              .EXAMPLE 
                                              PS C:\>Invoke-WsusSpringClean -DeclineArchitectures @('arm64', 'ia64') 
                                          
                                              Declines all architecture specific updates for ARM64 & IA64 (Itanium) systems. 
                                              .NOTES 
                                              The script intentionally avoids usage of most WSUS cmdlets provided by the UpdateServices module as many are extremely slow. This is particularly true of the Get-WsusUpdate cmdlet. 
                                          
                                              The efficiency of the update declining logic could be substantially improved. That said, this script is not typically run frequently (~monthly), so this isn't a major priority. 
                                              .LINK 
                                              https://github.com/ralish/PSWsusSpringClean 
                                          #>
                                          
                                          [CmdletBinding(DefaultParameterSetName='Default',SupportsShouldProcess)]
                                          Param(
                                              [Switch]$RunDefaultTasks,
                                              [Switch]$SynchroniseServer,
                                              [Switch]$FindSuspectDeclines,
                                          
                                              [Switch]$DeclineClusterUpdates,
                                              [Switch]$DeclineFarmUpdates,
                                              [Switch]$DeclinePrereleaseUpdates,
                                              [Switch]$DeclineSecurityOnlyUpdates,
                                          
                                              [String[]]$DeclineCategoriesExclude,
                                              [String[]]$DeclineCategoriesInclude,
                                          
                                              [ValidateScript({Test-WsusSpringCleanArchitectures -Architectures $_})]
                                              [String[]]$DeclineArchitectures,
                                          
                                              [ValidateScript({Test-WsusSpringCleanLanguageCodes -LanguageCodes $_})]
                                              [String[]]$DeclineLanguagesExclude,
                                          
                                              [ValidateScript({Test-WsusSpringCleanLanguageCodes -LanguageCodes $_})]
                                              [String[]]$DeclineLanguagesInclude,
                                          
                                              # Wrapping of Invoke-WsusServerCleanup
                                              [Switch]$CleanupObsoleteComputers,
                                              [Switch]$CleanupObsoleteUpdates,
                                              [Switch]$CleanupUnneededContentFiles,
                                              [Switch]$CompressUpdates,
                                              [Switch]$DeclineExpiredUpdates,
                                              [Switch]$DeclineSupersededUpdates
                                          )
                                          
                                          # Ensure that any errors we receive are considered fatal
                                          $ErrorActionPreference = 'Stop'
                                          
                                          if ($PSBoundParameters.ContainsKey('DeclineCategoriesExclude') -and $PSBoundParameters.ContainsKey('DeclineCategoriesInclude')) {
                                              throw 'Can only specify one of DeclineCategoriesExclude and DeclineCategoriesInclude.'
                                          }
                                          
                                          if ($PSBoundParameters.ContainsKey('DeclineLanguagesExclude') -and $PSBoundParameters.ContainsKey('DeclineLanguagesInclude')) {
                                              throw 'Can only specify one of DeclineLanguagesExclude and DeclineLanguagesInclude.'
                                          }
                                          
                                          if (!$script:WscMetadata) {
                                              Import-WsusSpringCleanMetadata
                                          }
                                          
                                          if ($RunDefaultTasks) {
                                              $DefaultTasks = @(
                                                  'DeclineClusterUpdates',
                                                  'DeclineFarmUpdates',
                                                  'DeclinePrereleaseUpdates',
                                                  'DeclineSecurityOnlyUpdates',
                                          
                                                  'CleanupObsoleteComputers',
                                                  'CleanupObsoleteUpdates',
                                                  'CleanupUnneededContentFiles',
                                                  'CompressUpdates',
                                                  'DeclineExpiredUpdates',
                                                  'DeclineSupersededUpdates'
                                              )
                                          
                                              foreach ($Task in $DefaultTasks) {
                                                  if ($PSBoundParameters.ContainsKey($Task)) {
                                                      Set-Variable -Name $Task -Value (Get-Variable -Name $Task).Value -WhatIf:$false
                                                  } else {
                                                      Set-Variable -Name $Task -Value $true -WhatIf:$false
                                                  }
                                              }
                                          }
                                          
                                          # Regular expressions for declining certain types of updates
                                          $script:RegExClusterUpdates = ' Failover Clustering '
                                          $script:RegExFarmUpdates = ' Farm[- ]'
                                          $script:RegExPrereleaseUpdates = ' (Beta|Preview|RC1|Release Candidate) '
                                          $script:RegExSecurityOnlyUpdates = ' Security Only (Quality )?Update '
                                          
                                          # Determine which categories of updates to decline (if any)
                                          if ($PSBoundParameters.ContainsKey('DeclineCategoriesExclude') -or $PSBoundParameters.ContainsKey('DeclineCategoriesInclude')) {
                                              Import-WsusSpringCleanCatalogue
                                              $CatalogueCategories = $script:WscCatalogue.Category | Sort-Object | Get-Unique
                                          
                                              if ($PSBoundParameters.ContainsKey('DeclineCategoriesExclude')) {
                                                  $DeclineCategories = $CatalogueCategories | Where-Object { $_ -notin $DeclineCategoriesExclude }
                                              } else {
                                                  $DeclineCategories = $CatalogueCategories | Where-Object { $_ -in $DeclineCategoriesInclude }
                                              }
                                          }
                                          
                                          # Fetch the metadata for any architectures we're going to decline
                                          if ($PSBoundParameters.ContainsKey('DeclineArchitectures')) {
                                              $DeclineArchitecturesMetadata = @()
                                              foreach ($Architecture in $DeclineArchitectures) {
                                                  $DeclineArchitecturesMetadata += $script:WscMetadata.SelectSingleNode('//Architectures/Architecture[@name="{0}"]' -f $Architecture)
                                              }
                                          }
                                          
                                          # Fetch the metadata for any languages we're going to decline
                                          if ($PSBoundParameters.ContainsKey('DeclineLanguagesExclude')) {
                                              $DeclineLanguagesMetadata = $script:WscMetadata.Languages.Language | Where-Object { $_.code -notin $DeclineLanguagesExclude }
                                          } elseif ($PSBoundParameters.ContainsKey('DeclineLanguagesInclude')) {
                                              $DeclineLanguagesMetadata = $script:WscMetadata.Languages.Language | Where-Object { $_.code -in $DeclineLanguagesInclude }
                                          }
                                          
                                          if ($SynchroniseServer) {
                                              Write-Host -ForegroundColor Green "`r`nStarting WSUS server synchronisation ..."
                                              Invoke-WsusServerSynchronisation
                                          }
                                          
                                          Write-Host -ForegroundColor Green "`r`nBeginning WSUS server cleanup (Phase 1) ..."
                                          $CleanupWrapperParams = @{
                                              CleanupObsoleteUpdates=$CleanupObsoleteUpdates
                                              CompressUpdates=$CompressUpdates
                                              DeclineExpiredUpdates=$DeclineExpiredUpdates
                                              DeclineSupersededUpdates=$DeclineSupersededUpdates
                                          }
                                          Invoke-WsusServerCleanupWrapper @CleanupWrapperParams
                                          
                                          Write-Host -ForegroundColor Green "`r`nBeginning WSUS server cleanup (Phase 2) ..."
                                          $SpringCleanParams = @{
                                              DeclineClusterUpdates=$DeclineClusterUpdates
                                              DeclineFarmUpdates=$DeclineFarmUpdates
                                              DeclinePrereleaseUpdates=$DeclinePrereleaseUpdates
                                              DeclineSecurityOnlyUpdates=$DeclineSecurityOnlyUpdates
                                          }
                                          
                                          if ($DeclineCategories) {
                                              $SpringCleanParams += @{DeclineCategories=$DeclineCategories}
                                          }
                                          
                                          if ($DeclineArchitecturesMetadata) {
                                              $SpringCleanParams += @{DeclineArchitectures=$DeclineArchitecturesMetadata}
                                          }
                                          
                                          if ($DeclineLanguagesMetadata) {
                                              $SpringCleanParams += @{DeclineLanguages=$DeclineLanguagesMetadata}
                                          }
                                          
                                          Invoke-WsusServerSpringClean @SpringCleanParams
                                          
                                          Write-Host -ForegroundColor Green "`r`nBeginning WSUS server cleanup (Phase 3) ..."
                                          $CleanupWrapperParams = @{
                                              CleanupObsoleteComputers=$CleanupObsoleteComputers
                                              CleanupUnneededContentFiles=$CleanupUnneededContentFiles
                                          }
                                          Invoke-WsusServerCleanupWrapper @CleanupWrapperParams
                                          
                                          if ($FindSuspectDeclines) {
                                              Get-WsusSuspectDeclines @SpringCleanParams
                                          }
                                          

                                          }

                                          Function Get-WsusSuspectDeclines {
                                          [CmdletBinding()]
                                          Param(
                                          [Switch]$DeclineClusterUpdates,
                                          [Switch]$DeclineFarmUpdates,
                                          [Switch]$DeclinePrereleaseUpdates,
                                          [Switch]$DeclineSecurityOnlyUpdates,

                                              [String[]]$DeclineCategories,
                                              [Xml.XmlElement[]]$DeclineArchitectures,
                                              [Xml.XmlElement[]]$DeclineLanguages
                                          )
                                          
                                          $WsusServer = Get-WsusServer
                                          $UpdateScope = New-Object -TypeName Microsoft.UpdateServices.Administration.UpdateScope
                                          
                                          Write-Host -ForegroundColor Green '[*] Retrieving declined updates ...'
                                          $UpdateScope.ApprovedStates = [Microsoft.UpdateServices.Administration.ApprovedStates]::Declined
                                          $WsusDeclined = $WsusServer.GetUpdates($UpdateScope)
                                          
                                          # Ignore all updates corresponding to architectures, categories or languages we declined
                                          $IgnoredCatalogueCategories = $script:WscCatalogue | Where-Object { $_.Category -in $DeclineCategories }
                                          $IgnoredArchitecturesRegEx = ' ({0})' -f [String]::Join('|', $DeclineArchitectures.regex)
                                          $IgnoredLanguagesRegEx = ' [[]?({0})(_LP|_LIP)?[]]?' -f [String]::Join('|', $DeclineLanguages.code)
                                          
                                          Write-Host -ForegroundColor Green '[*] Finding suspect declined updates ...'
                                          $SuspectDeclines = @()
                                          foreach ($Update in $WsusDeclined) {
                                              # Ignore superseded and expired updates
                                              if ($Update.IsSuperseded -or $Update.PublicationState -eq 'Expired') {
                                                  continue
                                              }
                                          
                                              # Ignore cluster updates if they were declined
                                              if ($DeclineClusterUpdates -and $Update.Title -match $RegExClusterUpdates) {
                                                  continue
                                              }
                                          
                                              # Ignore farm updates if they were declined
                                              if ($DeclineFarmUpdates -and $Update.Title -match $RegExFarmUpdates) {
                                                  continue
                                              }
                                          
                                              # Ignore pre-release updates if they were declined
                                              if ($DeclinePrereleaseUpdates -and $Update.Title -match $RegExPrereleaseUpdates) {
                                                  continue
                                              }
                                          
                                              # Ignore Security Only Quality updates if they were declined
                                              if ($DeclineSecurityOnlyUpdates -and $Update.Title -match $RegExSecurityOnlyUpdates) {
                                                  continue
                                              }
                                          
                                              # Ignore any update categories which were declined
                                              if ($Update.Title -in $IgnoredCatalogueCategories.Title) {
                                                  continue
                                              }
                                          
                                              # Ignore any update architectures which were declined
                                              if ($Update.Title -match $IgnoredArchitecturesRegEx) {
                                                  continue
                                              }
                                          
                                              # Ignore any update languages which were declined
                                              if ($Update.Title -match $IgnoredLanguagesRegEx) {
                                                  continue
                                              }
                                          
                                              $SuspectDeclines += $Update
                                          }
                                          
                                          return $SuspectDeclines
                                          

                                          }

                                          Function Import-WsusSpringCleanMetadata {
                                          [CmdletBinding()]
                                          Param()

                                          Write-Verbose -Message '[*] Importing module metadata ...'
                                          $MetadataPath = Join-Path -Path $PSScriptRoot -ChildPath 'PSWsusSpringClean.xml'
                                          $script:WscMetadata = ([Xml](Get-Content -Path $MetadataPath)).PSWsusSpringClean
                                          

                                          }

                                          Function Invoke-WsusDeclineUpdatesByCatalogue {
                                          [CmdletBinding(SupportsShouldProcess)]
                                          Param(
                                          [Parameter(Mandatory)]
                                          [Microsoft.UpdateServices.Internal.BaseApi.Update[]]$Updates,

                                              [Parameter(Mandatory)]
                                              [ValidateNotNullOrEmpty()]
                                              [String]$Category
                                          )
                                          
                                          Write-Host -ForegroundColor Green ('[*] Declining updates in category: {0}' -f $Category)
                                          $UpdatesToDecline = $script:WscCatalogue | Where-Object { $_.Category -eq $Category }
                                          $MatchingUpdates = $Updates | Where-Object { $_.Title -in $UpdatesToDecline.Title }
                                          
                                          foreach ($Update in $MatchingUpdates) {
                                              if ($PSCmdlet.ShouldProcess($Update.Title, 'Decline')) {
                                                  Write-Host -ForegroundColor Cyan ('[-] Declining update: {0}' -f $Update.Title)
                                                  $Update.Decline()
                                              }
                                          }
                                          

                                          }

                                          Function Invoke-WsusDeclineUpdatesByRegEx {
                                          [CmdletBinding(SupportsShouldProcess)]
                                          Param(
                                          [Parameter(Mandatory)]
                                          [Microsoft.UpdateServices.Internal.BaseApi.Update[]]$Updates,

                                              [Parameter(Mandatory)]
                                              [ValidateNotNullOrEmpty()]
                                              [String]$RegEx
                                          )
                                          
                                          foreach ($Update in $Updates) {
                                              if ($Update.Title -match $RegEx) {
                                                  if ($PSCmdlet.ShouldProcess($Update.Title, 'Decline')) {
                                                      Write-Host -ForegroundColor Cyan ('[-] Declining update: {0}' -f $Update.Title)
                                                      $Update.Decline()
                                                  }
                                              }
                                          }
                                          

                                          }

                                          Function Invoke-WsusServerCleanupWrapper {
                                          [CmdletBinding(SupportsShouldProcess)]
                                          Param(
                                          [Switch]$CleanupObsoleteComputers,
                                          [Switch]$CleanupObsoleteUpdates,
                                          [Switch]$CleanupUnneededContentFiles,
                                          [Switch]$CompressUpdates,
                                          [Switch]$DeclineExpiredUpdates,
                                          [Switch]$DeclineSupersededUpdates
                                          )

                                          if ($CleanupObsoleteComputers) {
                                              Write-Host -ForegroundColor Green '[*] Deleting obsolete computers ...'
                                              Write-Host (Invoke-WsusServerCleanup -CleanupObsoleteComputers)
                                          }
                                          
                                          if ($CleanupObsoleteUpdates) {
                                              Write-Host -ForegroundColor Green '[*] Deleting obsolete updates ...'
                                              Write-Host (Invoke-WsusServerCleanup -CleanupObsoleteUpdates)
                                          }
                                          
                                          if ($CleanupUnneededContentFiles) {
                                              Write-Host -ForegroundColor Green '[*] Deleting unneeded update files ...'
                                              Write-Host (Invoke-WsusServerCleanup -CleanupUnneededContentFiles)
                                          }
                                          
                                          if ($CompressUpdates) {
                                              Write-Host -ForegroundColor Green '[*] Deleting obsolete update revisions ...'
                                              Write-Host (Invoke-WsusServerCleanup -CompressUpdates)
                                          }
                                          
                                          if ($DeclineExpiredUpdates) {
                                              Write-Host -ForegroundColor Green '[*] Declining expired updates ...'
                                              Write-Host (Invoke-WsusServerCleanup -DeclineExpiredUpdates)
                                          }
                                          
                                          if ($DeclineSupersededUpdates) {
                                              Write-Host -ForegroundColor Green '[*] Declining superseded updates ...'
                                              Write-Host (Invoke-WsusServerCleanup -DeclineSupersededUpdates)
                                          }
                                          

                                          }

                                          Function Invoke-WsusServerSynchronisation {
                                          [CmdletBinding(SupportsShouldProcess)]
                                          Param()

                                          $WsusServer = Get-WsusServer
                                          
                                          if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'WSUS synchronization')) {
                                              $SyncStatus = $WsusServer.GetSubscription().GetSynchronizationStatus()
                                              if ($SyncStatus -eq 'NotProcessing') {
                                                  $WsusServer.GetSubscription().StartSynchronization()
                                              } elseif ($SyncStatus -eq 'Running') {
                                                  Write-Warning -Message "[!] A synchronisation appears to already be running! We'll wait for this one to complete ..."
                                              } else {
                                                  throw ('WSUS server returned unknown synchronisation status: {0}' -f $SyncStatus)
                                              }
                                          
                                              do {
                                                  Start-Sleep -Seconds 5
                                              } while ($WsusServer.GetSubscription().GetSynchronizationStatus() -eq 'Running')
                                          
                                              $SyncResult = $WsusServer.GetSubscription().GetLastSynchronizationInfo().Result
                                              if ($SyncResult -ne 'Succeeded') {
                                                  throw ('WSUS server synchronisation completed with unexpected result: {0}' -f $SyncResult)
                                              }
                                          }
                                          

                                          }

                                          Function Invoke-WsusServerSpringClean {
                                          [CmdletBinding(SupportsShouldProcess)]
                                          Param(
                                          [Switch]$DeclineClusterUpdates,
                                          [Switch]$DeclineFarmUpdates,
                                          [Switch]$DeclinePrereleaseUpdates,
                                          [Switch]$DeclineSecurityOnlyUpdates,

                                              [String[]]$DeclineCategories,
                                              [Xml.XmlElement[]]$DeclineArchitectures,
                                              [Xml.XmlElement[]]$DeclineLanguages
                                          )
                                          
                                          $WsusServer = Get-WsusServer
                                          $UpdateScope = New-Object -TypeName Microsoft.UpdateServices.Administration.UpdateScope
                                          
                                          Write-Host -ForegroundColor Green '[*] Retrieving approved updates ...'
                                          $UpdateScope.ApprovedStates = [Microsoft.UpdateServices.Administration.ApprovedStates]::LatestRevisionApproved
                                          $WsusApproved = $WsusServer.GetUpdates($UpdateScope)
                                          
                                          Write-Host -ForegroundColor Green '[*] Retrieving unapproved updates ...'
                                          $UpdateScope.ApprovedStates = [Microsoft.UpdateServices.Administration.ApprovedStates]::NotApproved
                                          $WsusUnapproved = $WsusServer.GetUpdates($UpdateScope)
                                          
                                          $WsusAnyExceptDeclined = $WsusApproved + $WsusUnapproved
                                          
                                          if ($DeclineClusterUpdates) {
                                              Write-Host -ForegroundColor Green '[*] Declining cluster updates ...'
                                              Invoke-WsusDeclineUpdatesByRegEx -Updates $WsusAnyExceptDeclined -RegEx $script:RegExClusterUpdates
                                          }
                                          
                                          if ($DeclineFarmUpdates) {
                                              Write-Host -ForegroundColor Green '[*] Declining farm updates ...'
                                              Invoke-WsusDeclineUpdatesByRegEx -Updates $WsusAnyExceptDeclined -RegEx $script:RegExFarmUpdates
                                          }
                                          
                                          if ($DeclinePrereleaseUpdates) {
                                              Write-Host -ForegroundColor Green '[*] Declining pre-release updates ...'
                                              Invoke-WsusDeclineUpdatesByRegEx -Updates $WsusAnyExceptDeclined -RegEx $script:RegExPrereleaseUpdates
                                          }
                                          
                                          if ($DeclineSecurityOnlyUpdates) {
                                              Write-Host -ForegroundColor Green '[*] Declining Security Only updates ...'
                                              Invoke-WsusDeclineUpdatesByRegEx -Updates $WsusAnyExceptDeclined -RegEx $script:RegExSecurityOnlyUpdates
                                          }
                                          
                                          if ($PSBoundParameters.ContainsKey('DeclineCategories')) {
                                              foreach ($Category in $DeclineCategories) {
                                                  Invoke-WsusDeclineUpdatesByCatalogue -Updates $WsusAnyExceptDeclined -Category $Category
                                              }
                                          }
                                          
                                          if ($PSBoundParameters.ContainsKey('DeclineArchitectures')) {
                                              foreach ($Architecture in $DeclineArchitectures) {
                                                  Write-Host -ForegroundColor Green ('[*] Declining updates with architecture: {0}' -f $Architecture.name)
                                                  $ArchitectureRegEx = ' ({0})' -f $Architecture.regex
                                                  Invoke-WsusDeclineUpdatesByRegEx -Updates $WsusAnyExceptDeclined -RegEx $ArchitectureRegEx
                                              }
                                          }
                                          
                                          if ($PSBoundParameters.ContainsKey('DeclineLanguages')) {
                                              foreach ($Language in $DeclineLanguages) {
                                                  Write-Host -ForegroundColor Green ('[*] Declining updates with language: {0}' -f $Language.code)
                                                  $LanguageRegEx = ' [[]?{0}(_LP|_LIP)?[]]?' -f $Language.code
                                                  Invoke-WsusDeclineUpdatesByRegEx -Updates $WsusAnyExceptDeclined -RegEx $LanguageRegEx
                                              }
                                          }
                                          

                                          }

                                          Function Test-WsusSpringCleanArchitectures {
                                          Param(
                                          [Parameter(Mandatory)]
                                          [String[]]$Architectures
                                          )

                                          if (!$script:WscMetadata) {
                                              Import-WsusSpringCleanMetadata
                                          }
                                          
                                          $KnownArchitectures = $script:WscMetadata.Architectures.Architecture.name
                                          foreach ($Architecture in $Architectures) {
                                              if ($Architecture -notin $KnownArchitectures) {
                                                  throw 'Unknown architecture specified: {0}' -f $Architecture
                                              }
                                          }
                                          
                                          return $true
                                          

                                          }

                                          Function Test-WsusSpringCleanLanguageCodes {
                                          Param(
                                          [Parameter(Mandatory)]
                                          [String[]]$LanguageCodes
                                          )

                                          if (!$script:WscMetadata) {
                                              Import-WsusSpringCleanMetadata
                                          }
                                          
                                          $KnownLanguageCodes = $script:WscMetadata.Languages.Language.code
                                          foreach ($LanguageCode in $LanguageCodes) {
                                              if ($LanguageCode -notin $KnownLanguageCodes) {
                                                  throw 'Unknown language code specified: {0}' -f $LanguageCode
                                              }
                                          }
                                          
                                          return $true
                                          

                                          }

                                          Function ConvertTo-WsusSpringCleanCatalogue {
                                          Param(
                                          [Parameter(Mandatory,ValueFromPipeline)]
                                          [Microsoft.UpdateServices.Internal.BaseApi.Update[]]$Updates
                                          )

                                          Process {
                                              foreach ($Update in $Updates) {
                                                  [String[]]$ProductTitles = @()
                                                  foreach ($ProductTitle in $Update.ProductTitles) {
                                                      $ProductTitles += $ProductTitle
                                                  }
                                          
                                                  [PSCustomObject]@{
                                                      'Category'      = 'Unknown'
                                                      'Title'         = $Update.Title
                                                      'ProductTitles' = [String]::Join(', ', $ProductTitles)
                                                  }
                                              }
                                          }
                                          

                                          }

                                          Function Import-WsusSpringCleanCatalogue {
                                          [CmdletBinding()]
                                          Param(
                                          [ValidateNotNullOrEmpty()]
                                          [String]$CataloguePath
                                          )

                                          if (!$CataloguePath) {
                                              $CataloguePath = Join-Path -Path $PSScriptRoot -ChildPath 'PSWsusSpringClean.csv'
                                          }
                                          
                                          Write-Verbose -Message '[*] Importing update catalogue ...'
                                          $script:WscCatalogue = Import-Csv -Path $CataloguePath
                                          

                                          }

                                          Function Test-WsusSpringCleanCatalogue {
                                          [CmdletBinding()]
                                          Param(
                                          [ValidateNotNullOrEmpty()]
                                          [String]$CataloguePath
                                          )

                                          Import-WsusSpringCleanCatalogue @PSBoundParameters
                                          
                                          Write-Host -ForegroundColor Green '[*] Retrieving all updates ...'
                                          $WsusServer = Get-WsusServer
                                          $WsusUpdateScope = New-Object -TypeName Microsoft.UpdateServices.Administration.UpdateScope
                                          $WsusUpdateScope.ApprovedStates = [Microsoft.UpdateServices.Administration.ApprovedStates]::Any
                                          $WsusUpdates = $WsusServer.GetUpdates($WsusUpdateScope)
                                          
                                          Write-Host -ForegroundColor Green '[*] Scanning for updates only present in catalogue ...'
                                          $CatalogueOnly = @()
                                          foreach ($Update in $script:WscCatalogue) {
                                              if ($Update.Title -notin $WsusUpdates.Title) {
                                                  $CatalogueOnly += $Update
                                              }
                                          }
                                          
                                          return $CatalogueOnly
                                          

                                          }

                                          Looks like it pasted in stupidly, sorry.

                                          black3dynamiteB ObsolesceO 2 Replies Last reply Reply Quote 0
                                          • black3dynamiteB
                                            black3dynamite @siringo
                                            last edited by

                                            @siringo That was definitely difficult to followed from my iPhone.

                                            S 1 Reply Last reply Reply Quote 0
                                            • 1
                                            • 2
                                            • 3
                                            • 4
                                            • 1 / 4
                                            • First post
                                              Last post