# encoding: utf-8 # api: powershell # title: WSUS Admin Module # description: This module allows you to manage WSUS from PowerShell. Save code as a .psm1 file and use the Import-Module command for this module. You can approve/decline updates, perform synchronizations, add/remove clients from a target group, create/delete Target groups and much more with currently 40 advanced functions. For more information about this module, please see my blog http://boeprox.wordpress.com/ # version: 1.0 # type: module # author: Boe Prox # license: CC0 # function: Get-WSUSCommands # x-poshcode-id: 2363 # x-archived: 2010-11-24T12:17:58 # # Write-Host "`n" Write-Host "`t`tWSUS Administrator Module 1.0" Write-Host "`n" Write-Host -nonewline "Make initial connection to WSUS Server:`t" Write-Host -fore Yellow "Connect-WSUSServer" Write-Host -nonewline "Disconnect from WSUS Server:`t`t" Write-Host -fore Yellow "Disconnect-WSUSServer" Write-Host -nonewline "List all available commands:`t`t" Write-Host -fore Yellow "Get-WSUSCommands" Write-Host "`n" function Get-WSUSCommands { <# .SYNOPSIS Lists all WSUS functions available from this module. .DESCRIPTION Lists all WSUS functions available from this module. .NOTES Name: Get-WSUSCommand Author: Boe Prox DateCreated: 18Oct2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSCommands Description ----------- This command lists all of the available WSUS commands in the module. #> [cmdletbinding()] Param () #List all WSUS functions available Get-Command *WSUS* -CommandType Function | Sort-Object Name } function Connect-WSUSServer { <# .SYNOPSIS Retrieves the last check-in times of clients on WSUS. .DESCRIPTION Retrieves the last check-in times of clients on WSUS. You will need to run this on a machine that has the WSUS Administrator console installed. .PARAMETER WsusServer Name of WSUS server to query against. .PARAMETER Secure Determines if a secure connection will be used to connect to the WSUS server. If not used, then a non-secure connection will be used. .NOTES Name: Get-LastCheckIn Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Connect-WSUSServer -wsusserver "server1" Description ----------- This command will make the connection to the WSUS using an unsecure port (Default:80). .EXAMPLE Connect-WSUSServer -wsusserver "server1" -secure Description ----------- This command will make a secure connection (Default: 443) to a WSUS server. #> [cmdletbinding( DefaultParameterSetName = 'wsus', ConfirmImpact = 'low' )] Param( [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'wsus', ValueFromPipeline = $True)] [string]$WsusServer, [Parameter( Mandatory = $False, Position = 1, ParameterSetName = 'wsus', ValueFromPipeline = $False)] [switch]$Secure ) #Load required assemblies [void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") #Make connection to WSUS server Write-Host -ForegroundColor Yellow "Attempting connection to WSUS Server: $($wsusserver)" $ErrorActionPreference = 'stop' Try { If ($secure) { $Global:wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusserver,$True) $Wsus | FT Name, Version,PortNumber } Else { $Global:wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusserver,$False) $Wsus | FT Name, Version,PortNumber } } Catch { Write-Error "Unable to connect to $($wsusserver)!`n$($error[0])" } } function Disconnect-WSUSServer { <# .SYNOPSIS Disconnects session against WSUS server. .DESCRIPTION Disconnects session against WSUS server. .NOTES Name: Disconnect-WSUSServer Author: Boe Prox DateCreated: 27Oct2010 .LINK https://boeprox.wordpress.org .EXAMPLE Disconnect-WSUSServer Description ----------- This command will disconnect the session to the WSUS server. #> [cmdletbinding()] Param () #Disconnect WSUS session by removing the variable Remove-Variable -Name wsus -Force } function Get-WSUSClients { <# .SYNOPSIS Retrieves a list of all of the clients in WSUS. .DESCRIPTION Retrieves a list of all of the clients in WSUS. .NOTES Name: Get-WSUSClients Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSClients Description ----------- This command will list every client in WSUS. #> [cmdletbinding()] Param () #Gather all computers in WSUS $wsus.GetComputerTargets() } function Start-WSUSSync { <# .SYNOPSIS Start synchronization on WSUS server. .DESCRIPTION Start synchronization on WSUS server. .PARAMETER Monitor Starts a synchronization and runs a background job to monitor currently running content download and notifies user when completed. .NOTES Name: Start-WSUSSync Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Start-WSUSSync Description ----------- This command will begin a manual sychronization on WSUS with the defined update source. .EXAMPLE Start-WSUSSync -monitor Description ----------- This command will begin a manual synchronization on WSUS and will begin a background job that will notifiy via pop-up message when the synchronization has completed. #> [cmdletbinding( DefaultParameterSetName = 'monitor', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param ( [Parameter( Mandatory = $False, Position = 0, ParameterSetName = 'monitor', ValueFromPipeline = $False)] [switch]$Monitor ) $sub = $wsus.GetSubscription() $sync = $sub.GetSynchronizationProgress() If ($monitor) { #Stop and remove any jobs for SyncMonitoring $jobs = Get-Job | ? {$_.Name -eq "WSUSSyncProgressMonitor"} If ($jobs) { $jobs | Stop-Job $jobs | Remove-Job } #Start WSUS synchronization If ($pscmdlet.ShouldProcess($($wsus.name))) { $sub.StartSynchronization() "Synchronization have been started." Start-Sleep -Seconds 3 Start-Job -Name "WSUSSyncProgressMonitor" -ArgumentList $sync -ScriptBlock { Param ( $sync ) #Load required assemblies for message window [void] [System.Reflection.Assembly]::LoadWithPartialName(�System.Windows.Forms�) While ($sync.Phase -ne "NotProcessing") { $null } [System.Windows.Forms.MessageBox]::Show("Synchronization has been completed on WSUS",�Information�) } | Out-Null } } Else { #Start WSUS synchronization If ($pscmdlet.ShouldProcess($($wsus.name))) { $sub.StartSynchronization() "Synchronization have been started." } } } function Stop-WSUSSync { <# .SYNOPSIS Stops a currently running WSUS sync. .DESCRIPTION Stops a currently running WSUS sync. .NOTES Name: Stop-WSUSSync Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Stop-WSUSSync Description ----------- This command will stop a currently running WSUS synchronization. #> [cmdletbinding( DefaultParameterSetName = 'update', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param() $sub = $wsus.GetSubscription() #Cancel synchronization running on WSUS If ($pscmdlet.ShouldProcess($($wsus.name))) { $sub.StopSynchronization() "Synchronization have been cancelled." } } function Get-WSUSSyncHistory { <# .SYNOPSIS Retrieves the synchronization history of the WSUS server. .DESCRIPTION Retrieves the synchronization history of the WSUS server. .NOTES Name: Get-WSUSSyncHistory Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSSyncHistory Description ----------- This command will list out the entire synchronization history of the WSUS server. #> [cmdletbinding()] Param () $sub = $wsus.GetSubscription() $sub.GetSynchronizationHistory() } function Get-WSUSSyncProgress { <# .SYNOPSIS Displays the current progress of a WSUS synchronization. .DESCRIPTION Displays the current progress of a WSUS synchronization. .PARAMETER Monitor Runs a background job to monitor currently running synchonization and notifies user when completed. .NOTES Name: Get-WSUSSyncProgress Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSSyncProgress Description ----------- This command will show you the current status of the WSUS sync. .EXAMPLE Get-WSUSSyncProgress -monitor Description ----------- This command will begin a background job that will notify you when the WSUS synchronization has been completed. #> [cmdletbinding()] Param ( [Parameter( Mandatory = $False, Position = 0, ParameterSetName = 'monitor', ValueFromPipeline = $False)] [switch]$Monitor ) $sub = $wsus.GetSubscription() If ($monitor) { $job = Get-Job If ($job) { $job = Get-Job -Name "WSUSSyncProgressMonitor" } If ($job) { Get-Job -Name "WSUSSyncProgressMonitor" | Stop-Job Get-Job -Name "WSUSSyncProgressMonitor" | Remove-Job } Start-Job -Name "WSUSSyncProgressMonitor" -ArgumentList $sub -ScriptBlock { Param ( $sub ) #Load required assemblies for message window [void] [System.Reflection.Assembly]::LoadWithPartialName(�System.Windows.Forms�) While (($sub.GetSynchronizationProgress()).Phase -ne "NotProcessing") { $null } [System.Windows.Forms.MessageBox]::Show("Synchronization has been completed on WSUS",�Information�) } | Out-Null } Else { #Gather all child servers in WSUS $sub.GetSynchronizationProgress() } } function Get-WSUSEvents { <# .SYNOPSIS Retrieves all WSUS events. .DESCRIPTION Retrieves all WSUS events from the WSUS server. .NOTES Name: Get-WSUSEvents Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSEvents Description ----------- This command will show you all of the WSUS events. #> [cmdletbinding()] Param () $sub = $wsus.GetSubscription() $sub.GetEventHistory() } function Get-WSUSGroups { <# .SYNOPSIS Retrieves all of the WSUS Target Groups. .DESCRIPTION Retrieves all of the WSUS Target Groups. .NOTES Name: Get-WSUSGroups Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSGroups Description ----------- This command will list out all of the WSUS Target groups and their respective IDs. #> [cmdletbinding()] Param () $wsus.GetComputerTargetGroups() } function Get-WSUSServer { <# .SYNOPSIS Retrieves connection and configuration information from the WSUS server. .DESCRIPTION Retrieves connection and configuration information from the WSUS server. .PARAMETER Configuration Lists more configuration information from WSUS Server .NOTES Name: Get-WSUSServer Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSServer Description ----------- This command will display basic information regarding the WSUS server. .EXAMPLE Get-WSUSServer -configuration Description ----------- This command will list out more detailed information regarding the configuration of the WSUS server. #> [cmdletbinding( DefaultParameterSetName = 'wsus', ConfirmImpact = 'low' )] Param( [Parameter( Mandatory = $False, Position = 0, ParameterSetName = 'wsus', ValueFromPipeline = $False)] [switch]$Configuration ) If ($configuration) { $wsus.GetConfiguration() } Else { $wsus } } function Get-WSUSUpdates { <# .SYNOPSIS Retrieves all of the updates from a WSUS server. .DESCRIPTION Retrieves all of the updates from a WSUS server. .NOTES Name: Get-WSUSUpdates Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSUpdates Description ----------- This command will list out every update that is in WSUS's database whether it has been approved or not. #> [cmdletbinding()] Param () $wsus.GetUpdates() } function Get-WSUSEmailConfig { <# .SYNOPSIS Retrieves the email notification configuration from WSUS. .DESCRIPTION Retrieves the email notification configuration from WSUS. .PARAMETER SendTestEmail Optional switch that will send a test email to the configured email addresses .NOTES Name: Get-WSUSEmailConfig Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSEmailConfig Description ----------- This command will display the configuration of the email notifications. .EXAMPLE Get-WSUSEmailConfig -SendTestEmail Description ----------- This command will send a test email to the address or addresses in the To field. #> [cmdletbinding( DefaultParameterSetName = 'wsus', ConfirmImpact = 'low' )] Param( [Parameter( Mandatory = $False, Position = 0, ParameterSetName = 'wsus', ValueFromPipeline = $False)] [switch]$SendTestEmail ) $email = $wsus.GetEmailNotificationConfiguration() If ($SendTestEmail) { $email.SendTestEmail() Write-Host -fore Green "Test email sent." } Else { $email } } function Get-WSUSUpdateCategories { <# .SYNOPSIS Retrieves the list of Update categories available from WSUS. .DESCRIPTION Retrieves the list of Update categories available from WSUS. .NOTES Name: Get-WSUSUpdateCategories Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSUpdateCategories Description ----------- This command will list all of the categories for updates in WSUS. #> [cmdletbinding()] Param () $wsus.GetUpdateCategories() } function Get-WSUSStatus { <# .SYNOPSIS Retrieves a list of all updates and their statuses along with computer statuses. .DESCRIPTION Retrieves a list of all updates and their statuses along with computer statuses. .NOTES Name: Get-WSUSStatus Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSStatus Description ----------- This command will display the status of the WSUS server along with update statuses. #> [cmdletbinding()] Param () $wsus.getstatus() } function Set-WSUSEmailConfig { <# .SYNOPSIS Configures the email notifications on a WSUS server. .DESCRIPTION Configures the email notifications on a WSUS server. It is important to note that the email address to send the emails to is Read-Only and can only be configured from the WSUS Admin Console. After the settings have been changed, the new configuration will be displayed. .PARAMETER EmailLanguage What type of language to send the email in. .PARAMETER SenderDisplayName The friendly name of where the email is coming from. .PARAMETER SenderEmailAddress The senders email address .PARAMETER SendStatusNotification Determines if an email will be sent for a status notification .PARAMETER SendSyncnotification Determines if an email will be sent after a sync by WSUS .PARAMETER SMTPHostname Server name of the smtp server to send email from .PARAMETER SMTPPort Port number to be used to connect to smtp server to send email .PARAMETER SmtpServerRequiresAuthentication Used if smtp server requires authentication .PARAMETER SmtpUserName Username to submit if required by smtp server .PARAMETER StatusNotificationFrequency Frequency (Daily or Weekly) to send notifications .PARAMETER StatusNotificationTimeOfDay Date/Time to send notifications .PARAMETER UpdateServer Name of the WSUS update server .PARAMETER SmtpPassword Password to user for smtp server connection. .NOTES Name: Set-WSUSEmailConfig Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Set-WSUSEmailConfig -SenderDisplayName "WSUSAdmin" -SenderEmailAddress "wsusadmin@domain.com" Description ----------- This command will change the sender name and email address for email notifications and then display the new settings. #> [cmdletbinding( DefaultParameterSetName = 'wsus', ConfirmImpact = 'low' )] Param( [Parameter( Mandatory = $False, Position = 0, ParameterSetName = '', ValueFromPipeline = $False)] [string]$EmailLanguage, [Parameter( Mandatory = $False, Position = 1, ParameterSetName = '', ValueFromPipeline = $False)] [string]$SenderDisplayName, [Parameter( Mandatory = $False, Position = 2, ParameterSetName = '', ValueFromPipeline = $False)] [string]$SenderEmailAddress, [Parameter( Mandatory = $False, Position = 3, ParameterSetName = '', ValueFromPipeline = $False)] [string][ValidateSet("True","False")]$SendStatusNotification, [Parameter( Mandatory = $False, Position = 4, ParameterSetName = '',ValueFromPipeline = $False)] [string][ValidateSet("True","False")]$SendSyncnotification, [Parameter( Mandatory = $False, Position = 5, ParameterSetName = '', ValueFromPipeline = $False)] [string]$SMTPHostname, [Parameter( Mandatory = $False, Position = 6, ParameterSetName = '', ValueFromPipeline = $False)] [int]$SMTPPort, [Parameter( Mandatory = $False, Position = 7, ParameterSetName = '', ValueFromPipeline = $False)] [string][ValidateSet("True","False")]$SmtpServerRequiresAuthentication, [Parameter( Mandatory = $False, Position = 8, ParameterSetName = 'account', ValueFromPipeline = $False)] [string]$SmtpUserName, [Parameter( Mandatory = $False, Position = 9, ParameterSetName = '', ValueFromPipeline = $False)] [string][ValidateSet("Daily","Weekly")]$StatusNotificationFrequency, [Parameter( Mandatory = $False, Position = 10, ParameterSetName = '', ValueFromPipeline = $False)] [string]$StatusNotificationTimeOfDay, [Parameter( Mandatory = $False,Position = 11, ParameterSetName = '',ValueFromPipeline = $False)] [string]$UpdateServer, [Parameter( Mandatory = $False,Position = 12, ParameterSetName = 'account',ValueFromPipeline = $False)] [string]$SmtpPassword ) #Configure Email Notifications $email = $wsus.GetEmailNotificationConfiguration() $ErrorActionPreference = 'stop' Try { If ($StatusNotificationTimeOfDay) { #Validate Notification Time of Day Parameter If (!([regex]::ismatch($StatusNotificationTimeOfDay,"^\d{2}:\d{2}$"))) { Write-Error "$($StatusNotificationTimeOfDay) is not a valid time to use!`nMust be 'NN:NN'" } Else { $email.StatusNotificationTimeOfDay = $StatusNotificationTimeOfDay } } If ($UpdateServer) {$email.UpdateServer = $UpdateServer} If ($EmailLanguage) {$email.EmailLanguage = $EmailLanguage} If ($SenderDisplayName) {$email.SenderDisplayName = $SenderDisplayName} If ($SenderEmailAddress) { #Validate Email Address Parameter If (!([regex]::ismatch($SenderEmailAddress,"^\w+@\w+\.com|mil|org|net$"))) { Write-Error "$($SenderEmailAddress) is not a valid email address!`nMust be 'xxxx@xxxxx.xxx'" } Else { $email.SenderEmailAddress = $SenderEmailAddress } } If ($SMTPHostname) {$email.SMTPHostname = $SMTPHostname} If ($SMTPPort) {$email.SMTPPort = $SMTPPort} If ($SmtpServerRequiresAuthentication) {$email.SmtpServerRequiresAuthentication = $SmtpServerRequiresAuthentication} If ($SmtpUserName) {$email.SmtpUserName = $SmtpUserName} If ($SmtpPassword) {$mail.SetSmtpUserPassword($SmtpPassword)} Switch ($StatusNotificationFrequency) { "Daily" {$email.StatusNotificationFrequency = [Microsoft.UpdateServices.Administration.EmailStatusNotificationFrequency]::Daily} "Weekly" {$email.StatusNotificationFrequency = [Microsoft.UpdateServices.Administration.EmailStatusNotificationFrequency]::Weekly} Default {$Null} } Switch ($SendStatusNotification) { "True" {$email.SendStatusNotification = 1} "False" {$email.SendStatusNotification = 0} Default {$Null} } Switch ($SendSyncNotification) { "True" {$email.SendSyncNotification = 1} "False" {$email.SendSyncNotification = 0} Default {$Null} } } Catch { Write-Error "$($error[0])" } #Save Configuration Changes Try { $email.Save() Write-Host -fore Green "Email settings changed" $email } Catch { Write-Error "$($error[0])" } } function Convert-WSUSTargetGroup { <# .SYNOPSIS Converts the WSUS group from ID to Name or Name to ID. .DESCRIPTION Converts the WSUS group from ID to Name or Name to ID. .PARAMETER Id GUID of the group to be converted to friendly name .PARAMETER Name Name of the group to be converted to a guid .NOTES Name: Convert-WSUSTargetGroup Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Convert-WSUSTargetGroup -name "Domain Servers" Description ----------- This command will convert the group name "Domain Servers" into the GUID format. .EXAMPLE Convert-WSUSTargetGroup -ID "b73ca6ed-5727-47f3-84de-015e03f6a88a" Description ----------- This command will convert the given GUID into a friendly name. #> [cmdletbinding( DefaultParameterSetName = 'name', ConfirmImpact = 'low' )] Param( [Parameter( Mandatory = $False, Position = 2, ParameterSetName = 'id', ValueFromPipeline = $False)] [string]$Id, [Parameter( Mandatory = $False, Position = 3, ParameterSetName = 'name', ValueFromPipeline = $False)] [string]$Name ) If ($name) { Try { $group = $wsus.GetComputerTargetGroups() | ? {$_.Name -eq $name} $group | Select -ExpandProperty ID } Catch { Write-Error "Unable to locate $($name)." } } If ($id) { Try { $group = $wsus.GetComputerTargetGroups() | ? {$_.ID -eq $id} $group | Select -ExpandProperty Name } Catch { Write-Error "Unable to locate $($id)." } } } function Get-WSUSClientsInGroup { <# .SYNOPSIS Retrieves a list of clients that are members of a group. .DESCRIPTION Retrieves a list of clients that are members of a group. .PARAMETER Id Retrieves list of clients in group by group guid. .PARAMETER Name Retrieves list of clients in group by group name. .NOTES Name: Get-WSUSClientsInGroup Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSClientsInGroup -name "Domain Servers" Description ----------- This command will list all clients that are members of the specified group via group name. .EXAMPLE Get-WSUSClientsInGroup -ID "b73ca6ed-5727-47f3-84de-015e03f6a88a" Description ----------- This command will list all clients that are members of the specified group via the group guid. #> [cmdletbinding( DefaultParameterSetName = 'name', ConfirmImpact = 'low' )] Param( [Parameter( Mandatory = $False, Position = 2, ParameterSetName = 'name', ValueFromPipeline = $False)] [string]$Name, [Parameter( Mandatory = $False, Position = 3, ParameterSetName = 'id', ValueFromPipeline = $False)] [string]$Id ) If ($id) { ($wsus.GetComputerTargetGroups() | ? {$_.Id -eq $id}).GetComputerTargets() } If ($name) { ($wsus.GetComputerTargetGroups() | ? {$_.name -eq $name}).GetComputerTargets() } } function Get-WSUSClient { <# .SYNOPSIS Retrieves information about a WSUS client. .DESCRIPTION Retrieves information about a WSUS client. .PARAMETER Computer Name of the client to search for. Accepts a partial name. .NOTES Name: Get-WSUSClient Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSClient -computer "server1" Description ----------- This command will search for and display all computers matching the given input. #> [cmdletbinding( DefaultParameterSetName = 'wsus', ConfirmImpact = 'low' )] Param( [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'wsus', ValueFromPipeline = $True)] [string]$Computer ) $ErrorActionPreference = 'stop' #Retrieve computer in WSUS Try { $wsus.SearchComputerTargets($computer) } Catch { Write-Error "Unable to retrieve $($computer) from database." } } function New-WSUSGroup { <# .SYNOPSIS Creates a new WSUS Target group. .DESCRIPTION Creates a new WSUS Target group. .PARAMETER Group Name of group being created. .PARAMETER ParentGroupName Name of group being created. .PARAMETER ParentGroupId Name of group being created. .NOTES Name: New-WSUSGroup Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE New-WSUSGroup -name "TestGroup" Description ----------- This command will create a new Target group called 'TestGroup' .EXAMPLE New-WSUSGroup -name "TestGroup" -parentgroupname "Domain Servers" Description ----------- This command will create a new Target group called 'TestGroup' under the parent group 'Domain Servers' #> [cmdletbinding( DefaultParameterSetName = 'group', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param( [Parameter( Mandatory = $True, Position = 0, ParameterSetName = '', ValueFromPipeline = $True)] [string]$Group, [Parameter( Mandatory = $False, Position = 1, ParameterSetName = 'parentgroup', ValueFromPipeline = $True)] [string]$ParentGroupName, [Parameter( Mandatory = $False, Position = 2, ParameterSetName = 'parentgroup', ValueFromPipeline = $True)] [string]$ParentGroupId ) Process { #Determine action based on Parameter Set Name Switch ($pscmdlet.ParameterSetName) { "group" { Write-Verbose "Creating computer group" If ($pscmdlet.ShouldProcess($group)) { #Create the computer target group $wsus.CreateComputerTargetGroup($group) "$($group) has been created." } } "parentgroup" { If ($parentgroupname) { #Retrieve group based off of name Write-Verbose "Querying for parent group" $parentgroup = Get-WSUSGroups | ? {$_.name -eq $parentgroupname} If (!$parentgroup) { Write-Error "Parent Group name `'$parentgroupname`' does not exist in WSUS!" Break } } If ($parentgroupid) { #Retrieve group based off of guid Write-Verbose "Querying for parent group" $parentgroup = Get-WSUSGroups | ? {$_.id -eq $parentgroupid} If (!$parentgroup) { Write-Error "Parent Group id `'$parentgroupid`' does not exist in WSUS!" Break } } Write-Verbose "Creating computer group" If ($pscmdlet.ShouldProcess($group)) { #Create the computer target group $wsus.CreateComputerTargetGroup($group,$parentgroup) "$($group) has been created under $($parentgroup.Name)." } } } } } function Get-WSUSUpdate { <# .SYNOPSIS Retrieves information from a wsus update. .DESCRIPTION Retrieves information from a wsus update. Depending on how the information is presented in the search, more than one update may be returned. .PARAMETER Update String to search for. This can be any string for the update to include KB article numbers, name of update, category, etc... Use of wildcards (*,%) not allowed in search! .NOTES Name: Get-WSUSUpdate Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSUpdate -update "Exchange" Description ----------- This command will list every update that has 'Exchange' in it. .EXAMPLE Get-WSUSUpdate -update "925474" Description ----------- This command will list every update that has '925474' in it. #> [cmdletbinding( DefaultParameterSetName = 'wsus', ConfirmImpact = 'low' )] Param( [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'wsus', ValueFromPipeline = $True)] [string]$Update ) $ErrorActionPreference = 'stop' #Retrieve computer in WSUS Try { $wsus.SearchUpdates($update) } Catch { Write-Error "Unable to retrieve $($update) from database." } } function Remove-WSUSGroup { <# .SYNOPSIS Creates a new WSUS Target group. .DESCRIPTION Creates a new WSUS Target group. .PARAMETER Name Name of group being deleted. .PARAMETER Id Id of group being deleted. .NOTES Name: Remove-WSUSGroup Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Remove-WSUSGroup -name "Domain Servers" Description ----------- This command will remove the Domain Servers WSUS Target group. .EXAMPLE Remove-WSUSGroup -id "fc93e74e-ba59-4593-9ff7-690af1be695f" Description ----------- This command will remove the Target group with ID 'fc93e74e-ba59-4593-9ff7-690af1be695f' from WSUS. #> [cmdletbinding( DefaultParameterSetName = 'name', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param( [Parameter( Mandatory = $False, Position = 0, ParameterSetName = 'name', ValueFromPipeline = $True)] [string]$Name, [Parameter( Mandatory = $False, Position = 1, ParameterSetName = 'id', ValueFromPipeline = $True)] [string]$Id ) Process { #Determine action based on Parameter Set Name Switch ($pscmdlet.ParameterSetName) { "name" { Write-Verbose "Querying for computer group" $group = Get-WSUSGroup -name $name If (!$group) { Write-Error "Group $name does not exist in WSUS!" Break } Else { If ($pscmdlet.ShouldProcess($name)) { #Create the computer target group $group.Delete() "$($name) has been deleted from WSUS." } } } "id" { Write-Verbose "Querying for computer group" $group = Get-WSUSGroup -id $id If (!$group) { Write-Error "Group $id does not exist in WSUS!" Break } If ($pscmdlet.ShouldProcess($id)) { #Create the computer target group $group.Delete() "$($id) has been deleted from WSUS." } } } } } function Add-WSUSClientToGroup { <# .SYNOPSIS Adds a computer client to an existing WSUS group. .DESCRIPTION Adds a computer client to an existing WSUS group. .PARAMETER Group Name of group to add client to. .PARAMETER Computer Name of computer being added to group. .NOTES Name: Add-WSUSClientToGroup Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Add-WSUSClientToGroup -group "Domain Servers" -computer "server1" Description ----------- This command will add the client "server1" to the WSUS target group "Domain Servers". #> [cmdletbinding( DefaultParameterSetName = 'group', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param( [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'group', ValueFromPipeline = $True)] [string]$Group, [Parameter( Mandatory = $False, Position = 1, ParameterSetName = 'group', ValueFromPipeline = $True)] [string]$Computer ) #Verify Computer is in WSUS Write-Verbose "Validating client in WSUS" $client = Get-WSUSClient -computer $computer If ($client) { #Get group object Write-Verbose "Retrieving group" $targetgroup = Get-WSUSGroup -name $group If (!$targetgroup) { Write-Error "Group $group does not exist in WSUS!" Break } #Add client to group Write-Verbose "Adding client to group" If ($pscmdlet.ShouldProcess($($client.fulldomainname))) { $targetgroup.AddComputerTarget($client) "$($client.FullDomainName) has been added to $($group)" } } Else { Write-Error "Computer: $computer is not in WSUS!" } } function Remove-WSUSClientFromGroup { <# .SYNOPSIS Removes a computer client to an existing WSUS group. .DESCRIPTION Removes a computer client to an existing WSUS group. .PARAMETER Group Name of group to remove client from. .PARAMETER Computer Name of computer being removed from group. .NOTES Name: Remove-WSUSClientToGroup Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Remove-WSUSClientFromGroup -group "Domain Servers" -computer "server1" Description ----------- This command will remove the client "server1" from the WSUS target group "Domain Servers". #> [cmdletbinding( DefaultParameterSetName = 'group', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param( [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'group', ValueFromPipeline = $True)] [string]$Group, [Parameter( Mandatory = $False, Position = 1, ParameterSetName = 'group', ValueFromPipeline = $True)] [string]$Computer ) #Verify Computer is in WSUS $client = Get-WSUSClient -computer $computer If ($client) { #Get group object Write-Verbose "Retrieving group" $targetgroup = Get-WSUSGroup -name $group If (!$targetgroup) { Write-Error "Group $group does not exist in WSUS!" Break } #Remove client from group Write-Verbose "Removing client to group" If ($pscmdlet.ShouldProcess($($client.fulldomainname))) { $targetgroup.RemoveComputerTarget($client) "$($client.fulldomainname) has been removed from $($group)" } } Else { Write-Error "Computer: $computer is not in WSUS!" } } function Get-WSUSDatabaseConfig { <# .SYNOPSIS Displays the current WSUS database configuration. .DESCRIPTION Displays the current WSUS database configuration. .NOTES Name: Get-WSUSDatabaseConfig Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSDatabaseConfig Description ----------- This command will display the configuration information for the WSUS connection to a database. #> [cmdletbinding()] Param () $wsus.GetDatabaseConfiguration() } function Get-WSUSSubscription { <# .SYNOPSIS Displays WSUS subscription information. .DESCRIPTION Displays WSUS subscription information. You can view the next synchronization time, who last modified the schedule, etc... .NOTES Name: Get-WSUSSubscription Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSSubscription Description ----------- This command will list out the various subscription information on the WSUS server. #> [cmdletbinding()] Param () $wsus.GetSubscription() } function Deny-WSUSUpdate { <# .SYNOPSIS Declines an update on WSUS. .DESCRIPTION Declines an update on WSUS. Use of the -whatif is advised to be sure you are declining the right patch or patches. .PARAMETER InputObject Collection of update/s being declined. This must be an object, otherwise it will fail. .PARAMETER Update Name of update/s being declined. .NOTES Name: Deny-WSUSUpdate Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSUpdate -update "Exchange 2010" | Deny-WSUSUpdate Description ----------- This command will decline all updates with 'Exchange 2010' in its metadata. .EXAMPLE Deny-WSUSUpdate -Update "Exchange 2010" Description ----------- This command will decline all updates with 'Exchange 2010' in its metadata. .EXAMPLE $updates = Get-WSUSUpdate -update "Exchange 2010" Deny-WSUSUpdate -InputObject $updates Description ----------- This command will decline all updates with 'Exchange 2010' in its metadata. .EXAMPLE Get-WSUSUpdate -update "Exchange 2010" | Deny-WSUSUpdate Description ----------- This command will decline all updates with 'Exchange 2010' in its metadata via the pipeline. #> [cmdletbinding( DefaultParameterSetName = 'collection', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param( [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'collection', ValueFromPipeline = $True)] [system.object]$InputObject, [Parameter( Mandatory = $False, Position = 1, ParameterSetName = 'string', ValueFromPipeline = $False)] [string]$Update ) Process { Switch ($pscmdlet.ParameterSetName) { "Collection" { Write-Verbose "Using 'Collection' set name" #Change the collection to patches for use in loop $patches = $inputobject } "String" { Write-Verbose "Using 'String' set name" #Gather all updates from given information Write-Verbose "Searching for updates" $patches = Get-WSUSUpdate -update $update } } ForEach ($patch in $patches) { #Decline the update Write-Verbose "Declining update" If ($pscmdlet.ShouldProcess($($patch.title))) { $patch.Decline($True) | out-null #Print out report of what was declined New-Object PSObject -Property @{ Patch = $patch.title ApprovalAction = "Declined" } } } } } function Approve-WSUSUpdate { <# .SYNOPSIS Approves a WSUS update for a specific group with an optional deadline. .DESCRIPTION Approves a WSUS update for a specific group with an optional deadline. .PARAMETER InputObject Update object that is being approved. .PARAMETER Update Name of update being approved. .PARAMETER Group Name of group which will receive the update. .PARAMETER Deadline Optional deadline for client to install patch. .PARAMETER Action Type of approval action to take on update. Accepted values are Install, Approve, Uninstall and NotApproved .NOTES Name: Approve-WSUSUpdate Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Approve-WSUSUpdate -update "KB979906" -Group "Domain Servers" -Action Install Description ----------- This command will approve all updates with the KnowledgeBase number of KB979906 for the 'Domain Servers' group and the action command of 'Install'. .EXAMPLE Approve-WSUSUpdate -update "KB979906" -Group "Domain Servers" -Action Install -Deadline (get-Date).AddDays(3) Description ----------- This command will approve all updates with the KnowledgeBase number of KB979906 for the 'Domain Servers' group and the action command of 'Install' and sets a deadline for 3 days from when this command is run. .EXAMPLE Get-WSUSUpdate -Update "KB979906" | Approve-WSUSUpdate -Group "Domain Servers" -Action Install Description ----------- This command will take the collection of objects from the Get-WSUSUpdate command and then approve all updates for the 'Domain Servers' group and the action command of 'Install'. #> [cmdletbinding( DefaultParameterSetName = 'string', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param( [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'collection', ValueFromPipeline = $True)] [system.object] [ValidateNotNullOrEmpty()] $InputObject, [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'string', ValueFromPipeline = $False)] [string]$Update, [Parameter( Mandatory = $True, Position = 1, ParameterSetName = '', ValueFromPipeline = $False)] [string] [ValidateSet("Install", "All", "NotApproved","Uninstall")] $Action, [Parameter( Mandatory = $True, Position = 2, ParameterSetName = '', ValueFromPipeline = $False)] [string]$Group, [Parameter( Mandatory = $False, Position = 3, ParameterSetName = '', ValueFromPipeline = $False)] [datetime]$Deadline ) Begin { #Define the actions available Write-Verbose "Defining available approval actions" $Install = [Microsoft.UpdateServices.Administration.UpdateApprovalAction]::Install $All = [Microsoft.UpdateServices.Administration.UpdateApprovalAction]::All $NotApproved = [Microsoft.UpdateServices.Administration.UpdateApprovalAction]::NotApproved $Uninstall = [Microsoft.UpdateServices.Administration.UpdateApprovalAction]::Uninstall #Search for group specified Write-Verbose "Searching for group" $targetgroup = Get-WSUSGroup -name $group If (!$targetgroup) { Write-Error "Group $group does not exist in WSUS!" Break } } Process { #Perform appropriate action based on Parameter set name Switch ($pscmdlet.ParameterSetName) { "collection" { Write-Verbose "Using 'Collection' set name" #Change the variable that will hold the objects $patches = $inputobject } "string" { Write-Verbose "Using 'String' set name" #Search for updates Write-Verbose "Searching for update/s" $patches = Get-WSUSUpdate -update $update If (!$patches) { Write-Error "Update $update could not be found in WSUS!" Break } } } ForEach ($patch in $patches) { #Determine if Deadline is required If ($deadline) { Write-Verbose "Approving update with a deadline." If ($pscmdlet.ShouldProcess($($patch.title))) { #Create the computer target group $patch.Approve($action,$targetgroup,$deadline) | out-null #Print out report of what was approved New-Object PSObject -Property @{ Patch = $patch.title TargetGroup = $group ApprovalAction = $action Deadline = "$($deadline)" } } } Else { #Approve the patch Write-Verbose "Approving update without a deadline." If ($pscmdlet.ShouldProcess($($patch.title))) { #Create the computer target group $patch.Approve($action,$targetgroup) | out-null #Print out report of what was approved New-Object PSObject -Property @{ Patch = $patch.title TargetGroup = $group ApprovalAction = $action } } } } } } function Get-WSUSGroup { <# .SYNOPSIS Retrieves specific WSUS target group. .DESCRIPTION Retrieves specific WSUS target group. .PARAMETER Name Name of group to search for. No wildcards allowed. .PARAMETER Id GUID of group to search for. No wildcards allowed. .NOTES Name: Get-WSUSGroups Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSGroup -name "Domain Servers" Description ----------- This command will search for the group and display the information for Domain Servers" .EXAMPLE Get-WSUSGroup -ID "0b5ba818-021e-4238-8098-7245b0f90557" Description ----------- This command will search for the group and display the information for the WSUS group guid 0b5ba818-021e-4238-8098-7245b0f90557" #> [cmdletbinding( DefaultParameterSetName = 'name', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param( [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'name', ValueFromPipeline = $False)] [string]$Name, [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'id', ValueFromPipeline = $False)] [string]$Id ) Switch ($pscmdlet.ParameterSetName) { "name" {$wsus.GetComputerTargetGroups() | ? {$_.name -eq $name}} "id" {$wsus.GetComputerTargetGroups() | ? {$_.id -eq $id}} } } function Remove-WSUSUpdate { <# .SYNOPSIS Removes an update on WSUS. .DESCRIPTION Removes an update on WSUS. Use of the -whatif is advised to be sure you are declining the right patch or patches. .PARAMETER Update Name of update being removed. .NOTES Name: Remove-WSUSUpdate Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Remove-WSUSUpdate -update "KB986569" Description ----------- This command will remove all instances of KB986569 from WSUS. #> [cmdletbinding( DefaultParameterSetName = 'update', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param( [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'update', ValueFromPipeline = $True)] [string]$Update ) Begin { #Gather all updates from given information Write-Verbose "Searching for updates" $patches = Get-WSUSUpdate -update $update } Process { ForEach ($patch in $patches) { #Storing update guid $guid = ($patch.id).updateid If ($pscmdlet.ShouldProcess($($patch.title))) { $wsus.DeleteUpdate($id,$True) "$($patch.title) has been deleted from WSUS" } } } } function Stop-WSUSDownloads { <# .SYNOPSIS Cancels all current WSUS downloads. .DESCRIPTION Cancels all current WSUS downloads. .NOTES Name: Stop-WSUSDownloads Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Stop-WSUSDownloads Description ----------- This command will stop all updates being downloaded to the WSUS server. #> [cmdletbinding( DefaultParameterSetName = 'update', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param() #Cancel all downloads running on WSUS If ($pscmdlet.ShouldProcess($($wsus.name))) { $wsus.CancelAllDownloads() "Downloads have been cancelled." } } function Resume-WSUSDownloads { <# .SYNOPSIS Resumes all current WSUS downloads. .DESCRIPTION Resumes all current WSUS downloads that had been cancelled. .NOTES Name: Resume-WSUSDownloads Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Resume-WSUSDownloads Description ----------- This command will resume the downloading of updates to the WSUS server. #> [cmdletbinding( DefaultParameterSetName = 'update', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param() #Cancel all downloads running on WSUS If ($pscmdlet.ShouldProcess($($wsus.name))) { $wsus.ResumeAllDownloads() "Downloads have been resumed." } } function Stop-WSUSUpdateDownload { <# .SYNOPSIS Stops update download after approval. .DESCRIPTION Stops update download after approval. .PARAMETER update Name of update to cancel download. .NOTES Name: Stop-WSUSUpdateDownload Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Stop-WSUSUpdateDownload -update "KB965896" Description ----------- This command will cancel the download of update KB956896. #> [cmdletbinding( DefaultParameterSetName = 'update', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param( [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'update', ValueFromPipeline = $True)] [string]$update ) Begin { #Gather all updates from given information Write-Verbose "Searching for updates" $patches = Get-WSUSUpdate -update $update } Process { If ($patches) { ForEach ($patch in $patches) { Write-Verbose "Cancelling update download" If ($pscmdlet.ShouldProcess($($patch.title))) { $patch.CancelDownload() "$($patch.title) download has been cancelled." } } } Else { Write-Warning "No patches found that need downloading cancelled." } } } function Resume-WSUSUpdateDownload { <# .SYNOPSIS Resumes previously cancelled update download after approval. .DESCRIPTION Resumes previously cancelled update download after approval. .PARAMETER Update Name of cancelled update download to resume download. .NOTES Name: Resume-WSUSUpdateDownload Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Resume-WSUSUpdateDownload -update "KB965896" Description ----------- This command will resume the download of update KB956896 that was previously cancelled. #> [cmdletbinding( DefaultParameterSetName = 'update', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param( [Parameter( Mandatory = $True, Position = 0, ParameterSetName = 'update', ValueFromPipeline = $True)] [string]$Update ) Begin { #Gather all updates from given information Write-Verbose "Searching for updates" $patches = Get-WSUSUpdate -update $update } Process { If ($patches) { ForEach ($patch in $patches) { Write-Verbose "Resuming update download" If ($pscmdlet.ShouldProcess($($patch.title))) { $patch.ResumeDownload() "$($patch.title) download has been resumed." } } } Else { Write-Warning "No patches found needing to resume download!" } } } function Start-WSUSCleanup { <# .SYNOPSIS Performs a cleanup on WSUS based on user inputs. .DESCRIPTION Performs a cleanup on WSUS based on user inputs. .PARAMETER DeclineSupersededUpdates Declined Superseded Updates will be removed. .PARAMETER DeclineExpiredUpdates Expired updates should be declined. .PARAMETER CleanupObsoleteUpdates Delete obsolete updates from the database. .PARAMETER CompressUpdates Obsolete revisions to updates should be deleted from the database. .PARAMETER CleanupObsoleteComputers Delete obsolete computers from the database. .PARAMETER CleanupUnneededContentFiles Delete unneeded update files. .NOTES Name: Start-WSUSCleanup Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Start-WSUSCleanup -CompressUpdates -CleanupObsoleteComputers Description ----------- This command will run the WSUS cleanup wizard and delete obsolete computers from the database and delete obsolete update revisions from the database. .EXAMPLE Start-WSUSCleanup -CompressUpdates -CleanupObsoleteComputers -DeclineExpiredUpdates -CleanupObsoleteUpdates -CleanupUnneededContentFiles Description ----------- This command performs a full WSUS cleanup against the database. #> [cmdletbinding( DefaultParameterSetName = 'cleanup', ConfirmImpact = 'low', SupportsShouldProcess = $True )] Param( [Parameter( Mandatory = $False, Position = 0, ParameterSetName = 'cleanup', ValueFromPipeline = $False)] [switch]$DeclineSupersededUpdates, [Parameter( Mandatory = $False, Position = 1, ParameterSetName = 'cleanup', ValueFromPipeline = $False)] [switch]$DeclineExpiredUpdates, [Parameter( Mandatory = $False, Position = 2, ParameterSetName = 'cleanup', ValueFromPipeline = $False)] [switch]$CleanupObsoleteUpdates, [Parameter( Mandatory = $False, Position = 3, ParameterSetName = 'cleanup', ValueFromPipeline = $False)] [switch]$CompressUpdates, [Parameter( Mandatory = $False, Position = 4, ParameterSetName = 'cleanup', ValueFromPipeline = $False)] [switch]$CleanupObsoleteComputers, [Parameter( Mandatory = $False, Position = 5, ParameterSetName = 'cleanup', ValueFromPipeline = $False)] [switch]$CleanupUnneededContentFiles ) Begin { #Create cleanup scope $cleanScope = new-object Microsoft.UpdateServices.Administration.CleanupScope #Create cleanup manager object $cleanup = $wsus.GetCleanupManager() #Determine what will be in the scope If ($DeclineSupersededUpdates) { $cleanScope.DeclineSupersededUpdates = $True } If ($DeclineExpiredUpdates) { $cleanScope.DeclineExpiredUpdates = $True } If ($CleanupObsoleteUpdates) { $cleanScope.CleanupObsoleteUpdates = $True } If ($CompressUpdates) { $cleanScope.CompressUpdates = $True } If ($CleanupObsoleteComputers) { $cleanScope.CleanupObsoleteComputers = $True } If ($CleanupUnneededContentFiles) { $cleanScope.CleanupUnneededContentFiles = $True } } Process { Write-Host "Beginning cleanup" If ($pscmdlet.ShouldProcess($($wsus.name))) { $cleanup.PerformCleanup($cleanScope) } } } function Get-WSUSChildServers { <# .SYNOPSIS Retrieves all WSUS child servers. .DESCRIPTION Retrieves all WSUS child servers. .NOTES Name: Get-WSUSChildServers Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSChildServers Description ----------- This command will display all of the Child WSUS servers. #> [cmdletbinding()] Param () #Gather all child servers in WSUS $wsus.GetChildServers() } function Get-WSUSDownstreamServers { <# .SYNOPSIS Retrieves all WSUS downstream servers. .DESCRIPTION Retrieves all WSUS downstream servers. .NOTES Name: Get-WSUSDownstreamServers Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSDownstreamServers Description ----------- This command will display a list of all of the downstream WSUS servers. #> [cmdletbinding()] Param () #Gather all child servers in WSUS $wsus.GetDownstreamServers() } function Get-WSUSContentDownloadProgress { <# .SYNOPSIS Retrieves the progress of currently downloading updates. Displayed in bytes downloaded. .DESCRIPTION Retrieves the progress of currently downloading updates. Displayed in bytes downloaded. .PARAMETER Monitor Runs a background job to monitor currently running content download and notifies user when completed. .NOTES Name: Get-WSUSContentDownloadProgress Author: Boe Prox DateCreated: 24SEPT2010 .LINK https://boeprox.wordpress.org .EXAMPLE Get-WSUSContentDownloadProgress Description ----------- This command will display the current progress of the content download. .EXAMPLE Get-WSUSContentDownloadProgress -monitor Description ----------- This command will create a background job that will monitor the progress and alert the user via pop-up message that the download has been completed. #> [cmdletbinding()] Param ( [Parameter( Mandatory = $False, Position = 0, ParameterSetName = 'monitor', ValueFromPipeline = $False)] [switch]$Monitor ) If ($monitor) { #Stop and remove same jobs if existing $job = Get-Jo