zWindowsUpdate.psm1
### Module - zWindowsUpdate # Task settings $WU_TaskName = 'zWindowsUpdate' $WU_TaskDescription = 'Windows update task created by zWindowsUpdate PowerShell module' $WU_TaskWorkingDirectory = 'C:\Program Files\zWindowsUpdate' # Folder is deleted when running Remove-zWUTask # File names $WU_ScriptFileName = 'zWUScript.ps1' $WU_XmlLogFileName = 'zWUScriptLog.xml' $WU_LogFileName = 'zWUScript-Error.log' # zWU Functions function Get-zWULog { <# .NOTES ###################### mail@nimbus117.co.uk ###################### .SYNOPSIS Get the log entires for a windows update task. .DESCRIPTION Returns one or more lines from the log file generated when the task is run. By default the last 1 line is returned. .PARAMETER ComputerName Specifies the computers on which the command runs. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the current user. .PARAMETER Full Return the full log. .PARAMETER Port Specifies the network port on the remote computer that is used for this command. To connect to a remote computer, the remote computer must be listening on the port that the connection uses. The default ports are 5985, which is the WinRM port for HTTP, and 5986, which is the WinRM port for HTTPS. .PARAMETER PSSessionOption Specifies advanced options for the session. Enter a SessionOption object, such as one that you create by using the New-PSSessionOption cmdlet, or a hash table in which the keys are session option names and the values are session option values. .PARAMETER Tail Retrun the last n entries of the log. .PARAMETER ThrottleLimit Specifies the maximum number of concurrent connections that can be established to run this command. .PARAMETER UseSSL Indicates that this cmdlet uses the Secure Sockets Layer (SSL) protocol to establish a connection to the remote computer. By default, SSL is not used. .EXAMPLE PS C:\>Get-zWULog 'SRV01', 'SRV02', 'SRV03', 'SRV04', 'SRV05', 'SRV06', 'CLIENT01' ComputerName Timestamp Level Message ------------ --------- ----- ------- SRV06 29/07/2017 04:38:40 Warning Finished - Reboot required - 24 of 24 update(s) installed SRV02 29/07/2017 03:20:55 Info Finished - Download only - 3 update(s) downloaded SRV01 29/07/2017 03:14:16 Info Searching for updates SRV04 29/07/2017 03:20:55 Info Finished - Search only - 3 update(s) found SRV03 29/07/2017 03:14:19 Info Downloading update 9 of 24 - Update for Windows Server 2012 R2 (KB2883200) (226.9MB) CLIENT01 29/07/2017 03:14:31 Info Installing update 4 of 10 - Feature update to Windows 10 Enterprise, version 1703 (0B-2.7GB) SRV05 29/07/2017 03:14:17 Info Finished - No reboot required - 1 of 1 update(s) installed Get the last line from the update task log on the specified remote computers. .EXAMPLE PS C:\>Get-zWULog SRV04 -Full | Out-GridView Get-the full update task log from the computer SRV04 and display the results in Out-GridView. .EXAMPLE PS C:\>$cred = Get-Credential PS C:\>$PSSessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck PS C:\>Get-zWULog 10.10.10.10 -Credential $cred -UseSSL -PSSessionOption $PSSessionOption -Full ComputerName Timestamp Level Message ------------ --------- ----- ------- 10.10.10.10 02/03/2018 16:13:45 Info ## zWindowsUpdate ## 10.10.10.10 02/03/2018 16:13:45 Info Parameter - AutoSelect = True 10.10.10.10 02/03/2018 16:13:45 Info Parameter - SearchOnly = True 10.10.10.10 02/03/2018 16:13:45 Info Parameter - Service = WindowsUpdate 10.10.10.10 02/03/2018 16:13:45 Info Starting windows update session 10.10.10.10 02/03/2018 16:13:45 Info Searching for updates 10.10.10.10 02/03/2018 16:13:53 Info Found 3 update(s) (0B-1.2GB) 10.10.10.10 02/03/2018 16:13:53 Info Windows Malicious Software Removal Tool x64 - February 2018 (KB890830) (0B-38.4MB) 10.10.10.10 02/03/2018 16:13:53 Info 2018-02 Cumulative Update for Windows Server 2016 for x64-based Systems (KB4074590) (0B-1.1GB) 10.10.10.10 02/03/2018 16:13:53 Info Update for Windows Defender antimalware platform - KB4052623 (Version 4.12.17007.18022) (0B-3.1MB) 10.10.10.10 02/03/2018 16:13:53 Info Finished - Search only - 3 update(s) found Get the full update task log from the computer with the Ip address 10.10.10.10. The connection will use SSL and the PSSessionOptions provided. .LINK about_zWindowsUpdate Get-zWUTask New-zWUTask Remove-zWUTask Start-zWUTask Stop-zWUTask Wait-zWUTask #> [cmdletbinding(DefaultParameterSetName = 'Tail')] param( [parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Alias('Name', 'PSComputerName')] [string[]]$ComputerName, [PSCredential][System.Management.Automation.CredentialAttribute()]$Credential, [parameter(ParameterSetName = 'Full')] [switch]$Full, [ValidateRange(1, 65535)] [int]$Port, [System.Management.Automation.Remoting.PSSessionOption]$PSSessionOption, [parameter(Position=1,ParameterSetName = 'Tail')] [uint32]$Tail = 1, [uint16]$ThrottleLimit, [switch]$UseSSL ) begin { $Command = $MyInvocation.MyCommand.Name $ComputerNames = @() $sb = { $Task = Get-ScheduledTask -TaskName $using:WU_TaskName -ErrorAction 'SilentlyContinue' if ($Task) { $Path = Join-Path -Path $Task.Actions.WorkingDirectory -ChildPath $using:WU_XmlLogFileName if (Test-Path $Path -PathType Leaf) { $Import = Import-Clixml -Path $Path -ErrorAction 'Stop' if ($using:Full) {$Import} else {$Import | Select-Object -Last $using:Tail} } else {Write-Warning "[$env:COMPUTERNAME] $using:Command - No log file found."} } else {Write-Warning "[$env:COMPUTERNAME] $using:Command - No task named $using:WU_TaskName."} } } process {$ComputerNames += $ComputerName} end { $Invoke_Params = @{ScriptBlock = $sb ; ComputerName = $ComputerNames} if ($Credential) {$Invoke_Params += @{Credential = $Credential}} if ($ThrottleLimit) {$Invoke_Params += @{ThrottleLimit = $ThrottleLimit}} if ($Port) {$Invoke_Params += @{Port = $Port}} if ($UseSSL) {$Invoke_Params += @{UseSSL = $UseSSL}} if ($PSSessionOption) {$Invoke_Params += @{SessionOption = $PSSessionOption}} Invoke-Command @Invoke_Params | Select-Object @{l='ComputerName';e={$_.PSComputerName}}, TimeStamp, Level, Message } } Set-Alias -Name gzl -Value Get-zWULog function Get-zWUTask { <# .NOTES ###################### mail@nimbus117.co.uk ###################### .SYNOPSIS Get a windows update task. .DESCRIPTION Gets details of a windows update task. The details returned are the task State, LastRunTime and Parameters. .PARAMETER CimSessionOption Sets advanced options for the new CIM session. Enter the name of a CimSessionOption object created by using the New-CimSessionOption cmdlet. .PARAMETER ComputerName Specifies the computers on which the command runs. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the current user. .PARAMETER Port Specifies the network port on the remote computer that is used for this connection. To connect to a remote computer, the remote computer must be listening on the port that the connection uses. The default ports are 5985 (the WinRM port for HTTP) and 5986 (the WinRM port for HTTPS). .EXAMPLE PS C:\>Get-zWUTask SRV01 ComputerName State LastRunTime Parameters ------------ ----- ----------- ---------- SRV01 Ready 29/07/2017 03:14:16 -AcceptEula -DownloadOnly This command returns the details for the update task on SRV01. .EXAMPLE PS C:\>Get-zWUTask 'SRV01', 'SRV02', 'SRV03', 'SRV04', 'SRV05', 'SRV06', 'CLIENT01' ComputerName State LastRunTime Parameters ------------ ----- ----------- ---------- SRV05 Ready 29/07/2017 03:14:17 -SearchOnly -UpdateType SecurityUpdates,CriticalUpdates SRV06 Ready 29/07/2017 03:14:15 -AcceptEula -AutoSelect -DownloadOnly CLIENT01 Ready 29/07/2017 03:14:17 -AcceptEula -SearchOnly -Service WindowsUpdate SRV02 Ready 29/07/2017 03:14:24 -SearchOnly -UpdateType SecurityUpdates,CriticalUpdates SRV01 Ready 29/07/2017 03:14:16 -AcceptEula -ExcludeKB KB2267602,KB890830 -Reboot SRV04 Ready 29/07/2017 03:14:19 -AcceptEula -AutoSelect -DownloadOnly SRV03 Ready 29/07/2017 03:14:19 -AcceptEula -ExcludeOptional -Reboot .LINK about_zWindowsUpdate Get-zWULog New-zWUTask Remove-zWUTask Start-zWUTask Stop-zWUTask Wait-zWUTask #> [cmdletbinding()] param( [Microsoft.Management.Infrastructure.Options.WSManSessionOptions]$CimSessionOption, [parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Alias('Name', 'PSComputerName')] [string[]]$ComputerName, [PSCredential][System.Management.Automation.CredentialAttribute()]$Credential, [ValidateRange(1, 65535)] [int]$Port ) begin {$Command = $MyInvocation.MyCommand.Name} process { $Cim_Params = @{ComputerName = $ComputerName ; Name = ("$WU_TaskName-" + [guid]::NewGuid().Guid)} if ($Credential) {$Cim_Params += @{Credential = $Credential}} if ($Port) {$Cim_Params += @{Port = $Port}} if ($CimSessionOption) {$Cim_Params += @{SessionOption = $CimSessionOption}} $CimSession = New-CimSession @Cim_Params foreach ($Session in $CimSession) { $Task = Get-ScheduledTask -TaskName $WU_TaskName -CimSession $Session -ErrorAction 'SilentlyContinue' if ($Task) { $Task | Select-Object ` @{l='ComputerName';e={$_.PSComputerName}}, ` State, ` @{l='LastRunTime';e={($_ | Get-ScheduledTaskInfo).LastRunTime}}, ` @{l='Parameters';e={($_.Actions.Arguments -split ".ps1' ")[1].TrimEnd("`" > $WU_LogFileName 2>&1")}} } else {Write-Warning "[$($Session.ComputerName)] $Command - No task named $WU_TaskName."} } } end {Get-CimSession -Name "$WU_TaskName*" | Remove-CimSession} } Set-Alias -Name gzt -Value Get-zWUTask function New-zWUTask { <# .NOTES ###################### mail@nimbus117.co.uk ###################### .SYNOPSIS Creates a new windows update task. .DESCRIPTION Copies the zWUScript.ps1 script from this module to the remote or local computer and creates a scheduled task to run it. The task is created without a trigger. By default when the task is run the script will search for, download and install all software updates but will not reboot the computer if required. .PARAMETER AcceptEula Accept update EULA if needed. .PARAMETER AutoSelect Only include updates that are flagged to be automatically selected by Windows Update. .PARAMETER ComputerName Specifies the computers on which the command runs. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the current user. .PARAMETER DownloadOnly Download updates but do not install them. .PARAMETER ExcludeKB Exclude updates by KB number. .PARAMETER ExcludeOptional Exclude updates that are considered optional. .PARAMETER IncludeKB Include updates by KB number. .PARAMETER Port Specifies the network port on the remote computer that is used for this command. To connect to a remote computer, the remote computer must be listening on the port that the connection uses. The default ports are 5985, which is the WinRM port for HTTP, and 5986, which is the WinRM port for HTTPS. .PARAMETER PSSessionOption Specifies advanced options for the session. Enter a SessionOption object, such as one that you create by using the New-PSSessionOption cmdlet, or a hash table in which the keys are session option names and the values are session option values. .PARAMETER Reboot Attempt to reboot the computer if required after installing updates. .PARAMETER SearchOnly Search for updates only, do not download or install them. .PARAMETER Service Select update service. Possible values are 'MicrosoftUpdate', 'WindowsUpdate', 'WSUS'. When not specified the system default is used. The script will attempt to add the MicrosoftUpdate service if it is not registered. .PARAMETER SmtpFrom From address for the email report. .PARAMETER SmtpServer Smtp server used to send the email report. .PARAMETER SmtpTo To address for the email report. .PARAMETER ThrottleLimit Specifies the maximum number of concurrent connections that can be established to run this command. .PARAMETER UseSSL Indicates that this cmdlet uses the Secure Sockets Layer (SSL) protocol to establish a connection to the remote computer. By default, SSL is not used. .PARAMETER UpdateType Specify which update types to search for, such as CriticalUpdates or SecurityUpdates. Possible values are 'Application', 'CriticalUpdates', 'Definitions', 'FeaturePacks', 'SecurityUpdates', 'ServicePacks', 'Tools', 'UpdateRollups', 'Updates'. The default is all software updates. .EXAMPLE PS C:\>New-zWUTask -ComputerName SRV01 -UpdateType CriticalUpdates,SecurityUpdates -Reboot | Start-zWUTask ComputerName TaskName ------------ -------- SRV05 zWindowsUpdate This example shows how to create a windows update task on the remote computer SRV01 and start it. The task will search for, download and install security and critical updates then reboot the computer if needed. .EXAMPLE PS C:\>$Computers = (Get-ADComputer -Filter "name -like 'srv*'").Name PS C:\>$cred = Get-Credential PS C:\>New-zWUTask -ComputerName $Computers -Credential $cred -AutoSelect -SearchOnly ComputerName TaskName ------------ -------- SRV05 zWindowsUpdate SRV01 zWindowsUpdate SRV02 zWindowsUpdate SRV03 zWindowsUpdate SRV04 zWindowsUpdate In this example tasks are created on multiple computers and are set to search for updates only. The first command uses the Get-ADComputer cmdlet to gather a list of computers and saves them in the variable $Computers. The Second command gets a credential object and saves it to the variable $cred The last command creates the tasks on the computers specified in the $Computers variable and uses the credentials specified in the $cred variable to authenticate the remote session. .EXAMPLE PS C:\>$Computers = 'srv01', 'srv02', 'srv03' PS C:\>New-zWUTask $Computers -AutoSelect -Reboot PS C:\>$Trigger = New-ScheduledTaskTrigger -At 03:00 -Weekly -DaysOfWeek Wednesday PS C:\>Set-ScheduledTask -TaskName zWindowsUpdate -Trigger $Trigger -CimSession $Computers In the above example a windows update task is created on the computers srv01, srv02 and srv03 and set to reboot the computer automatically if required. The builtin ScheduledTask cmdlets are then used to create and apply a trigger to the tasks so they run on a schedule. In this case every Wednesday at 3:00am. .EXAMPLE PS C:\>New-zWUTask $Computers -Confirm:$false -AutoSelect -ExcludeKB KB2267602,KB890830 -SearchOnly PS C:\>Start-zWUTask $Computers -Confirm:$false | Wait-zWUTask -Delay 30 .LINK about_zWindowsUpdate Get-zWULog Get-zWUTask Remove-zWUTask Start-zWUTask Stop-zWUTask Wait-zWUTask #> [cmdletbinding(SupportsShouldProcess = $true,ConfirmImpact = 'High', DefaultParameterSetName = 'Install')] param( [parameter(ParameterSetName = 'DownloadOnly')] [parameter(ParameterSetName = 'Install')] [switch]$AcceptEula, [switch]$AutoSelect, [parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Alias('Name', 'PSComputerName')] [string[]]$ComputerName, [PSCredential][System.Management.Automation.CredentialAttribute()]$Credential, [parameter(ParameterSetName = 'DownloadOnly')] [switch]$DownloadOnly, [ValidateScript({$_ -match 'kb[0-9]{6,}'})] [string[]]$ExcludeKB, [switch]$ExcludeOptional, [ValidateScript({$_ -match 'kb[0-9]{6,}'})] [string[]]$IncludeKB, [ValidateRange(1, 65535)] [int]$Port, [System.Management.Automation.Remoting.PSSessionOption]$PSSessionOption, [parameter(ParameterSetName = 'Install')] [switch]$Reboot, [parameter(ParameterSetName = 'SearchOnly')] [switch]$SearchOnly, [ValidateSet('MicrosoftUpdate', 'WindowsUpdate', 'WSUS')] [ValidateNotNullOrEmpty()] [string]$Service, [Net.Mail.MailAddress]$SmtpFrom, [ValidateNotNullOrEmpty()] [string]$SmtpServer, [Net.Mail.MailAddress]$SmtpTo, [uint16]$ThrottleLimit, [parameter(Position=1)] [ValidateSet('Application', 'CriticalUpdates', 'Definitions', 'FeaturePacks', 'SecurityUpdates', 'ServicePacks', 'Tools', 'UpdateRollups', 'Updates')] [ValidateNotNullOrEmpty()] [String[]]$UpdateType, [switch]$UseSSL ) begin { $Command = $MyInvocation.MyCommand.Name if (($SmtpFrom -or $SmtpTo -or $SmtpServer) -and -not ($SmtpFrom -and $SmtpTo -and $SmtpServer)) {throw "$Command : Provide all -Smtp* parameters"} $ScriptFilePath = Join-Path -Path $WU_TaskWorkingDirectory -ChildPath $WU_ScriptFileName $ModulePath = (Get-Module $MyInvocation.MyCommand.ModuleName).ModuleBase $UpdateScript = Get-Content "$ModulePath\$WU_ScriptFileName" $Argument = "-NoProfile -ExecutionPolicy Bypass -Command `"& '$ScriptFilePath'" switch ($true) { $AcceptEula {$Argument += ' -AcceptEula'} $AutoSelect {$Argument += ' -AutoSelect'} $DownloadOnly {$Argument += ' -DownloadOnly'} ($ExcludeKB -as [bool]) {$Argument += ' -ExcludeKB ' ; $ExcludeKB | ForEach-Object {$Argument += "$_,"} ; $Argument = $Argument.TrimEnd(',')} $ExcludeOptional {$Argument += ' -ExcludeOptional'} ($IncludeKB -as [bool]) {$Argument += ' -IncludeKB ' ; $IncludeKB | ForEach-Object {$Argument += "$_,"} ; $Argument = $Argument.TrimEnd(',')} $Reboot {$Argument += ' -Reboot'} $SearchOnly {$Argument += ' -SearchOnly'} ($Service -as [bool]) {$Argument += " -Service $Service"} ($SmtpFrom -as [bool]) {$Argument += " -SmtpFrom $($SmtpFrom.Address)"} ($SmtpTo -as [bool]) {$Argument += " -SmtpTo $($SmtpTo.Address)"} ($SmtpServer -as [bool]) {$Argument += " -SmtpServer $SmtpServer"} ($UpdateType.Count -gt 0) {$Argument += ' -UpdateType ' ; $UpdateType | ForEach-Object {$Argument += "$_,"} ; $Argument = $Argument.TrimEnd(',')} } $Argument += "`" > $WU_LogFileName 2>&1" $sb = { $Task = Get-ScheduledTask -TaskName $using:WU_TaskName -ErrorAction 'SilentlyContinue' if ($Task.State -ne 'Running') { if (-not(Test-Path $using:WU_TaskWorkingDirectory -PathType Container)) {mkdir $using:WU_TaskWorkingDirectory -Force | Out-Null} $using:UpdateScript | Out-File $using:ScriptFilePath -Force $Action = New-ScheduledTaskAction -Execute 'PowerShell.exe' -Argument $Using:Argument -WorkingDirectory $using:WU_TaskWorkingDirectory Register-ScheduledTask -Action $Action -User 'System' -TaskName $using:WU_TaskName -Description $using:WU_TaskDescription -RunLevel Highest -Force } else {Write-Warning "[$env:COMPUTERNAME] $using:Command - Task is running."} } } process {$ComputerNames += $ComputerName} end { if ($PSCmdlet.ShouldProcess($ComputerNames,'Create new windows update task')) { $Invoke_Params = @{ScriptBlock = $sb ; ComputerName = $ComputerNames} if ($Credential) {$Invoke_Params += @{Credential = $Credential}} if ($ThrottleLimit) {$Invoke_Params += @{ThrottleLimit = $ThrottleLimit}} if ($Port) {$Invoke_Params += @{Port = $Port}} if ($UseSSL) {$Invoke_Params += @{UseSSL = $UseSSL}} if ($PSSessionOption) {$Invoke_Params += @{SessionOption = $PSSessionOption}} Invoke-Command @Invoke_Params | Select-Object @{l='ComputerName';e={$_.PSComputerName}}, TaskName } } } Set-Alias -Name nzt -Value New-zWUTask function Remove-zWUTask { <# .NOTES ###################### mail@nimbus117.co.uk ###################### .SYNOPSIS Removes a windows update task. .DESCRIPTION Removes the scheduled task and deletes the task working directory. .PARAMETER ComputerName Specifies the computers on which the command runs. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the current user. .PARAMETER Port Specifies the network port on the remote computer that is used for this command. To connect to a remote computer, the remote computer must be listening on the port that the connection uses. The default ports are 5985, which is the WinRM port for HTTP, and 5986, which is the WinRM port for HTTPS. .PARAMETER PSSessionOption Specifies advanced options for the session. Enter a SessionOption object, such as one that you create by using the New-PSSessionOption cmdlet, or a hash table in which the keys are session option names and the values are session option values. .PARAMETER ThrottleLimit Specifies the maximum number of concurrent connections that can be established to run this command. .PARAMETER UseSSL Indicates that this cmdlet uses the Secure Sockets Layer (SSL) protocol to establish a connection to the remote computer. By default, SSL is not used. .EXAMPLE PS C:\>Remove-zWUTask SRV01 .EXAMPLE PS C:\>Remove-zWUTask -ComputerName (Get-ADComputer -Filter "name -like 'srv*'").Name -Confirm:$false .LINK about_zWindowsUpdate Get-zWULog Get-zWUTask New-zWUTask Start-zWUTask Stop-zWUTask Wait-zWUTask #> [cmdletbinding(SupportsShouldProcess = $true,ConfirmImpact = 'High')] param( [parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Alias('Name', 'PSComputerName')] [string[]]$ComputerName, [PSCredential][System.Management.Automation.CredentialAttribute()]$Credential, [ValidateRange(1, 65535)] [int]$Port, [System.Management.Automation.Remoting.PSSessionOption]$PSSessionOption, [uint16]$ThrottleLimit, [switch]$UseSSL ) begin { $Command = $MyInvocation.MyCommand.Name $sb = { $Task = Get-ScheduledTask -TaskName $using:WU_TaskName -ErrorAction 'SilentlyContinue' if ($Task) { if ($Task.State -ne 'Running') { Remove-Item $Task.Actions.WorkingDirectory -Recurse -Force -Confirm:$false $Task | Unregister-ScheduledTask -Confirm:$false } else {Write-Warning "[$env:COMPUTERNAME] $using:Command - Task is running."} } else {Write-Warning "[$env:COMPUTERNAME] $using:Command - No task named $using:WU_TaskName."} } } process {$ComputerNames += $ComputerName} end { if ($PSCmdlet.ShouldProcess($ComputerNames,'Remove windows update task')) { $Invoke_Params = @{ScriptBlock = $sb ; ComputerName = $ComputerNames} if ($Credential) {$Invoke_Params += @{Credential = $Credential}} if ($ThrottleLimit) {$Invoke_Params += @{ThrottleLimit = $ThrottleLimit}} if ($Port) {$Invoke_Params += @{Port = $Port}} if ($UseSSL) {$Invoke_Params += @{UseSSL = $UseSSL}} if ($PSSessionOption) {$Invoke_Params += @{SessionOption = $PSSessionOption}} Invoke-Command @Invoke_Params } } } Set-Alias -Name rzt -Value Remove-zWUTask function Start-zWUTask { <# .NOTES ###################### mail@nimbus117.co.uk ###################### .SYNOPSIS Start a windows update task. .DESCRIPTION Start a windows update task. .PARAMETER CimSessionOption Sets advanced options for the new CIM session. Enter the name of a CimSessionOption object created by using the New-CimSessionOption cmdlet. .PARAMETER ComputerName Specifies the computers on which the command runs. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the current user. .PARAMETER Port Specifies the network port on the remote computer that is used for this connection. To connect to a remote computer, the remote computer must be listening on the port that the connection uses. The default ports are 5985 (the WinRM port for HTTP) and 5986 (the WinRM port for HTTPS). .EXAMPLE Start-zWUTask 192.168.0.236 -Credential $cred .EXAMPLE New-zWUTask 'srv01', 'srv02' -Confirm:$false | Start-zWUTask -Confirm:$false .LINK about_zWindowsUpdate Get-zWULog Get-zWUTask New-zWUTask Remove-zWUTask Stop-zWUTask Wait-zWUTask #> [cmdletbinding(SupportsShouldProcess = $true,ConfirmImpact = 'High')] param( [Microsoft.Management.Infrastructure.Options.WSManSessionOptions]$CimSessionOption, [parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Alias('Name', 'PSComputerName')] [string[]]$ComputerName, [PSCredential][System.Management.Automation.CredentialAttribute()]$Credential, [ValidateRange(1, 65535)] [int]$Port ) begin {$Command = $MyInvocation.MyCommand.Name} process { if ($PSCmdlet.ShouldProcess($ComputerName,'Start windows update task')) { $Cim_Params = @{ComputerName = $ComputerName ; Name = ("$WU_TaskName-" + [guid]::NewGuid().Guid)} if ($Credential) {$Cim_Params += @{Credential = $Credential}} if ($Port) {$Cim_Params += @{Port = $Port}} if ($CimSessionOption) {$Cim_Params += @{SessionOption = $CimSessionOption}} $CimSession = New-CimSession @Cim_Params foreach ($Session in $CimSession) { $Task = Get-ScheduledTask -TaskName $WU_TaskName -CimSession $Session -ErrorAction 'SilentlyContinue' if ($Task) { if ($Task.State -ne 'Running') { $Task | Start-ScheduledTask | Out-Null $Task | Get-ScheduledTask | Select-Object @{l='ComputerName';e={$_.PSComputerName}}, State } else {Write-Warning "[$($Session.ComputerName)] $Command - Task is already running."} } else {Write-Warning "[$($Session.ComputerName)] $Command - No task named $WU_TaskName."} } } } end {Get-CimSession -Name "$WU_TaskName*" | Remove-CimSession} } Set-Alias -Name szt -Value Start-zWUTask function Stop-zWUTask { <# .NOTES ###################### mail@nimbus117.co.uk ###################### .SYNOPSIS Stop a windows update task. .DESCRIPTION Stop a windows update task. .PARAMETER CimSessionOption Sets advanced options for the new CIM session. Enter the name of a CimSessionOption object created by using the New-CimSessionOption cmdlet. .PARAMETER ComputerName Specifies the computers on which the command runs. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the current user. .PARAMETER Port Specifies the network port on the remote computer that is used for this connection. To connect to a remote computer, the remote computer must be listening on the port that the connection uses. The default ports are 5985 (the WinRM port for HTTP) and 5986 (the WinRM port for HTTPS). .EXAMPLE Stop-zWUTask -ComputerName 192.168.0.236 -Credential $cred .EXAMPLE Stop-zWUtask $Computers -Confirm:$false .LINK about_zWindowsUpdate Get-zWULog Get-zWUTask New-zWUTask Remove-zWUTask Start-zWUTask Wait-zWUTask #> [cmdletbinding(SupportsShouldProcess = $true,ConfirmImpact = 'High')] param( [Microsoft.Management.Infrastructure.Options.WSManSessionOptions]$CimSessionOption, [parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Alias('Name', 'PSComputerName')] [string[]]$ComputerName, [PSCredential][System.Management.Automation.CredentialAttribute()]$Credential, [ValidateRange(1, 65535)] [int]$Port ) begin {$Command = $MyInvocation.MyCommand.Name} process { if ($PSCmdlet.ShouldProcess($ComputerName,'Stop windows update task')) { $Cim_Params = @{ComputerName = $ComputerName ; Name = ("$WU_TaskName-" + [guid]::NewGuid().Guid)} if ($Credential) {$Cim_Params += @{Credential = $Credential}} if ($Port) {$Cim_Params += @{Port = $Port}} if ($CimSessionOption) {$Cim_Params += @{SessionOption = $CimSessionOption}} $CimSession = New-CimSession @Cim_Params foreach ($Session in $CimSession) { $Task = Get-ScheduledTask -TaskName $WU_TaskName -CimSession $Session -ErrorAction 'SilentlyContinue' if ($Task) { if ($Task.State -eq 'Running') { $Task | Stop-ScheduledTask | Out-Null $Task | Get-ScheduledTask | Select-Object @{l='ComputerName';e={$_.PSComputerName}}, State } else {Write-Warning "[$($Session.ComputerName)] $Command - Task is not running."} } else {Write-Warning "[$($Session.ComputerName)] $Command - No task named $WU_TaskName."} } } } end {Get-CimSession -Name "$WU_TaskName*" | Remove-CimSession} } Set-Alias -Name spzt -Value Stop-zWUTask function Wait-zWUTask { <# .NOTES ###################### mail@nimbus117.co.uk ###################### .SYNOPSIS Waits for a windows update task to finish. .DESCRIPTION Checks the state of the windows update tasks on the specified computers and waits until they are all complete before continuing the pipeline. .PARAMETER CimSessionOption Sets advanced options for the new CIM session. Enter the name of a CimSessionOption object created by using the New-CimSessionOption cmdlet. .PARAMETER ComputerName Specifies the computers on which the command runs. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the current user. .PARAMETER Delay The interval between checking the state of the task in seconds. The default is 60 seconds. .PARAMETER Port Specifies the network port on the remote computer that is used for this connection. To connect to a remote computer, the remote computer must be listening on the port that the connection uses. The default ports are 5985 (the WinRM port for HTTP) and 5986 (the WinRM port for HTTPS). .PARAMETER Silent Hide the progress bar. .EXAMPLE PS C:\>$Computers = (Get-ADComputer -Filter "name -like 'srv*'").Name PS C:\>Wait-zWUTask -ComputerName $Computers ComputerName State ------------ ----- SRV01 Ready SRV02 Ready SRV03 Ready SRV04 Ready .EXAMPLE New-zWUTask $Computers -SearchOnly | Start-zWUTask | Wait-zWUTask -Delay 30 | Get-zWULog -Full | Out-GridView .LINK about_zWindowsUpdate Get-zWULog Get-zWUTask New-zWUTask Remove-zWUTask Start-zWUTask Stop-zWUTask #> [cmdletbinding()] param( [Microsoft.Management.Infrastructure.Options.WSManSessionOptions]$CimSessionOption, [parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Alias('Name', 'PSComputerName')] [string[]]$ComputerName, [PSCredential][System.Management.Automation.CredentialAttribute()]$Credential, [parameter(Position=1)] [ValidateRange(10,300)] [uint32]$Delay = 60, [ValidateRange(1, 65535)] [int]$Port, [switch]$Silent ) begin {$ComputerNames = @()} process {$ComputerNames += $ComputerName} end { $TotalCount = ($ComputerNames | Measure-Object).Count $RunningCount = $TotalCount $Cim_Params = @{ComputerName = $ComputerNames ; Name = ("$WU_TaskName-" + [guid]::NewGuid().Guid)} if ($Credential) {$Cim_Params += @{Credential = $Credential}} if ($Port) {$Cim_Params += @{Port = $Port}} if ($CimSessionOption) {$Cim_Params += @{SessionOption = $CimSessionOption}} $CimSession = New-CimSession @Cim_Params if ($CimSession) { $Waiting = $true while ($Waiting) { if (-not $Silent) { Write-Progress ` -Activity 'Wait-zWUTask' -CurrentOperation 'Checking task state' ` -Status "$($TotalCount - $RunningCount) of $TotalCount complete" ` -PercentComplete ((($TotalCount - $RunningCount) / $TotalCount) * 100) } $Tasks = Get-ScheduledTask -TaskName $WU_TaskName -CimSession $CimSession if ($Tasks.State -contains 'Running') { $RunningCount = ($Tasks | Where-Object {$_.State -eq 'Running'} | Measure-Object).Count if (-not $Silent) { Write-Progress ` -Activity 'Wait-zWUTask' -CurrentOperation "Waiting $Delay seconds" ` -Status "$($TotalCount - $RunningCount) of $TotalCount complete" ` -PercentComplete ((($TotalCount - $RunningCount) / $TotalCount) * 100) } Start-Sleep $Delay } else {$Waiting = $false} } if (-not $Silent) {Write-Progress -Activity 'Wait-zWUTask' -Completed} $Tasks | Select-Object @{l='ComputerName';e={$_.PSComputerName}}, @{l='State';e={$_.State.ToString()}} | Sort-Object ComputerName Get-CimSession -Name "$WU_TaskName*" | Remove-CimSession } } } Set-Alias -Name wzt -Value Wait-zWUTask Export-ModuleMember -Function * -Alias * |