Skip to content

Commit e6c1e0f

Browse files
committed
Merge branch 'dev' into 'master'
Invoke-WindowsUpdate: Improves the creation of WU scheduled task See merge request fozzy-winadmins/AutomaticMaintenance!28
2 parents acbe232 + c654430 commit e6c1e0f

File tree

2 files changed

+104
-54
lines changed

2 files changed

+104
-54
lines changed

AutomaticMaintenance.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@{
22
RootModule = 'AutomaticMaintenance.psm1'
3-
ModuleVersion = '2.11.0'
3+
ModuleVersion = '2.11.1'
44
GUID = '8e34abf8-40ba-4c68-8bf8-f235cd001d82'
55
Author = 'Kirill Nikolaev'
66
CompanyName = 'Fozzy Inc.'

Private/WindowsUpdate/Invoke-WindowsUpdate.ps1

Lines changed: 103 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ function Invoke-WindowsUpdate {
3030
Write-Debug -Message ('$DefaultFilterString = ''{0}''' -f $DefaultFilterString)
3131
Write-Debug -Message ('$Criteria = ''{0}''' -f $Criteria)
3232

33+
Write-Debug -Message ('$RemoteCimSession = New-CimSession -ComputerName ''{0}''' -f $ComputerName)
34+
$RemoteCimSession = New-CimSession -ComputerName $ComputerName
35+
Write-Debug -Message ('$RemoteCimSession: ''{0}''' -f (Out-String -InputObject $RemoteCimSession))
36+
3337
if (-not $Filter) {
3438
Write-Debug -Message ('$ComputerMaintenanceConfiguration = Get-ComputerMaintenanceConfiguration -ComputerName {0}' -f $ComputerName)
3539
$ComputerMaintenanceConfiguration = Get-ComputerMaintenanceConfiguration -ComputerName $ComputerName
@@ -98,69 +102,109 @@ function Invoke-WindowsUpdate {
98102
$ConvertedScriptBlock = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($JoinedScriptBlockString))
99103
Write-Debug -Message ('$ConvertedScriptBlock: ''{0}''' -f $ConvertedScriptBlock)
100104

101-
Write-Debug -Message '$Scheduler = New-Object -ComObject ''Schedule.Service'''
102-
$Scheduler = New-Object -ComObject 'Schedule.Service'
103-
Write-Debug -Message '$Task = $Scheduler.NewTask(0)'
104-
$Task = $Scheduler.NewTask(0)
105-
106-
Write-Debug -Message '$RegistrationInfo = $Task.RegistrationInfo'
107-
$RegistrationInfo = $Task.RegistrationInfo
108-
Write-Debug -Message ('$RegistrationInfo.Description = ''{0}''' -f $TaskDescription)
109-
$RegistrationInfo.Description = $TaskDescription
110-
Write-Debug -Message '$RegistrationInfo.Author = ''SYSTEM'''
111-
$RegistrationInfo.Author = 'SYSTEM'
112-
113-
Write-Debug -Message '$Settings = $Task.Settings'
114-
$Settings = $Task.Settings
115-
Write-Debug -Message '$Settings.Enabled = $true'
116-
$Settings.Enabled = $true
117-
Write-Debug -Message '$Settings.StartWhenAvailable = $true'
118-
$Settings.StartWhenAvailable = $true
119-
Write-Debug -Message '$Settings.Hidden = $false'
120-
$Settings.Hidden = $false
121-
122-
Write-Debug -Message '$Action = $Task.Actions.Create(0)'
123-
$Action = $Task.Actions.Create(0)
124-
Write-Debug -Message '$Action.Path = ''powershell'''
125-
$Action.Path = 'powershell'
126-
Write-Debug -Message ('$Action.Arguments = ''-NoLogo -NoProfile -NonInteractive -EncodedCommand {{0}}'' -f ''{0}''' -f $ConvertedScriptBlock)
127-
$Action.Arguments = '-NoLogo -NoProfile -NonInteractive -EncodedCommand {0}' -f $ConvertedScriptBlock
128-
129-
Write-Debug -Message '$Task.Principal.RunLevel = 1'
130-
$Task.Principal.RunLevel = 1
131-
132-
Write-Debug -Message ('$Task.XmlText: {0}' -f [string]$Task.XmlText)
133-
134-
Write-Debug -Message ('$Scheduler.Connect(''{0}'')' -f $ComputerName)
135-
$Scheduler.Connect($ComputerName)
136-
Write-Debug -Message '$RootFolder = $Scheduler.GetFolder(''\'')'
137-
$RootFolder = $Scheduler.GetFolder('\')
138-
Write-Debug -Message ('$RootFolder: ''{0}''' -f $RootFolder | Out-String)
139-
140-
Write-Debug -Message ('$RunningTask = $Scheduler.GetRunningTasks(0) | Where-Object {{$_.Name -eq ''{0}''}}' -f $TaskName)
141-
$RunningTask = $Scheduler.GetRunningTasks(0) | Where-Object {$_.Name -eq $TaskName}
142-
Write-Debug -Message ('$RunningTask: {0}' -f [string]$RunningTask.Name)
143-
Write-Debug -Message 'if ($RunningTask)'
144-
if ($RunningTask) {
145-
$Message = 'Task {0} is already running (PID: {1}) @ host {2}' -f $TaskName, $RunningTask.EnginePID, $ComputerName
146-
$PSCmdlet.ThrowTerminatingError((New-Object -TypeName 'System.Management.Automation.ErrorRecord' -ArgumentList ((New-Object -TypeName 'System.InvalidOperationException' -ArgumentList $Message), 'InvalidOperationException', [System.Management.Automation.ErrorCategory]::ResourceExists, $null)))
105+
Write-Debug -Message '$ExistingSheduledTasks = Get-ScheduledTask -CimSession $RemoteCimSession'
106+
$ExistingSheduledTasks = Get-ScheduledTask -CimSession $RemoteCimSession
107+
Write-Debug -Message ('$ExistingSheduledTasks: ''{0}''' -f ($ExistingSheduledTasks.TaskName -join ', '))
108+
109+
Write-Debug -Message '$ScheduledTaskStateRunning = ''Running'''
110+
$ScheduledTaskStateRunning = 'Running'
111+
112+
Write-Debug -Message 'foreach ($ExistingSheduledTask in $ExistingSheduledTasks)'
113+
foreach ($ExistingSheduledTask in $ExistingSheduledTasks) {
114+
Write-Debug -Message ('$ExistingSheduledTask: ''{0}''' -f (Out-String -InputObject $ExistingSheduledTask))
115+
Write-Debug -Message ('if ($ExistingSheduledTask.TaskName -eq ''{0}'')' -f $TaskName)
116+
if ($ExistingSheduledTask.TaskName -eq $TaskName) {
117+
Write-Debug -Message '$ScheduledTaskState = $ExistingSheduledTask.State.ToString()'
118+
$ScheduledTaskState = $ExistingSheduledTask.State.ToString()
119+
Write-Debug -Message ('$ScheduledTaskState = ''{0}''' -f $ScheduledTaskState)
120+
Write-Debug -Message 'if ($ScheduledTaskState -eq $ScheduledTaskStateRunning)'
121+
if ($ScheduledTaskState -eq $ScheduledTaskStateRunning) {
122+
$Message = 'Task ''{0}'' is already running on host ''{1}'', task path: ''{2}''' -f $TaskName, $ComputerName, $ExistingSheduledTask.TaskPath
123+
$PSCmdlet.ThrowTerminatingError((New-Object -TypeName 'System.Management.Automation.ErrorRecord' -ArgumentList ((New-Object -TypeName 'System.InvalidOperationException' -ArgumentList $Message), 'InvalidOperationException', [System.Management.Automation.ErrorCategory]::ResourceExists, $null)))
124+
}
125+
else {
126+
Write-Debug -Message 'Unregister-ScheduledTask -InputObject $ExistingSheduledTask -Confirm:$false'
127+
Unregister-ScheduledTask -InputObject $ExistingSheduledTask -Confirm:$false
128+
}
129+
}
130+
}
131+
132+
Write-Debug -Message ('$ScheduledTaskActionArgument = ''-NoLogo -NoProfile -NonInteractive -EncodedCommand {{0}}'' -f {0}' -f $ConvertedScriptBlock)
133+
$ScheduledTaskActionArgument = '-NoLogo -NoProfile -NonInteractive -EncodedCommand {0}' -f $ConvertedScriptBlock
134+
Write-Debug -Message ('$ScheduledTaskActionArgument = ''{0}''' -f $ScheduledTaskActionArgument)
135+
Write-Debug -Message '$RemoteCimsessionParams = @{ CimSession = $RemoteCimSession }'
136+
137+
$RemoteCimsessionParams = @{
138+
CimSession = $RemoteCimSession
139+
}
140+
141+
Write-Debug -Message ('$RemoteCimsessionParams: ''{0}''' -f (Out-String -InputObject $RemoteCimsessionParams))
142+
Write-Debug -Message ('$NewTaskActionParams = @{{ Execute = ''powershell''; Argument = ''{0}'' }}' -f $ScheduledTaskActionArgument)
143+
144+
$NewTaskActionParams = @{
145+
Execute = 'powershell'
146+
Argument = $ScheduledTaskActionArgument
147+
}
148+
149+
Write-Debug -Message ('$NewTaskActionParams: ''{0}''' -f (Out-String -InputObject $NewTaskActionParams))
150+
Write-Debug -Message '$NewTaskPrincipalParams = @{ UserId = ''NT AUTHORITY\SYSTEM''; RunLevel = ''Highest''; Id = ''Author''; LogonType = ''ServiceAccount'' }'
151+
152+
$NewTaskPrincipalParams = @{
153+
UserId = 'NT AUTHORITY\SYSTEM'
154+
RunLevel = 'Highest'
155+
Id = 'Author'
156+
LogonType = 'ServiceAccount'
147157
}
148158

149-
Write-Debug -Message ('$null = $RootFolder.RegisterTaskDefinition(''{0}'', $Task, 6, ''SYSTEM'', $null, 1)' -f $TaskName)
150-
$null = $RootFolder.RegisterTaskDefinition($TaskName, $Task, 6, 'SYSTEM', $null, 1)
151-
Write-Debug -Message ('$null = $RootFolder.GetTask(''{0}'').Run(0)' -f $TaskName)
152-
$null = $RootFolder.GetTask($TaskName).Run(0)
159+
Write-Debug -Message ('$NewTaskPrincipalParams: ''{0}''' -f (Out-String -InputObject $NewTaskPrincipalParams))
160+
Write-Debug -Message '$NewTaskSettingSetParams: @{ Compatibility = ''Win8''; MultipleInstances = ''IgnoreNew''; DontStopIfGoingOnBatteries = $true; StartWhenAvailable = $true }'
161+
162+
$NewTaskSettingSetParams = @{
163+
Compatibility = 'Win8'
164+
MultipleInstances = 'IgnoreNew'
165+
DontStopIfGoingOnBatteries = $true
166+
StartWhenAvailable = $true
167+
}
168+
169+
Write-Debug -Message ('$NewTaskSettingSetParams: ''{0}''' -f (Out-String -InputObject $NewTaskSettingSetParams))
170+
Write-Debug -Message ('$NewScheduledTaskParameters = @{{ Action = New-ScheduledTaskAction @NewTaskActionParams @RemoteCimsessionParams; Principal = New-ScheduledTaskPrincipal @NewTaskPrincipalParams @RemoteCimsessionParams; Settings = New-ScheduledTaskSettingsSet @NewTaskSettingSetParams @RemoteCimsessionParams; Description = ''{0}'' }}' -f $TaskDescription)
171+
172+
$NewScheduledTaskParameters = @{
173+
174+
Action = New-ScheduledTaskAction @NewTaskActionParams @RemoteCimsessionParams
175+
Principal = New-ScheduledTaskPrincipal @NewTaskPrincipalParams @RemoteCimsessionParams
176+
Settings = New-ScheduledTaskSettingsSet @NewTaskSettingSetParams @RemoteCimsessionParams
177+
Description = $TaskDescription
178+
}
179+
180+
Write-Debug -Message ('$NewScheduledTaskParameters: ''{0}''' -f (Out-String -InputObject $NewScheduledTaskParameters))
181+
182+
Write-Debug -Message 'New-ScheduledTask @NewScheduledTaskParameters @RemoteCimsessionParams'
183+
$ScheduledTask = New-ScheduledTask @NewScheduledTaskParameters @RemoteCimsessionParams
184+
Write-Debug -Message ('$ScheduledTask: ''{0}''' -f (Out-String -InputObject $ScheduledTask))
185+
186+
Write-Debug -Message ('$null = Register-ScheduledTask -TaskName ''{0}'' -TaskPath ''\'' -InputObject $ScheduledTask @RemoteCimsessionParams' -f $TaskName)
187+
$null = Register-ScheduledTask -TaskName $TaskName -TaskPath '\' -InputObject $ScheduledTask @RemoteCimsessionParams
188+
189+
Write-Debug -Message ('$RegisteredTask = Get-ScheduledTask -TaskName ''{0}'' -CimSession $RemoteCimSession' -f $TaskName)
190+
$RegisteredTask = Get-ScheduledTask -TaskName $TaskName -CimSession $RemoteCimSession
191+
Write-Debug -Message ('$RegisteredTask: ''{0}''' -f (Out-String -InputObject $RegisteredTask))
192+
193+
Write-Debug -Message 'Start-ScheduledTask -InputObject $RegisteredTask'
194+
Start-ScheduledTask -InputObject $RegisteredTask
153195

154196
Write-Debug -Message '$InitialDateTime = Get-Date'
155197
$InitialDateTime = Get-Date
156198
Write-Debug -Message ('$InitialDateTime: ''{0}''' -f [string]$InitialDateTime)
199+
Write-Debug -Message 'do while ($RunningTask)'
157200
do {
158201
Write-Debug -Message ('Start-Sleep -Seconds {0}' -f $Timeout)
159202
Start-Sleep -Seconds $Timeout
160203

161-
Write-Debug -Message ('$RunningTask = $Scheduler.GetRunningTasks(0) | Where-Object {{$_.Name -eq ''{0}''}}' -f $TaskName)
162-
$RunningTask = $Scheduler.GetRunningTasks(0) | Where-Object {$_.Name -eq $TaskName}
163-
Write-Debug -Message ('$RunningTask: {0}' -f [string]$RunningTask.Name)
204+
Write-Debug -Message ('$RunningTask = Get-ScheduledTask -TaskName ''{0}'' -CimSession $RemoteCimSession | Where-Object -FilterScript {{ $_.State.ToString() -eq ''{1}'' }}' -f $TaskName, $ScheduledTaskStateRunning)
205+
$RunningTask = Get-ScheduledTask -TaskName $TaskName -CimSession $RemoteCimSession | Where-Object -FilterScript { $_.State.ToString() -eq $ScheduledTaskStateRunning }
206+
Write-Debug -Message ('$RunningTask: {0}' -f (Out-String -InputObject $RunningTask))
207+
Write-Debug -Message 'if ($RunningTask)'
164208
if ($RunningTask) {
165209
Write-Debug -Message '$CurrentDateTime = Get-Date'
166210
$CurrentDateTime = Get-Date
@@ -179,6 +223,12 @@ function Invoke-WindowsUpdate {
179223
}
180224
while ($RunningTask)
181225

226+
Write-Debug -Message 'Unregister-ScheduledTask -InputObject $RegisteredTask -Confirm:$false'
227+
Unregister-ScheduledTask -InputObject $RegisteredTask -Confirm:$false
228+
229+
Write-Debug -Message '$RemoteCimSession.Close()'
230+
$RemoteCimSession.Close()
231+
182232
Write-Debug -Message ('EXIT TRY {0}' -f $MyInvocation.MyCommand.Name)
183233
}
184234
catch {

0 commit comments

Comments
 (0)