modules/deploy/dsc/ext/PsOrg/StackExchangeResources/DSCResources/StackExchange_ScheduledTask/StackExchange_ScheduledTask.psm1
function Get-TargetResource { [OutputType([Hashtable])] param ( [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Name, [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $FilePath, [parameter()] [string] $At = (Get-Date), [parameter()] [int] $Hours = 0, [parameter()] [int] $Minutes = 0, [parameter()] [bool] $Once = $false, [parameter()] [int] $DaysInterval, [parameter()] [bool] $Daily = $false, [parameter()] #[ValidateSet('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')] [string[]] $DaysOfWeek, [parameter()] [bool] $Weekly = $false, [parameter()] [System.Management.Automation.PSCredential] $Credential = [System.Management.Automation.PSCredential]::Empty, [ValidateSet('Present','Absent')] [string] $Ensure = 'Present' ) $Session = new-pssession -computername $env:computername -Credential $Credential -Authentication CredSSP $Job =Invoke-Command -Session $Session { Get-ScheduledJob -Name $Name -ErrorAction SilentlyContinue } #Needs to return a hashtable that returns the current #status of the configuration component $Configuration = @{ Name = $Name } if ($Job) { $Configuration.FilePath = $Job.Command if ($Job.JobTriggers[0].At.HasValue) { $Configuration.At = $job.JobTriggers[0].At.Value.ToString() } if ($Job.JobTriggers[0].RepetitionInterval.HasValue) { $Configuration.Hours = $Job.JobTriggers[0].RepetitionInterval.Value.Hours $Configuration.Minutes = $Job.JobTriggers[0].RepetitionInterval.Value.Minutes } if ( 'Once' -like $Job.JobTriggers[0].Frequency ) { $Configuration.Once = $true } else { $Configuration.Once = $false } if ( 'Daily' -like $Job.JobTriggers[0].Frequency ) { $Configuration.Daily = $true $Configuration.DaysInterval = $Job.JobTriggers[0].Interval } else { $Configuration.Daily = $false } if ( 'Weekly' -like $Job.JobTriggers[0].Frequency ) { $Configuration.Weekly = $true [string[]]$Configuration.DaysOfWeek = $job.JobTriggers[0].DaysOfWeek } else { $Configuration.Weekly = $false } $Configuration.Ensure = 'Present' } else { $Configuration.FilePath = $FilePath $Configuration.Ensure = 'Absent' } return $Configuration } function Set-TargetResource { param ( [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Name, [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $FilePath, [parameter()] [string] $At = (Get-Date), [parameter()] [int] $Hours = 0, [parameter()] [int] $Minutes = 0, [parameter()] [bool] $Once = $false, [parameter()] [int] $DaysInterval = 0, [parameter()] [bool] $Daily = $false, [parameter()] #[ValidateSet('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')] [string[]] $DaysOfWeek, [parameter()] [bool] $Weekly = $false, [parameter()] [System.Management.Automation.PSCredential] $Credential = [System.Management.Automation.PSCredential]::Empty, [ValidateSet('Present','Absent')] [string] $Ensure = 'Present' ) $Session = new-pssession -computername $env:computername -Credential $Credential $Job = Invoke-Command -Session $Session { Get-ScheduledJob -Name $Using:Name -ErrorAction SilentlyContinue } if ($Ensure -like 'Present') { $JobParameters = @{ Name = $Name FilePath = $FilePath #Credential = $credential MaxResultCount = 10 } $JobTriggerParameters = @{} $JobTriggerParameters.At = $At if ($Once) { $JobTriggerParameters.Once = $true if (($Hours -gt 0) -or ($Minutes -gt 0)) { $JobTriggerParameters.RepetitionInterval = New-TimeSpan -Hours $Hours -Minutes $Minutes $JobTriggerParameters.RepetitionDuration = [timespan]::MaxValue } } elseif ($Daily) { $JobTriggerParameters.Daily = $true if ($DaysInterval -gt 0) { $JobTriggerParameters.DaysInterval = $DaysInterval } } elseif ($Weekly) { $JobTriggerParameters.Weekly = $true if ($DaysOfWeek.count -gt 0) { $JobTriggerParameters.DaysOfWeek = $DaysOfWeek } } ### If the job exists, then remove it before adding again if ($Job) { #Jobber Clobber Invoke-Command -Session $Session {Unregister-ScheduledJob -Name $Using:Name} } Invoke-Command -Session $Session { #TODO: this seems like a hacky way to do splatting, but I don't know a better way to do it $jobParameters = $using:JobParameters $jobTriggerParameters = $using:JobTriggerParameters $jobParameters.Trigger = New-JobTrigger @jobTriggerParameters Register-ScheduledJob @jobParameters -ErrorAction SilentlyContinue } } else { Write-Verbose "Job $Name removed." } } function Test-TargetResource { [OutputType([boolean])] param ( [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Name, [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $FilePath, [parameter()] [string] $At = (Get-Date), [parameter()] [int] $Hours = 0, [parameter()] [int] $Minutes = 0, [parameter()] [bool] $Once = $false, [parameter()] [int] $DaysInterval, [parameter()] [bool] $Daily = $false, [parameter()] #[ValidateSet('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')] [string[]] $DaysOfWeek, [parameter()] [bool] $Weekly = $false, [parameter()] [System.Management.Automation.PSCredential] $Credential = [System.Management.Automation.PSCredential]::Empty, [ValidateSet('Present','Absent')] [string] $Ensure = 'Present' ) New-TargetResourceObject @psboundparameters if ($script:TargetResource.Ensure -like 'Present') { if ($script:TargetResource.Job) { Test-JobFilePath Test-JobTriggerAtTime Test-JobFrequency if ($script:TargetResource.Once) { Test-OnceJobTrigger } if ($script:TargetResource.Daily) { Test-DailyJobTrigger } if ($script:TargetResource.Weekly) { Test-WeeklyJobTrigger } } else { $script:TargetResource.IsValid = $false Write-Verbose "Unable to find matching job." } } else { if ($script:TargetResource.job) { $script:TargetResource.IsValid = $false Write-Verbose "Job should not be present, but is registered." } else { Write-Verbose "No job found and no job should be present." } } return $script:TargetResource.IsValid } $TargetResource = $null function New-TargetResourceObject { param ( [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Name, [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $FilePath, [parameter()] [string] $At = (Get-Date), [parameter()] [int] $Hours = 0, [parameter()] [int] $Minutes = 0, [parameter()] [bool] $Once = $false, [parameter()] [int] $DaysInterval, [parameter()] [bool] $Daily = $false, [parameter()] #[ValidateSet('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')] [string[]] $DaysOfWeek, [parameter()] [bool] $Weekly = $false, [parameter()] [System.Management.Automation.PSCredential] $Credential = [System.Management.Automation.PSCredential]::Empty, [ValidateSet('Present','Absent')] [string] $Ensure = 'Present' ) if (-not $psboundparameters.containskey('At')) { $psboundparameters.Add('At', $At) } if (-not $psboundparameters.containskey('Hours')) { $psboundparameters.Add('Hours', $Hours) } if (-not $psboundparameters.containskey('Minutes')) { $psboundparameters.Add('Minutes', $Minutes) } if (-not $psboundparameters.containskey('Once')) { $psboundparameters.Add('Once', $Once) } if (-not $psboundparameters.containskey('Daily')) { $psboundparameters.Add('Daily', $Daily) } if (-not $psboundparameters.containskey('Weekly')) { $psboundparameters.Add('Weekly', $Weekly) } $Job = Get-ScheduledJob -Name $Name -ErrorAction SilentlyContinue if ($Job) { $psboundparameters.Add('Job', $Job) } if (-not $psboundparameters.containskey('Ensure')) { $psboundparameters.Add('Ensure', $Ensure) } $psboundparameters.Add('IsValid', $true) $script:TargetResource = [pscustomobject]$psboundparameters } function Remove-Job { param ( [parameter()] [string] $Name, [parameter()] [System.Management.Automation.PSCredential] $Credential = [System.Management.Automation.PSCredential]::Empty ) $Session = new-pssession -computername $env:computername -Credential $Credential -Authentication CredSSP Invoke-Command -Session $Session { $Job = Get-ScheduledJob -Name $using:Name -ErrorAction SilentlyContinue if ($Job) { $job | Unregister-ScheduledJob -Force -Confirm:$False } } } function Test-JobFilePath { [cmdletbinding()] param () if ($script:TargetResource.IsValid) { Write-Verbose "Comparing $($script:TargetResource.FilePath) to $($script:TargetResource.Job.Command)" $script:TargetResource.IsValid = $script:TargetResource.FilePath -like $script:TargetResource.Job.Command } Write-Verbose "Checking Filepath against existing command. Status is $($script:TargetResource.IsValid)." } function Test-JobTriggerAtTime { [cmdletbinding()] param () $Trigger = $script:TargetResource.job.JobTriggers[0] if ($script:TargetResource.IsValid) { if ($Trigger.At.HasValue) { $script:TargetResource.IsValid = [datetime]::Parse($script:TargetResource.At) -eq $Trigger.At.Value } else { $script:TargetResource.IsValid = $False } } Write-Verbose "Checking Job Trigger At time. Status is $($script:TargetResource.IsValid)." } function Test-JobFrequency { [cmdletbinding()] param() $Frequency = $script:TargetResource.Job.JobTriggers[0].Frequency if ($script:TargetResource.Once) { $script:TargetResource.IsValid = 'Once' -like $Frequency } if ($script:TargetResource.Daily) { $script:TargetResource.IsValid = 'Daily' -like $Frequency } if ($script:TargetResource.Weekly) { $script:TargetResource.IsValid = 'Weekly' -like $Frequency } } function Test-OnceJobTrigger { [cmdletbinding()] param () $Trigger = $script:TargetResource.Job.JobTriggers[0] if ($script:TargetResource.IsValid -and $script:TargetResource.Once) { if ($Trigger.RepetitionInterval.HasValue) { $script:TargetResource.IsValid = $script:TargetResource.Hours -eq $Trigger.RepetitionInterval.Value.Hours $script:TargetResource.IsValid = $script:TargetResource.Minutes -eq $Trigger.RepetitionInterval.Value.Minutes } else { $script:TargetResource.IsValid = $false } } Write-Verbose "Checking Job Trigger repetition is set to Once. Status is $($script:TargetResource.IsValid)." } function Test-DailyJobTrigger { [cmdletbinding()] param () $Trigger = $script:TargetResource.Job.JobTriggers[0] if ($script:TargetResource.IsValid -and $script:TargetResource.Daily) { $script:TargetResource.IsValid = $script:TargetResource.DaysInterval -eq $Trigger.Interval } Write-Verbose "Checking Job Trigger repetition is set to Daily. Status is $($script:TargetResource.IsValid)." } function Test-WeeklyJobTrigger { [cmdletbinding()] param() $Trigger = $script:TargetResource.Job.JobTriggers[0] if ($script:TargetResource.IsValid -and $script:TargetResource.Weekly) { Test-DaysOfWeekInWeeklyJobTrigger } Write-Verbose "Checking Job Trigger repetition is set to Weekly. Status is $($script:TargetResource.IsValid)." } function Test-DaysOfWeekInWeeklyJobTrigger { [cmdletbinding()] param() if ( $script:TargetResource.DaysOfWeek.Count -eq $Trigger.DaysOfWeek.count ){ if ($script:TargetResource.DaysOfWeek.count -gt 0) { foreach ($day in $Trigger.DaysOfWeek) { if (-not $script:TargetResource.IsValid) { break } $script:TargetResource.IsValid = ($script:TargetResource.DaysOfWeek -contains $day) } } } else { $script:TargetResource.IsValid = $false } } |