DSCResources/xScheduledTask/xScheduledTask.psm1
#region TestTaskAction Function TestTaskAction { [OutputType([bool])] #region parameter param ( [ciminstance[]]$Action, $TaskInstance ) #endregion [bool]$Result = $True; Write-Verbose -Message ("Found action count "+ $Action.Count); foreach($item in $Action) { $hasvalue = $item.CimInstanceProperties.where({$_.IsValueModified -eq $True}) $Action_Sys = $TaskInstance.Actions.where({$_.Execute -eq $item.Execute}) if($Action_Sys) { Write-Verbose -Message ("found action $($item.Execute)"); $Re = CimComparator -CimObjects $hasvalue -Source $Action_Sys if(!$Re) { $Result = $false } } else { Write-Verbose -Message ("can not found action $($item.Execute)"); $Result =$false; } } return $Result; } #endregion #region TestTaskUserPrincipal Function TestTaskUserPrincipal { [OutputType([bool])] param ( [ciminstance]$UserPrincipal, $TaskInstance ) [bool]$Result = $True; Write-Verbose -Message ("Found UserPrincipal count "+ @($UserPrincipal).Count); $hasvalue = $UserPrincipal.CimInstanceProperties.where({$_.IsValueModified -eq $True}) $Re = CimComparator -Source $TaskInstance.Principal -CimObjects $hasvalue if(!$Re) { $Result = $false } $Result } #endregion #region TestTaskGroupPrincipal Function TestTaskGroupPrincipal { [outputtype([bool])] param ( [ciminstance]$GroupPrincipal, $TaskInstance ) [bool]$Result = $True; Write-Verbose -Message ("Found GroupPrincipal count "+ @($GroupPrincipal).Count); $hasvalue = $GroupPrincipal.CimInstanceProperties.where({$_.IsValueModified -eq $True}) $Re = CimComparator -CimObjects $hasvalue -Source $TaskInstance.Principal if(!$Re) { $Result = $false } $Result } #endregion #region TestTaskSettingsSet Function TestTaskSettingsSet { param ( [ciminstance]$SettingsSet, $TaskInstance ) [bool]$Result = $True; Write-Verbose -Message ("Found SettingsSet count "+ @($SettingsSet).Count); $hasvalue = $SettingsSet.CimInstanceProperties.where({($_.IsValueModified -eq $True) -and $_.CimType -ne "Instance"}) $Re = CimComparator -CimObjects $hasvalue -Source $TaskInstance.Settings if(!$Re) { $Result = $false } $input_idle = $SettingsSet.CimInstanceProperties.where({($_.IsValueModified -eq $True) -and ($_.CimType -eq "Instance")}).Value.CimInstanceProperties.where({($_.IsValueModified -eq $True)}) $Re = CimComparator -CimObjects $input_idle -Source $TaskInstance.Settings.IdleSettings Write-Verbose -Message ("Testing Task IdleSetting"); if(!$Re) { $Result = $false } Write-Verbose -Message ("Testing Task IdleSetting $Result"); $Result } #endregion #region TestTaskNetworkSetting Function TestTaskNetworkSetting { param ( [ciminstance]$NetworkSetting, $TaskInstance ) [bool]$Result = $True; Write-Verbose -Message ("Found NetworkSetting count "+ @($NetworkSetting).Count); $hasvalue = $NetworkSetting.CimInstanceProperties.where({$_.IsValueModified -eq $True}) $Re =CimComparator -CimObjects $hasvalue -Source $TaskInstance.Settings.NetworkSettings if(!$Re) { $Result = $false } $Result } #endregion #region TestIdleSetting Function TestIdleSetting { param ( [ciminstance]$IdleSetting, $TaskInstance ) [bool]$Result = $True; Write-Verbose -Message ("Found IdleSetting count "+ @($IdleSetting).Count); $hasvalue = $IdleSetting.CimInstanceProperties.where({$_.IsValueModified -eq $True}) $Re = CimComparator -Source $TaskInstance.Settings.IdleSettings -CimObjects $hasvalue if(!$Re) { $Result = $false } $Result } #endregion #region TestTaskTriggers Function TestTaskTriggers { param ( [ciminstance[]]$TaskTriggers, $TaskInstance ) [bool]$Result = $True; Write-Verbose -Message ("Found TestTaskTriggers count "+ ($TaskTriggers).Count); foreach($item in $TaskTriggers) { $hasvalue = $item.CimInstanceProperties.where({($_.IsValueModified -eq $True) -and ($_.CimType -ne "Instance")}) ## not incloud ciminstance $Input_WithID_in_Sys = $TaskInstance.Triggers.where({$_.Id -eq $item.ID}) if(!$Input_WithID_in_Sys) { $Result = $false; Write-Verbose -Message ("Find Trigger at ID $($item.ID) $false") } else { Write-Verbose -Message ("Find Trigger at ID $($item.ID) $true") $Re = CimComparator -Source $Input_WithID_in_Sys -CimObjects $hasvalue if(!$Re) { $Result = $false } if($item.TaskRepetition) { $Cim_Repetition=$item.TaskRepetition.CimInstanceProperties.where({$_.IsValueModified -eq $True}) $Re= CimComparator -Source $Input_WithID_in_Sys.Repetition -CimObjects $Cim_Repetition if(!$Re) { $Result = $false } } } } $Result; } #endregion #region CimSet Function CimSet { param ( [Object]$Source, [object[]]$CimObjects ) foreach($Cimobj in $CimObjects) { Write-Verbose -Message ("Set property at $($Cimobj.name) to $($Cimobj.value)") $Source.($Cimobj.Name) = $Cimobj.value } } #endregion #region CimComparator Function CimComparator { param ( [object]$Source, [object[]]$CimObjects ) $Result =$true foreach($Cimobj in $CimObjects) { if($Source.($Cimobj.Name) -eq ($Cimobj.Value)) { #Write-Verbose -Message ("Testting with $($Cimobj.name) $($Cimobj.value)"+" Match"); } else { Write-Verbose -Message ("Testting with $($Cimobj.name) $($Cimobj.value)"+" Not Match"); $Result =$false } } $Result; } #endregion #region Cim2Hashtable Function Cim2Hashtable { param ( [object[]]$Cim, [switch]$Build ) $has = @{} if($Build) { foreach($item in $Cim) { $has.Add( $item.Name , ( ($item.Value) -as ([System.Type]::GetType("System.$($item.CimType)")) )) } } else { $Cim.foreach({$has.add($_.name,$_.value)}) } $has } #endregion #region Set-TargetResource Function Set-TargetResource { param ( [parameter(Mandatory= $true)] [string]$Name, [parameter(Mandatory= $true)] [string]$Path, [parameter(Mandatory= $false)] [ciminstance[]]$TaskAction, [parameter(Mandatory= $false)] [ciminstance]$TaskUserPrincipal, [parameter(Mandatory= $false)] [ciminstance]$TaskGroupPrincipal, [parameter(Mandatory= $false)] [ciminstance]$TaskSettingsSet, [parameter(Mandatory= $false)] [ciminstance]$NetworkSetting, [parameter(Mandatory= $false)] [ciminstance[]]$TaskTriggers # for version 4.0 #[parameter(Mandatory= $false)] #[ciminstance]$IdleSetting, ) $New_Task_Parameter = @{} $Task = Get-ScheduledTask -TaskName $Name -TaskPath $Path -ErrorAction SilentlyContinue #region new task if($Task) { Unregister-ScheduledTask -TaskName $Name -TaskPath $Path -Confirm:$false $Task = $null; } #endregion #region action if($TaskAction) { $New_CIM_Actions = @() foreach($item in $TaskAction) { $InputValue = $item.CimInstanceProperties.where({$_.IsValueModified -eq $True}) Write-Verbose -Message ("Add Action with Execute $($item.Execute)") $New_CIM_Action = New-ScheduledTaskAction -Execute $item.Execute CimSet -CimObjects $InputValue -Source $New_CIM_Action $New_CIM_Actions+= $New_CIM_Action } ##### build hash parameterbinds $New_Task_Parameter.Add("Action",$New_CIM_Actions) } #endregion #region group if($TaskGroupPrincipal) { $New_CIM_GroupPrincipal = New-ScheduledTaskPrincipal -GroupId $TaskGroupPrincipal.GroupID Write-Verbose -Message ("Add GroupPrincipal with GroupId $($TaskGroupPrincipal.GroupID)") $InputValue = $TaskGroupPrincipal.CimInstanceProperties.where({$_.IsValueModified -eq $True}) CimSet -CimObjects $InputValue -Source $New_CIM_GroupPrincipal $New_Task_Parameter.Add("Principal",$New_CIM_GroupPrincipal) } #endregion #region user if($TaskUserPrincipal) { $New_CIM_UserPrincipal = New-ScheduledTaskPrincipal -UserId $TaskUserPrincipal.UserID $InputValue = $TaskUserPrincipal.CimInstanceProperties.where({$_.IsValueModified -eq $True}) Write-Verbose -Message ("Add UserPrincipal with UserID $($TaskUserPrincipal.UserID)") CimSet -CimObjects $InputValue -Source $New_CIM_UserPrincipal $New_Task_Parameter.Add("Principal",$New_CIM_UserPrincipal) } #endregion #region setting if($TaskSettingsSet) { Write-Verbose -Message ("Add SettingsSet") $New_CIM_SettingsSet=New-ScheduledTaskSettingsSet $InputValue = $TaskSettingsSet.CimInstanceProperties.where({($_.IsValueModified -eq $True)-and ($_.CimType -ne "Instance")}) CimSet -CimObjects $InputValue -Source $New_CIM_SettingsSet $New_Task_Parameter.Add("Settings",$New_CIM_SettingsSet) #region idle $Input_IdleSetting = $TaskSettingsSet.CimInstanceProperties.where({($_.IsValueModified -eq $True)-and ($_.CimType -eq "Instance")}).value.CimInstanceProperties.where({($_.IsValueModified -eq $True)}) if($Input_IdleSetting) { Write-Verbose -Message ("Add IdleSetting") CimSet -CimObjects $Input_IdleSetting -Source $New_CIM_SettingsSet.IdleSettings } #endregion } #endregion #region network if($NetworkSetting) { Write-Verbose -Message ("Add NetworkSetting") $InputValue = $NetworkSetting.CimInstanceProperties.where({$_.IsValueModified -eq $True}) CimSet -CimObjects $InputValue -Source $New_CIM_SettingsSet.NetworkSettings } #endregion #region Trigger if($TaskTriggers) { $New_CIM_Triggers = @() foreach($item in $TaskTriggers) { Write-Verbose -Message ("Add TaskTrigger") $New_CIM_Trigger = $null $hasvalue = $item.CimInstanceProperties.where({($_.IsValueModified -eq $True) -and ($_.CimType -ne "Instance")}) ## not incloud ciminstance $Input_Repetition = $item.CimInstanceProperties.where({($_.IsValueModified -eq $True) -and ($_.CimType -eq "Instance")}).Value.CimInstanceProperties.where({($_.IsValueModified -eq $True)}) if($item.DaysInterval) { $New_CIM_Trigger = New-ScheduledTaskTrigger -At $item.StartBoundary -Daily -DaysInterval $item.DaysInterval CimSet -CimObjects $hasvalue -Source $New_CIM_Trigger } if($item.WeeksInterval) { $New_CIM_Trigger = New-ScheduledTaskTrigger -At $item.StartBoundary -Weekly -WeeksInterval $item.WeeksInterval -DaysOfWeek Friday CimSet -CimObjects $hasvalue -Source $New_CIM_Trigger } if($item.StateChange) { #$New_CIM_Trigger= New-CimInstance -Namespace "Root/Microsoft/Windows/TaskScheduler" -ClassName "MSFT_TaskSessionStateChangeTrigger" -ClientOnly -Property (Cim2Hashtable -Cim $hasvalue) } if($Input_Repetition) { #$h =@{} #$Input_Repetition.foreach({$h.add($_.name,$_.value)}) $New_CIM_Trigger.Repetition =New-CimInstance -Namespace "Root/Microsoft/Windows/TaskScheduler" -ClassName "MSFT_TaskRepetitionPattern" -ClientOnly -Property (Cim2Hashtable -Cim $Input_Repetition) } $New_CIM_Triggers += $New_CIM_Trigger } $New_Task_Parameter.Add("Trigger",$New_CIM_Triggers) } #endregion Write-Verbose -Message ("Add Task") $Task = New-ScheduledTask @New_Task_Parameter Register-ScheduledTask -InputObject $Task -TaskName $Name -TaskPath $Path } #endregion #region Get-TargetResource Function Get-TargetResource { [outputtype([hashtable])] param ( [parameter(Mandatory= $true)] [string]$Name, [parameter(Mandatory= $true)] [string]$Path ) [hashtable]$Result = @{} $Result.Add("Name",$Name) $Result.Add("Path",$Path) $actions = @() $Task = Get-ScheduledTask -TaskName $Name -TaskPath $Path -ErrorAction SilentlyContinue if($Task) { foreach($item in $Task.Actions) {#'root/microsoft/Windows/DesiredStateConfiguration' $CimProperty =@{} $CimProperty.Add("Execute",$item.Execute) $CimProperty.Add("Arguments",$item.Arguments) $CimProperty.Add("WorkingDirectory",$item.WorkingDirectory) $CimProperty.Add("ID",$item.ID) $actions +=$CimProperty } $Result.Add("TaskAction",$actions); if($Task.Principal.UserID) { [hashtable]$User = @{} $User.Add("UserID",$Task.Principal.UserId) $User.Add("LogonType",$Task.Principal.LogonType.tostring()) $User.Add("Id",$Task.Principal.Id) $User.Add("RunLevel",$Task.Principal.RunLevel.tostring()) $User.Add("ProcessTokenSidType",$Task.Principal.ProcessTokenSidType.tostring()) $User.Add("RequiredPrivilege",$Task.Principal.RequiredPrivilege) $Result.Add("TaskUserPrincipal",($User)) } if($Task.Principal.GroupId) { [hashtable]$Group = @{} $Group.Add("GroupId",$Task.Principal.GroupId) $Group.Add("Id",$Task.Principal.Id) $Group.Add("RunLevel",$Task.Principal.RunLevel.tostring()) $Group.Add("ProcessTokenSidType",$Task.Principal.ProcessTokenSidType.tostring()) $Group.Add("RequiredPrivilege",$Task.Principal.RequiredPrivilege) $Result.Add("TaskGroupPrincipal",($Group)) } #region setting $Setting = @{} $Setting.Add("AllowDemandStart",[bool]$Task.Settings.AllowDemandStart) $Setting.Add("AllowHardTerminate",[bool]$Task.Settings.AllowHardTerminate) $Setting.Add("Compatibility",$Task.Settings.Compatibility.tostring()) $Setting.Add("DeleteExpiredTaskAfter",[string]$Task.Settings.DeleteExpiredTaskAfter) $Setting.Add("DisallowStartIfOnBatteries",[bool]$Task.Settings.DisallowStartIfOnBatteries) $Setting.Add("Enabled",[bool]$Task.Settings.Enabled) $Setting.Add("ExecutionTimeLimit",$Task.Settings.ExecutionTimeLimit) $Setting.Add("Hidden",[bool]$Task.Settings.Hidden) $Setting.Add("MultipleInstances",$Task.Settings.MultipleInstances.tostring()) $Setting.Add("Priority",[string]$Task.Settings.Priority) $Setting.Add("RestartCount",[string]$Task.Settings.RestartCount) $Setting.Add("RestartInterval",[string]$Task.Settings.RestartInterval) $Setting.Add("RunOnlyIfIdle",[bool]$Task.Settings.RunOnlyIfIdle) $Setting.Add("RunOnlyIfNetworkAvailable",[bool]$Task.Settings.RunOnlyIfNetworkAvailable) $Setting.Add("StartWhenAvailable",[bool]$Task.Settings.StartWhenAvailable) $Setting.Add("StopIfGoingOnBatteries",[bool]$Task.Settings.StopIfGoingOnBatteries) $Setting.Add("WakeToRun",[bool]$Task.Settings.WakeToRun) $Setting.Add("DisallowStartOnRemoteAppSession",[bool]$Task.Settings.DisallowStartOnRemoteAppSession) $Setting.Add("UseUnifiedSchedulingEngine",[bool]$Task.Settings.UseUnifiedSchedulingEngine) $Setting.Add("volatile",[bool]$Task.Settings.volatile) #region idle [hashtable]$Idle = @{} $Idle.Add("IdleDuration",[String]$Task.Settings.IdleSettings.IdleDuration) $Idle.Add("RestartOnIdle",[bool]$Task.Settings.IdleSettings.RestartOnIdle) $Idle.Add("StopOnIdleEnd",[bool]$Task.Settings.IdleSettings.StopOnIdleEnd) $Idle.Add("WaitTimeout",[String]$Task.Settings.IdleSettings.WaitTimeout) $Idle_CIM= New-CimInstance -Namespace 'root/microsoft/Windows/DesiredStateConfiguration' -ClassName IdleSetting -Property $Idle -ClientOnly $Setting.Add("IdleSetting",($Idle_CIM)) #endregion $Result.Add("TaskSettingsSet",($Setting)) #endregion #region NetworkSetting $Network = @{} $Network.Add("Name",[string]$Task.Settings.NetworkSettings.Name); $Network.Add("ID",[string]$Task.Settings.NetworkSettings.Id); $Result.Add("NetworkSetting",($Network)) #endregion $Triggers = @() foreach($item in $Task.Triggers) { $t =@{} $t.Add("Id",[String]$item.Id) $t.Add("StateChange",[uint32]$item.StateChange) $t.Add("Enabled",[bool]$item.Enabled) $t.Add("DaysOfWeek",[Uint16]$item.DaysOfWeek) $t.Add("StartBoundary",[String]$item.StartBoundary) $t.Add("EndBoundary",[String]$item.EndBoundary) $t.Add("ExecutionTimeLimit",[String]$item.ExecutionTimeLimit) $t.Add("RandomDelay",[String]$item.RandomDelay) $t.Add("Delay",[String]$item.Delay) $t.Add("UserId",[String]$item.UserId) $t.Add("WeeksInterval",[uint16]$item.WeeksInterval) $t.Add("DaysInterval",[uint16]$item.DaysInterval) $Triggers+=$t } $Result.add("TaskTriggers",$Triggers) #region TaskTriggers #endregion } return $Result; } #endregion #region Test-TargetResource Function Test-TargetResource { [CmdletBinding()] #region parameter param ( [parameter(Mandatory= $true)] [string]$Name, [parameter(Mandatory= $true)] [string]$Path, [parameter(Mandatory= $false)] [ciminstance[]]$TaskAction, [parameter(Mandatory= $false)] [ciminstance]$TaskUserPrincipal, [parameter(Mandatory= $false)] [ciminstance]$TaskGroupPrincipal, [parameter(Mandatory= $false)] [ciminstance]$TaskSettingsSet, [parameter(Mandatory= $false)] [ciminstance]$NetworkSetting, [parameter(Mandatory= $false)] [ciminstance[]]$TaskTriggers ## for vsersion 4.0.0. #[parameter(Mandatory= $false)] #[ciminstance]$IdleSetting, ) #endregion [bool]$Result = $true; $Task = Get-ScheduledTask -TaskName $name -TaskPath $Path -ErrorAction SilentlyContinue; #region it is test do { Write-Verbose ("Start Testing") #region test ok if(!$Task) { Write-Verbose -Message ("Testing Task exist "); $Re = $false; Write-Verbose -Message ("Testing Task exist " +$Re); } else { Write-Verbose -Message ("Testing Task exist " +$Result); } if($TaskAction) { Write-Verbose -Message ("Testing Task Action "); $Re = TestTaskAction -Action $TaskAction -TaskInstance $Task if(!$Re) { $Result =$false; } Write-Verbose -Message ("Testing Task Action "+$Re); } if($TaskUserPrincipal) { Write-Verbose -Message ("Testing Task UserPrincipal"); $Re = TestTaskUserPrincipal -UserPrincipal $TaskUserPrincipal -TaskInstance $Task if(!$Re) { $Result =$false; } Write-Verbose -Message ("Testing Task UserPrincipal "+$Re); } if($TaskGroupPrincipal) { Write-Verbose -Message ("Testing Task GroupPrincipal"); $Re =TestTaskGroupPrincipal -GroupPrincipal $TaskGroupPrincipal -TaskInstance $Task if(!$Re) { $Result =$false; } Write-Verbose -Message ("Testing Task GroupPrincipal "+$Re); } if($TaskSettingsSet) { Write-Verbose -Message ("Testing Task SettingsSet"); $Re =TestTaskSettingsSet -SettingsSet $TaskSettingsSet -TaskInstance $Task if(!$Re) { $Result =$false; } Write-Verbose -Message ("Testing Task SettingsSet "+$Re); } if($NetworkSetting) { Write-Verbose -Message ("Testing Task NetworkSetting"); $Re = TestTaskNetworkSetting -NetworkSetting $NetworkSetting -TaskInstance $Task if(!$Re) { $Result =$false; } Write-Verbose -Message ("Testing Task NetworkSetting "+$Re); } if($TaskTriggers) { Write-Verbose -Message ("Testing Task Triggers"); $Re = TestTaskTriggers -TaskInstance $Task -TaskTriggers $TaskTriggers if(!$Re) { $Result =$false; } Write-Verbose -Message ("Testing Task Triggers "+$Re); } #endregion break; } while($Result -eq $true) #endregion Write-Verbose ("Successful completion Testing Result $($Result)") return $Result; } #endregion Export-ModuleMember -Function *TargetResource |