|
| 1 | +function Get-TargetResource |
| 2 | +{ |
| 3 | + [OutputType([System.Collections.Hashtable])] |
| 4 | + param |
| 5 | + ( |
| 6 | + [Parameter(Mandatory=$true)] |
| 7 | + [System.String] |
| 8 | + $TaskName, |
| 9 | + |
| 10 | + [Parameter(Mandatory=$false)] |
| 11 | + [System.String] |
| 12 | + $TaskPath = "\", |
| 13 | + |
| 14 | + [Parameter(Mandatory=$true)] |
| 15 | + [System.String] |
| 16 | + $ActionExecutable, |
| 17 | + |
| 18 | + [Parameter(Mandatory=$false)] |
| 19 | + [System.String] |
| 20 | + $ActionArguments, |
| 21 | + |
| 22 | + [Parameter(Mandatory=$false)] |
| 23 | + [System.String] |
| 24 | + $ActionWorkingPath, |
| 25 | + |
| 26 | + [Parameter(Mandatory=$true)] |
| 27 | + [System.String] |
| 28 | + [ValidateSet("Minutes", "Hourly", "Daily")] $ScheduleType, |
| 29 | + |
| 30 | + [Parameter(Mandatory=$true)] |
| 31 | + [System.UInt32] |
| 32 | + $RepeatInterval, |
| 33 | + |
| 34 | + [Parameter(Mandatory=$false)] |
| 35 | + [System.String] |
| 36 | + $StartTime = "12:00 AM", |
| 37 | + |
| 38 | + [Parameter(Mandatory=$false)] |
| 39 | + [System.String] |
| 40 | + [ValidateSet("Present","Absent")] |
| 41 | + $Ensure = "Present", |
| 42 | + |
| 43 | + [Parameter(Mandatory=$false)] |
| 44 | + [System.Management.Automation.PSCredential] |
| 45 | + $ExecuteAsCredential |
| 46 | + ) |
| 47 | + $task = Get-ScheduledTask -TaskName $TaskName -TaskPath $TaskPath -ErrorAction SilentlyContinue |
| 48 | + |
| 49 | + if ($null -eq $task) |
| 50 | + { |
| 51 | + return @{ |
| 52 | + TaskName = $TaskName |
| 53 | + TaskPath = $TaskPath |
| 54 | + Ensure = "Absent" |
| 55 | + TriggerType = "Unknown" |
| 56 | + } |
| 57 | + } |
| 58 | + else |
| 59 | + { |
| 60 | + $action = $task.Actions | Select -First 1 |
| 61 | + $trigger = $task.Triggers | Select -First 1 |
| 62 | + $repetition = $trigger.Repetition |
| 63 | + $returnScheduleType = "Unknown" |
| 64 | + $returnInveral = 0 |
| 65 | + |
| 66 | + # Check for full formatting |
| 67 | + if ($repetition.Interval -like "P*DT*H*M*S") |
| 68 | + { |
| 69 | + $timespan = [Timespan]::Parse(($repetition.Interval -replace "P" -replace "DT", ":" -replace "H", ":" -replace "M", ":" -replace "S")) |
| 70 | + |
| 71 | + if ($timespan.Days -ge 1) |
| 72 | + { |
| 73 | + $returnScheduleType = "Daily" |
| 74 | + $returnInveral = $timespan.TotalDays |
| 75 | + } |
| 76 | + elseif ($timespan.Hours -ge 1 -and $timespan.Minutes -eq 0) |
| 77 | + { |
| 78 | + $returnScheduleType = "Hourly" |
| 79 | + $returnInveral = $timespan.TotalHours |
| 80 | + } |
| 81 | + elseif ($timespan.Minutes -ge 1) |
| 82 | + { |
| 83 | + $returnScheduleType = "Minutes" |
| 84 | + $returnInveral = $timespan.TotalMinutes |
| 85 | + } |
| 86 | + } |
| 87 | + else |
| 88 | + { |
| 89 | + if ($repetition.Duration -eq $null -and $repetition.Interval -eq $null) |
| 90 | + { |
| 91 | + $returnScheduleType = "Daily" |
| 92 | + $returnInveral = $trigger.DaysInterval |
| 93 | + } |
| 94 | + if ($repetition.Duration -eq $null -and $repetition.Interval -like "P*D") |
| 95 | + { |
| 96 | + $returnScheduleType = "Daily" |
| 97 | + [System.Uint32]$returnInveral = $repetition.Interval -replace "P" -replace "D" |
| 98 | + } |
| 99 | + if (($repetition.Duration -eq "P1D" -or $repetition.Duration -eq $null) ` |
| 100 | + -and $repetition.Interval -like "PT*H") |
| 101 | + { |
| 102 | + $returnScheduleType = "Hourly" |
| 103 | + [System.Uint32]$returnInveral = $repetition.Interval -replace "PT" -replace "H" |
| 104 | + } |
| 105 | + if (($repetition.Duration -eq "P1D" -or $repetition.Duration -eq $null) ` |
| 106 | + -and $repetition.Interval -like "PT*M") |
| 107 | + { |
| 108 | + $returnScheduleType = "Minutes" |
| 109 | + if ($repetition.Interval.Contains('H')) |
| 110 | + { |
| 111 | + $timeToParse = ($repetition.Interval -replace "PT" -replace "H",":" -replace "M") |
| 112 | + [System.Uint32]$returnInveral = [TimeSpan]::Parse($timeToParse).TotalMinutes |
| 113 | + } |
| 114 | + else |
| 115 | + { |
| 116 | + [System.Uint32]$returnInveral = $repetition.Interval -replace "PT" -replace "M" |
| 117 | + } |
| 118 | + } |
| 119 | + } |
| 120 | + |
| 121 | + return @{ |
| 122 | + TaskName = $TaskName |
| 123 | + TaskPath = $TaskPath |
| 124 | + Ensure = "Present" |
| 125 | + ActionExecutable = $action.Execute |
| 126 | + ActionArguments = $action.Arguments |
| 127 | + ActionWorkingPath = $action.WorkingDirectory |
| 128 | + ScheduleType = $returnScheduleType |
| 129 | + RepeatInterval = $returnInveral |
| 130 | + ExecuteAsCredential = $task.Principal.UserId |
| 131 | + } |
| 132 | + } |
| 133 | +} |
| 134 | + |
| 135 | +function Set-TargetResource |
| 136 | +{ |
| 137 | + param |
| 138 | + ( |
| 139 | + [Parameter(Mandatory=$true)] |
| 140 | + [System.String] |
| 141 | + $TaskName, |
| 142 | + |
| 143 | + [Parameter(Mandatory=$false)] |
| 144 | + [System.String] |
| 145 | + $TaskPath = "\", |
| 146 | + |
| 147 | + [Parameter(Mandatory=$true)] |
| 148 | + [System.String] |
| 149 | + $ActionExecutable, |
| 150 | + |
| 151 | + [Parameter(Mandatory=$false)] |
| 152 | + [System.String] |
| 153 | + $ActionArguments, |
| 154 | + |
| 155 | + [Parameter(Mandatory=$false)] |
| 156 | + [System.String] |
| 157 | + $ActionWorkingPath, |
| 158 | + |
| 159 | + [Parameter(Mandatory=$true)] |
| 160 | + [System.String] |
| 161 | + [ValidateSet("Minutes", "Hourly", "Daily")] $ScheduleType, |
| 162 | + |
| 163 | + [Parameter(Mandatory=$true)] |
| 164 | + [System.UInt32] |
| 165 | + $RepeatInterval, |
| 166 | + |
| 167 | + [Parameter(Mandatory=$false)] |
| 168 | + [System.String] |
| 169 | + $StartTime = "12:00 AM", |
| 170 | + |
| 171 | + [Parameter(Mandatory=$false)] |
| 172 | + [System.String] |
| 173 | + [ValidateSet("Present","Absent")] |
| 174 | + $Ensure = "Present", |
| 175 | + |
| 176 | + [Parameter(Mandatory=$false)] |
| 177 | + [System.Management.Automation.PSCredential] |
| 178 | + $ExecuteAsCredential |
| 179 | + ) |
| 180 | + |
| 181 | + $currentValues = Get-TargetResource @PSBoundParameters |
| 182 | + |
| 183 | + if ($Ensure -eq "Present") |
| 184 | + { |
| 185 | + $actionArgs = @{ |
| 186 | + Execute = $ActionExecutable |
| 187 | + } |
| 188 | + if ($PSBoundParameters.ContainsKey("ActionArguments")) |
| 189 | + { |
| 190 | + $actionArgs.Add("Argument", $ActionArguments) |
| 191 | + } |
| 192 | + if ($PSBoundParameters.ContainsKey("ActionWorkingPath")) |
| 193 | + { |
| 194 | + $actionArgs.Add("WorkingDirectory", $ActionWorkingPath) |
| 195 | + } |
| 196 | + $action = New-ScheduledTaskAction @actionArgs |
| 197 | + |
| 198 | + $date = (Get-Date).Date |
| 199 | + $startTime = [DateTime]::Parse("$($date.ToShortDateString()) $StartTime") |
| 200 | + switch ($ScheduleType) |
| 201 | + { |
| 202 | + "Minutes" |
| 203 | + { |
| 204 | + $repeatAt = New-TimeSpan -Minutes $RepeatInterval |
| 205 | + } |
| 206 | + "Hourly" |
| 207 | + { |
| 208 | + $repeatAt = New-TimeSpan -Hours $RepeatInterval |
| 209 | + } |
| 210 | + "Daily" |
| 211 | + { |
| 212 | + $repeatAt = New-TimeSpan -Days $RepeatInterval |
| 213 | + } |
| 214 | + } |
| 215 | + try |
| 216 | + { |
| 217 | + $trigger = New-ScheduledTaskTrigger -Once -At $startTime ` |
| 218 | + -RepetitionInterval $repeatAt |
| 219 | + } |
| 220 | + catch |
| 221 | + { |
| 222 | + $trigger = New-ScheduledTaskTrigger -Once -At $startTime ` |
| 223 | + -RepetitionInterval $repeatAt ` |
| 224 | + -RepetitionDuration ([TimeSpan]::MaxValue) |
| 225 | + } |
| 226 | + |
| 227 | + if ($currentValues.Ensure -eq "Absent") |
| 228 | + { |
| 229 | + Write-Verbose -Message "Creating new scheduled task `"$TaskName`"" |
| 230 | + |
| 231 | + $scheduledTask = New-ScheduledTask -Action $action -Trigger $trigger |
| 232 | + $registerArgs = @{ |
| 233 | + TaskName = $TaskName |
| 234 | + TaskPath = $TaskPath |
| 235 | + InputObject = $scheduledTask |
| 236 | + } |
| 237 | + if ($PSBoundParameters.ContainsKey("ExecuteAsCredential") -eq $true) |
| 238 | + { |
| 239 | + $registerArgs.Add("User", $ExecuteAsCredential.UserName) |
| 240 | + $registerArgs.Add("Password", $ExecuteAsCredential.GetNetworkCredential().Password) |
| 241 | + } |
| 242 | + else |
| 243 | + { |
| 244 | + $registerArgs.Add("User", "NT AUTHORITY\SYSTEM") |
| 245 | + } |
| 246 | + Register-ScheduledTask @registerArgs |
| 247 | + } |
| 248 | + if ($currentValues.Ensure -eq "Present") |
| 249 | + { |
| 250 | + Write-Verbose -Message "Updating scheduled task `"$TaskName`"" |
| 251 | + |
| 252 | + $setArgs = @{ |
| 253 | + TaskName = $TaskName |
| 254 | + TaskPath = $TaskPath |
| 255 | + Action= $action |
| 256 | + Trigger = $trigger |
| 257 | + } |
| 258 | + if ($PSBoundParameters.ContainsKey("ExecuteAsCredential") -eq $true) |
| 259 | + { |
| 260 | + $setArgs.Add("User", $ExecuteAsCredential.UserName) |
| 261 | + $setArgs.Add("Password", $ExecuteAsCredential.GetNetworkCredential().Password) |
| 262 | + } |
| 263 | + else |
| 264 | + { |
| 265 | + $setArgs.Add("User", "NT AUTHORITY\SYSTEM") |
| 266 | + } |
| 267 | + Set-ScheduledTask @setArgs |
| 268 | + } |
| 269 | + } |
| 270 | + |
| 271 | + if ($Ensure -eq "Absent") |
| 272 | + { |
| 273 | + Write-Verbose -Message "Removing scheduled task `"$TaskName`"" |
| 274 | + Unregister-ScheduledTask -TaskName $TaskName -TaskPath $TaskPath -Confirm:$false |
| 275 | + } |
| 276 | +} |
| 277 | + |
| 278 | +function Test-TargetResource |
| 279 | +{ |
| 280 | + [OutputType([System.Boolean])] |
| 281 | + param |
| 282 | + ( |
| 283 | + [Parameter(Mandatory=$true)] |
| 284 | + [System.String] |
| 285 | + $TaskName, |
| 286 | + |
| 287 | + [Parameter(Mandatory=$false)] |
| 288 | + [System.String] |
| 289 | + $TaskPath = "\", |
| 290 | + |
| 291 | + [Parameter(Mandatory=$true)] |
| 292 | + [System.String] |
| 293 | + $ActionExecutable, |
| 294 | + |
| 295 | + [Parameter(Mandatory=$false)] |
| 296 | + [System.String] |
| 297 | + $ActionArguments, |
| 298 | + |
| 299 | + [Parameter(Mandatory=$false)] |
| 300 | + [System.String] |
| 301 | + $ActionWorkingPath, |
| 302 | + |
| 303 | + [Parameter(Mandatory=$true)] |
| 304 | + [System.String] |
| 305 | + [ValidateSet("Minutes", "Hourly", "Daily")] $ScheduleType, |
| 306 | + |
| 307 | + [Parameter(Mandatory=$true)] |
| 308 | + [System.UInt32] |
| 309 | + $RepeatInterval, |
| 310 | + |
| 311 | + [Parameter(Mandatory=$false)] |
| 312 | + [System.String] |
| 313 | + $StartTime = "12:00 AM", |
| 314 | + |
| 315 | + [Parameter(Mandatory=$false)] |
| 316 | + [System.String] |
| 317 | + [ValidateSet("Present","Absent")] |
| 318 | + $Ensure = "Present", |
| 319 | + |
| 320 | + [Parameter(Mandatory=$false)] |
| 321 | + [System.Management.Automation.PSCredential] |
| 322 | + $ExecuteAsCredential |
| 323 | + ) |
| 324 | + |
| 325 | + $currentValues = Get-TargetResource @PSBoundParameters |
| 326 | + if ($Ensure -ne $currentValues.Ensure) |
| 327 | + { |
| 328 | + return $false |
| 329 | + } |
| 330 | + if ($Ensure -eq "Present") |
| 331 | + { |
| 332 | + if ($TaskPath -ne $currentValues.TaskPath) |
| 333 | + { |
| 334 | + Write-Verbose -Message "TaskPath does not match desired state. Current value: $($currentValues.TaskPath) - Desired Value: $TaskPath" |
| 335 | + return $false |
| 336 | + } |
| 337 | + if ($ActionExecutable -ne $currentValues.ActionExecutable) |
| 338 | + { |
| 339 | + Write-Verbose -Message "ActionExecutable does not match desired state. Current value: $($currentValues.ActionExecutable) - Desired Value: $ActionExecutable" |
| 340 | + return $false |
| 341 | + } |
| 342 | + if (($PSBoundParameters.ContainsKey("ActionArguments") -eq $true) ` |
| 343 | + -and ($ActionArguments -ne $currentValues.ActionArguments)) |
| 344 | + { |
| 345 | + Write-Verbose -Message "ActionArguments does not match desired state. Current value: $($currentValues.ActionArguments) - Desired Value: $ActionArguments" |
| 346 | + return $false |
| 347 | + } |
| 348 | + if (($PSBoundParameters.ContainsKey("ActionWorkingPath") -eq $true) ` |
| 349 | + -and ($ActionWorkingPath -ne $currentValues.ActionWorkingPath)) |
| 350 | + { |
| 351 | + Write-Verbose -Message "ActionWorkingPath does not match desired state. Current value: $($currentValues.ActionWorkingPath) - Desired Value: $ActionWorkingPath" |
| 352 | + return $false |
| 353 | + } |
| 354 | + if ($ScheduleType -ne $currentValues.ScheduleType) |
| 355 | + { |
| 356 | + Write-Verbose -Message "ScheduleType does not match desired state. Current value: $($currentValues.ScheduleType) - Desired Value: $ScheduleType" |
| 357 | + return $false |
| 358 | + } |
| 359 | + if ($RepeatInterval -ne $currentValues.RepeatInterval) |
| 360 | + { |
| 361 | + Write-Verbose -Message "RepeatInterval does not match desired state. Current value: $($currentValues.RepeatInterval) - Desired Value: $RepeatInterval" |
| 362 | + return $false |
| 363 | + } |
| 364 | + |
| 365 | + if ($PSBoundParameters.ContainsKey("ExecuteAsCredential") -eq $true) |
| 366 | + { |
| 367 | + if ($ExecuteAsCredential.UserName -ne $currentValues.ExecuteAsCredential) |
| 368 | + { |
| 369 | + Write-Verbose -Message "ExecuteAsCredential does not match desired state. Current value: $($currentValues.ExecuteAsCredential) - Desired Value: $localUser" |
| 370 | + return $false |
| 371 | + } |
| 372 | + } |
| 373 | + } |
| 374 | + |
| 375 | + return $true |
| 376 | +} |
0 commit comments