diff --git a/CHANGELOG.md b/CHANGELOG.md
index c882fe49..197b3942 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,9 @@
- Moved strings to localization file.
- Changed the scope from Global to Script in MSFT_ScheduledTask.Integration.Tests.ps1
- Changed the scope from Global to Script ComputerManagementDsc.Common.Tests.ps1
+- ScheduledTask:
+ - Added support for event based triggers, implemented using the ScheduleType OnEvent
+ fixes [Issue #167](https://github.com/PowerShell/ComputerManagementDsc/issues/167)
## 5.1.0.0
diff --git a/Modules/ComputerManagementDsc/DSCResources/MSFT_ScheduledTask/MSFT_ScheduledTask.psm1 b/Modules/ComputerManagementDsc/DSCResources/MSFT_ScheduledTask/MSFT_ScheduledTask.psm1
index 7d7329d9..4210a65e 100644
--- a/Modules/ComputerManagementDsc/DSCResources/MSFT_ScheduledTask/MSFT_ScheduledTask.psm1
+++ b/Modules/ComputerManagementDsc/DSCResources/MSFT_ScheduledTask/MSFT_ScheduledTask.psm1
@@ -201,6 +201,15 @@ $script:localizedData = Get-LocalizedData `
.PARAMETER LogonType
Specifies the security logon method that Task Scheduler uses to run the tasks that
are associated with the principal. Not used in Get-TargetResource.
+
+ .PARAMETER EventSubscription
+ The event subscription in a string that can be parsed as valid XML. This parameter is only
+ valid in combination with the OnEvent Schedule Type. For the query schema please check:
+ https://docs.microsoft.com/en-us/windows/desktop/WES/queryschema-schema
+
+ .PARAMETER Delay
+ The time to wait after an event based trigger was triggered. This parameter is only
+ valid in combination with the OnEvent Schedule Type.
#>
function Get-TargetResource
{
@@ -234,7 +243,7 @@ function Get-TargetResource
[Parameter()]
[System.String]
- [ValidateSet('Once', 'Daily', 'Weekly', 'AtStartup', 'AtLogOn')]
+ [ValidateSet('Once', 'Daily', 'Weekly', 'AtStartup', 'AtLogOn', 'OnEvent')]
$ScheduleType,
[Parameter()]
@@ -376,7 +385,15 @@ function Get-TargetResource
[Parameter()]
[ValidateSet('Group', 'Interactive', 'InteractiveOrPassword', 'None', 'Password', 'S4U', 'ServiceAccount')]
[System.String]
- $LogonType
+ $LogonType,
+
+ [Parameter()]
+ [System.String]
+ $EventSubscription,
+
+ [Parameter()]
+ [System.String]
+ $Delay = '00:00:00'
)
$TaskPath = ConvertTo-NormalizedTaskPath -TaskPath $TaskPath
@@ -436,6 +453,12 @@ function Get-TargetResource
break
}
+ 'MSFT_TaskEventTrigger'
+ {
+ $returnScheduleType = 'OnEvent'
+ break
+ }
+
default
{
$returnScheduleType = ''
@@ -510,6 +533,8 @@ function Get-TargetResource
RunOnlyIfNetworkAvailable = $settings.RunOnlyIfNetworkAvailable
RunLevel = [System.String] $task.Principal.RunLevel
LogonType = [System.String] $task.Principal.LogonType
+ EventSubscription = $trigger.Subscription
+ Delay = ConvertTo-TimeSpanStringFromScheduledTaskString -TimeSpan $trigger.Delay
}
}
}
@@ -665,6 +690,15 @@ function Get-TargetResource
.PARAMETER LogonType
Specifies the security logon method that Task Scheduler uses to run the tasks that
are associated with the principal.
+
+ .PARAMETER EventSubscription
+ The event subscription in a string that can be parsed as valid XML. This parameter is only
+ valid in combination with the OnEvent Schedule Type. For the query schema please check:
+ https://docs.microsoft.com/en-us/windows/desktop/WES/queryschema-schema
+
+ .PARAMETER Delay
+ The time to wait after an event based trigger was triggered. This parameter is only
+ valid in combination with the OnEvent Schedule Type.
#>
function Set-TargetResource
{
@@ -697,7 +731,7 @@ function Set-TargetResource
[Parameter()]
[System.String]
- [ValidateSet('Once', 'Daily', 'Weekly', 'AtStartup', 'AtLogOn')]
+ [ValidateSet('Once', 'Daily', 'Weekly', 'AtStartup', 'AtLogOn', 'OnEvent')]
$ScheduleType,
[Parameter()]
@@ -839,7 +873,15 @@ function Set-TargetResource
[Parameter()]
[ValidateSet('Group', 'Interactive', 'InteractiveOrPassword', 'None', 'Password', 'S4U', 'ServiceAccount')]
[System.String]
- $LogonType
+ $LogonType,
+
+ [Parameter()]
+ [System.String]
+ $EventSubscription,
+
+ [Parameter()]
+ [System.String]
+ $Delay = '00:00:00'
)
$TaskPath = ConvertTo-NormalizedTaskPath -TaskPath $TaskPath
@@ -902,6 +944,13 @@ function Set-TargetResource
-ArgumentName DaysOfWeek
}
+ if ($ScheduleType -eq 'OnEvent' -and -not ([xml]$EventSubscription))
+ {
+ New-InvalidArgumentException `
+ -Message ($script:localizedData.OnEventSubscriptionError) `
+ -ArgumentName EventSubscription
+ }
+
# Configure the action
$actionParameters = @{
Execute = $ActionExecutable
@@ -989,7 +1038,8 @@ function Set-TargetResource
# Configure the trigger
$triggerParameters = @{}
- if ($RandomDelay -gt [System.TimeSpan]::FromSeconds(0))
+ # A random delay is not supported when the scheduleType is set to OnEvent
+ if ($RandomDelay -gt [System.TimeSpan]::FromSeconds(0) -and $ScheduleType -ne 'OnEvent')
{
$triggerParameters.Add('RandomDelay', $RandomDelay)
}
@@ -1049,9 +1099,23 @@ function Set-TargetResource
break
}
+
+ 'OnEvent'
+ {
+ Write-Verbose -Message ($script:localizedData.ConfigureTaskEventTrigger -f $TaskName)
+
+ $cimTriggerClass = Get-CimClass -ClassName MSFT_TaskEventTrigger -Namespace Root/Microsoft/Windows/TaskScheduler:MSFT_TaskEventTrigger
+ $trigger = New-CimInstance -CimClass $cimTriggerClass -ClientOnly
+ $trigger.Enabled = $true
+ $trigger.Delay = [System.Xml.XmlConvert]::ToString([timespan]$Delay)
+ $trigger.Subscription = $EventSubscription
+ }
}
- $trigger = New-ScheduledTaskTrigger @triggerParameters -ErrorAction SilentlyContinue
+ if ($ScheduleType -ne 'OnEvent')
+ {
+ $trigger = New-ScheduledTaskTrigger @triggerParameters -ErrorAction SilentlyContinue
+ }
if (-not $trigger)
{
@@ -1390,6 +1454,15 @@ function Set-TargetResource
.PARAMETER LogonType
Specifies the security logon method that Task Scheduler uses to run the tasks that
are associated with the principal.
+
+ .PARAMETER EventSubscription
+ The event subscription in a string that can be parsed as valid XML. This parameter is only
+ valid in combination with the OnEvent Schedule Type. For the query schema please check:
+ https://docs.microsoft.com/en-us/windows/desktop/WES/queryschema-schema
+
+ .PARAMETER Delay
+ The time to wait after an event based trigger was triggered. This parameter is only
+ valid in combination with the OnEvent Schedule Type.
#>
function Test-TargetResource
{
@@ -1423,7 +1496,7 @@ function Test-TargetResource
[Parameter()]
[System.String]
- [ValidateSet('Once', 'Daily', 'Weekly', 'AtStartup', 'AtLogOn')]
+ [ValidateSet('Once', 'Daily', 'Weekly', 'AtStartup', 'AtLogOn', 'OnEvent')]
$ScheduleType,
[Parameter()]
@@ -1565,7 +1638,15 @@ function Test-TargetResource
[Parameter()]
[ValidateSet('Group', 'Interactive', 'InteractiveOrPassword', 'None', 'Password', 'S4U', 'ServiceAccount')]
[System.String]
- $LogonType
+ $LogonType,
+
+ [Parameter()]
+ [System.String]
+ $EventSubscription,
+
+ [Parameter()]
+ [System.String]
+ $Delay = '00:00:00'
)
$TaskPath = ConvertTo-NormalizedTaskPath -TaskPath $TaskPath
@@ -1580,7 +1661,16 @@ function Test-TargetResource
if ($PSBoundParameters.ContainsKey('RandomDelay'))
{
- $PSBoundParameters['RandomDelay'] = (ConvertTo-TimeSpanFromTimeSpanString -TimeSpanString $RandomDelay).ToString()
+ if ($ScheduleType -eq 'OnEvent')
+ {
+ # A random delay is not supported when the ScheduleType is set to OnEvent.
+ Write-Verbose -Message ($script:localizedData.IgnoreRandomDelayWithTriggerTypeOnEvent -f $TaskName)
+ $null = $PSBoundParameters.Remove('RandomDelay')
+ }
+ else
+ {
+ $PSBoundParameters['RandomDelay'] = (ConvertTo-TimeSpanFromTimeSpanString -TimeSpanString $RandomDelay).ToString()
+ }
}
if ($PSBoundParameters.ContainsKey('RepetitionDuration'))
diff --git a/Modules/ComputerManagementDsc/DSCResources/MSFT_ScheduledTask/MSFT_ScheduledTask.schema.mof b/Modules/ComputerManagementDsc/DSCResources/MSFT_ScheduledTask/MSFT_ScheduledTask.schema.mof
index 494409fb..4d40f88a 100644
--- a/Modules/ComputerManagementDsc/DSCResources/MSFT_ScheduledTask/MSFT_ScheduledTask.schema.mof
+++ b/Modules/ComputerManagementDsc/DSCResources/MSFT_ScheduledTask/MSFT_ScheduledTask.schema.mof
@@ -7,7 +7,7 @@ class MSFT_ScheduledTask : OMI_BaseResource
[Write, Description("The path to the .exe for this task")] string ActionExecutable;
[Write, Description("The arguments to pass the executable")] string ActionArguments;
[Write, Description("The working path to specify for the executable")] string ActionWorkingPath;
- [Write, Description("When should the task be executed"), ValueMap{"Once", "Daily", "Weekly", "AtStartup", "AtLogOn"}, Values{"Once", "Daily", "Weekly", "AtStartup", "AtLogOn"}] string ScheduleType;
+ [Write, Description("When should the task be executed"), ValueMap{"Once", "Daily", "Weekly", "AtStartup", "AtLogOn", "OnEvent"}, Values{"Once", "Daily", "Weekly", "AtStartup", "AtLogOn", "OnEvent"}] string ScheduleType;
[Write, Description("How many units (minutes, hours, days) between each run of this task?")] String RepeatInterval;
[Write, Description("The time of day this task should start at - defaults to 12:00 AM. Not valid for AtLogon and AtStartup tasks")] DateTime StartTime;
[Write, Description("Present if the task should exist, Absent if it should be removed"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure;
@@ -42,4 +42,6 @@ class MSFT_ScheduledTask : OMI_BaseResource
[Write, Description("Indicates that Task Scheduler runs the task only when a network is available. Task Scheduler uses the NetworkID parameter and NetworkName parameter that you specify in this cmdlet to determine if the network is available.")] Boolean RunOnlyIfNetworkAvailable;
[Write, Description("Specifies the level of user rights that Task Scheduler uses to run the tasks that are associated with the principal. Defaults to 'Limited'."), ValueMap{"Limited","Highest"}, Values{"Limited","Highest"}] String RunLevel;
[Write, Description("Specifies the security logon method that Task Scheduler uses to run the tasks that are associated with the principal."), ValueMap{"Group","Interactive","InteractiveOrPassword","None","Password","S4U","ServiceAccount"}, Values{"Group","Interactive","InteractiveOrPassword","None","Password","S4U","ServiceAccount"}] String LogonType;
+ [Write, Description("Specifies the EventSubscription in XML. This can be easily generated using the Windows Eventlog Viewer. For the query schema please check: https://docs.microsoft.com/en-us/windows/desktop/WES/queryschema-schema. Can only be used in combination with ScheduleType OnEvent")] String EventSubscription;
+ [Write, Description("Specifies a delay to the start of the trigger. The delay is a static delay before the task is executed. Can only be used in combination with ScheduleType OnEvent")] String Delay;
};
diff --git a/Modules/ComputerManagementDsc/DSCResources/MSFT_ScheduledTask/en-US/MSFT_ScheduledTask.strings.psd1 b/Modules/ComputerManagementDsc/DSCResources/MSFT_ScheduledTask/en-US/MSFT_ScheduledTask.strings.psd1
index 31a11ec6..d811266f 100644
--- a/Modules/ComputerManagementDsc/DSCResources/MSFT_ScheduledTask/en-US/MSFT_ScheduledTask.strings.psd1
+++ b/Modules/ComputerManagementDsc/DSCResources/MSFT_ScheduledTask/en-US/MSFT_ScheduledTask.strings.psd1
@@ -10,6 +10,7 @@ ConvertFrom-StringData @'
DaysIntervalError = DaysInterval must be greater than zero (0) for Daily schedules. DaysInterval specified is '{0}'.
WeeksIntervalError = WeeksInterval must be greater than zero (0) for Weekly schedules. WeeksInterval specified is '{0}'.
WeekDayMissingError = At least one weekday must be selected for Weekly schedule.
+ OnEventSubscriptionError = No (valid) XML Event Subscription was provided. This is required when the scheduletype is OnEvent.
TriggerCreationError = Error creating new scheduled task trigger.
ConfigureTriggerRepetitionMessage = Configuring trigger repetition.
RepetitionIntervalError = Repetition interval is set to '{0}' but repetition duration is '{1}'.
@@ -20,6 +21,8 @@ ConvertFrom-StringData @'
CreateScheduledTaskPrincipalMessage = Creating scheduled task principal for account '{0}' using logon type '{1}'.
RemovePreviousScheduledTaskMessage = Removing previous scheduled task '{0}' from '{1}'.
CreateNewScheduledTaskMessage = Creating new scheduled task '{0}' in '{1}'.
+ ConfigureTaskEventTrigger = Setting up an event based trigger on task {0}.
+ IgnoreRandomDelayWithTriggerTypeOnEvent = The parameter RandomDelay in task {0} is ignored. A random delay is not supported when the trigger type is set to OnEvent.
SetRepetitionTriggerMessage = Setting repetition trigger settings on task '{0}' in '{1}'.
RegisterScheduledTaskMessage = Registering the scheduled task '{0}' in '{1}'.
RetrieveScheduledTaskMessage = Retrieving the scheduled task '{0}' from '{1}'.
diff --git a/Modules/ComputerManagementDsc/Examples/Resources/ScheduledTask/13-CreateScheduledTasksOnEvent.ps1 b/Modules/ComputerManagementDsc/Examples/Resources/ScheduledTask/13-CreateScheduledTasksOnEvent.ps1
new file mode 100644
index 00000000..c34b22b6
--- /dev/null
+++ b/Modules/ComputerManagementDsc/Examples/Resources/ScheduledTask/13-CreateScheduledTasksOnEvent.ps1
@@ -0,0 +1,33 @@
+<#
+ .EXAMPLE
+ This example creates a scheduled task called 'TriggerOnServiceFailures' in the folder
+ root folder. The task is delayed by exactly 30 seconds each time. The task will run when
+ an error event 7001 of source Service Control Manager is generated in the system log.
+ When a service crashes, it waits for 30 seconds and then starts a new PowerShell instance,
+ in which the file c:\temp\seeme.txt get's created with the value 'Worked!'
+#>
+Configuration Example
+{
+ param
+ (
+ [Parameter()]
+ [System.String[]]
+ $NodeName = 'localhost'
+ )
+
+ Import-DscResource -ModuleName ComputerManagementDsc
+
+ Node $NodeName
+ {
+ ScheduledTask ServiceEventManager
+ {
+ TaskName = 'TriggerOnServiceFailures'
+ Ensure = 'Present'
+ ScheduleType = 'OnEvent'
+ ActionExecutable = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
+ ActionArguments = '-Command Set-Content -Path c:\temp\seeme.txt -Value ''Worked!'''
+ EventSubscription = ''
+ Delay = '00:00:30'
+ }
+ }
+}
diff --git a/Tests/Integration/MSFT_ScheduledTask.Config.ps1 b/Tests/Integration/MSFT_ScheduledTask.Config.ps1
index b3d85910..8195dff4 100644
--- a/Tests/Integration/MSFT_ScheduledTask.Config.ps1
+++ b/Tests/Integration/MSFT_ScheduledTask.Config.ps1
@@ -168,6 +168,25 @@ Configuration ScheduledTaskExecuteAsAdd
}
}
+Configuration ScheduledTaskOnEventAdd
+{
+ Import-DscResource -ModuleName ComputerManagementDsc
+ node 'localhost'
+ {
+ ScheduledTask ScheduledTaskOnEventAdd
+ {
+ TaskName = 'Test task OnEvent'
+ TaskPath = '\ComputerManagementDsc\'
+ Ensure = 'Present'
+ ScheduleType = 'OnEvent'
+ ActionExecutable = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
+ ActionArguments = '-Command Set-Content -Path c:\temp\seeme.txt -Value ''Worked!'''
+ EventSubscription = ''
+ Delay = '00:00:30'
+ }
+ }
+}
+
Configuration ScheduledTaskOnceMod
{
Import-DscResource -ModuleName ComputerManagementDsc
@@ -294,6 +313,25 @@ Configuration ScheduledTaskExecuteAsMod
}
}
+Configuration ScheduledTaskOnEventMod
+{
+ Import-DscResource -ModuleName ComputerManagementDsc
+ node 'localhost'
+ {
+ ScheduledTask ScheduledTaskOnEventMod
+ {
+ TaskName = 'Test task OnEvent'
+ TaskPath = '\ComputerManagementDsc\'
+ Ensure = 'Present'
+ ScheduleType = 'OnEvent'
+ ActionExecutable = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
+ ActionArguments = '-Command Set-Content -Path c:\temp\seeme.txt -Value ''Worked!'''
+ EventSubscription = ''
+ Delay = '00:00:45'
+ }
+ }
+}
+
Configuration ScheduledTaskOnceDel
{
Import-DscResource -ModuleName ComputerManagementDsc
@@ -425,6 +463,25 @@ Configuration ScheduledTaskExecuteAsDel
}
}
+Configuration ScheduledTaskOnEventDel
+{
+ Import-DscResource -ModuleName ComputerManagementDsc
+ node 'localhost'
+ {
+ ScheduledTask ScheduledTaskOnEventDel
+ {
+ TaskName = 'Test task OnEvent'
+ TaskPath = '\ComputerManagementDsc\'
+ Ensure = 'Absent'
+ ScheduleType = 'OnEvent'
+ ActionExecutable = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
+ ActionArguments = '-Command Set-Content -Path c:\temp\seeme.txt -Value ''Worked!'''
+ EventSubscription = ''
+ Delay = '00:00:30'
+ }
+ }
+}
+
Configuration ScheduledTaskDisableBuiltIn
{
Import-DscResource -ModuleName ComputerManagementDsc
diff --git a/Tests/Integration/MSFT_ScheduledTask.Integration.Tests.ps1 b/Tests/Integration/MSFT_ScheduledTask.Integration.Tests.ps1
index 37575fc4..38ae8f2f 100644
--- a/Tests/Integration/MSFT_ScheduledTask.Integration.Tests.ps1
+++ b/Tests/Integration/MSFT_ScheduledTask.Integration.Tests.ps1
@@ -36,6 +36,7 @@ try
AtLogon = 'ScheduledTaskLogon'
AtStartup = 'ScheduledTaskStartup'
ExecuteAs = 'ScheduledTaskExecuteAs'
+ OnEvent = 'ScheduledTaskOnEvent'
}
$configData = @{
diff --git a/Tests/Unit/MSFT_ScheduledTask.Tests.ps1 b/Tests/Unit/MSFT_ScheduledTask.Tests.ps1
index ffae5045..e3943a7a 100644
--- a/Tests/Unit/MSFT_ScheduledTask.Tests.ps1
+++ b/Tests/Unit/MSFT_ScheduledTask.Tests.ps1
@@ -102,7 +102,7 @@ try
ScheduleType = 'Once'
RepeatInterval = (New-TimeSpan -Minutes 15).ToString()
RepetitionDuration = (New-TimeSpan -Minutes 150).ToString()
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith { return $null }
@@ -130,7 +130,7 @@ try
RepeatInterval = (New-TimeSpan -Minutes 15).ToString()
RepetitionDuration = (New-TimeSpan -Minutes 15).ToString()
Ensure = 'Absent'
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -174,7 +174,7 @@ try
TaskName = 'Test task'
TaskPath = '\Test\'
Enable = $false
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -219,7 +219,7 @@ try
TaskName = 'Test task'
TaskPath = '\Test\'
Ensure = 'Absent'
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -271,7 +271,7 @@ try
ActionExecutable = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
ScheduleType = 'Once'
Ensure = 'Absent'
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask
@@ -294,7 +294,7 @@ try
ScheduleType = 'Once'
RepeatInterval = (New-TimeSpan -Minutes 15).ToString()
RepetitionDuration = (New-TimeSpan -Minutes 150).ToString()
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -346,7 +346,7 @@ try
ScheduleType = 'Once'
RepeatInterval = (New-TimeSpan -Minutes 15).ToString()
RepetitionDuration = (New-TimeSpan -Minutes 30).ToString()
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -393,7 +393,7 @@ try
ScheduleType = 'Once'
RepeatInterval = (New-TimeSpan -Hours 4).ToString()
RepetitionDuration = (New-TimeSpan -Hours 8).ToString()
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -445,7 +445,7 @@ try
ScheduleType = 'Once'
RepeatInterval = (New-TimeSpan -Hours 4).ToString()
RepetitionDuration = (New-TimeSpan -Hours 8).ToString()
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -491,7 +491,7 @@ try
ActionExecutable = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
ScheduleType = 'Daily'
DaysInterval = 3
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -542,7 +542,7 @@ try
ActionExecutable = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
ScheduleType = 'Daily'
DaysInterval = 3
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -587,7 +587,7 @@ try
RepeatInterval = (New-TimeSpan -Minutes 15).ToString()
RepetitionDuration = (New-TimeSpan -Hours 8).ToString()
ExecuteAsCredential = New-Object System.Management.Automation.PSCredential ('DEMO\RightUser', (ConvertTo-SecureString 'ExamplePassword' -AsPlainText -Force))
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -641,7 +641,7 @@ try
RepetitionDuration = (New-TimeSpan -Hours 8).ToString()
ExecuteAsCredential = New-Object System.Management.Automation.PSCredential ('DEMO\RightUser', (ConvertTo-SecureString 'ExamplePassword' -AsPlainText -Force))
LogonType = 'S4U'
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -697,7 +697,7 @@ try
RepetitionDuration = (New-TimeSpan -Hours 8).ToString()
ExecuteAsCredential = New-Object System.Management.Automation.PSCredential ('DEMO\RightUser', (ConvertTo-SecureString 'ExamplePassword' -AsPlainText -Force))
RunLevel = 'Highest'
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -752,7 +752,7 @@ try
ScheduleType = 'Once'
RepeatInterval = (New-TimeSpan -Minutes 15).ToString()
RepetitionDuration = (New-TimeSpan -Hours 8).ToString()
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -806,7 +806,7 @@ try
ScheduleType = 'Once'
RepeatInterval = (New-TimeSpan -Minutes 15).ToString()
RepetitionDuration = (New-TimeSpan -Hours 8).ToString()
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -860,7 +860,7 @@ try
RepeatInterval = (New-TimeSpan -Minutes 15).ToString()
RepetitionDuration = (New-TimeSpan -Hours 8).ToString()
Enable = $false
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -919,7 +919,7 @@ try
RepetitionDuration = (New-TimeSpan -Hours 8).ToString()
ExecutionTimeLimit = (New-TimeSpan -Seconds 0).ToString()
Enable = $true
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -982,7 +982,7 @@ try
ExecutionTimeLimit = (New-TimeSpan -Minutes 7).ToString()
RestartInterval = (New-TimeSpan -Minutes 8).ToString()
Enable = $true
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -1041,7 +1041,7 @@ try
RepeatInterval = (New-TimeSpan -Minutes 15).ToString()
RepetitionDuration = (New-TimeSpan -Hours 8).ToString()
Enable = $false
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -1093,7 +1093,7 @@ try
RepeatInterval = (New-TimeSpan -Minutes 15).ToString()
RepetitionDuration = (New-TimeSpan -Hours 8).ToString()
Enable = $true
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -1149,7 +1149,7 @@ try
ScheduleType = 'Once'
RepeatInterval = (New-TimeSpan -Minutes 15).ToString()
RepetitionDuration = (New-TimeSpan -Hours 8).ToString()
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -1227,7 +1227,7 @@ try
IdleDuration = (New-TimeSpan -Minutes 6).ToString()
ExecutionTimeLimit = (New-TimeSpan -Minutes 7).ToString()
RestartInterval = (New-TimeSpan -Minutes 8).ToString()
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -1293,7 +1293,7 @@ try
IdleDuration = (New-TimeSpan -Minutes 6).ToString()
ExecutionTimeLimit = (New-TimeSpan -Minutes 7).ToString()
RestartInterval = (New-TimeSpan -Minutes 8).ToString()
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -1355,7 +1355,7 @@ try
ScheduleType = 'Once'
RepeatInterval = (New-TimeSpan -Minutes 20).ToString()
RepetitionDuration = 'Indefinitely'
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -1408,7 +1408,7 @@ try
ScheduleType = 'Once'
RepeatInterval = (New-TimeSpan -Minutes 20).ToString()
RepetitionDuration = (New-TimeSpan -Hours 9).ToString()
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -1461,7 +1461,7 @@ try
ScheduleType = 'Once'
RepeatInterval = (New-TimeSpan -Minutes 20).ToString()
RepetitionDuration = 'Indefinitely'
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -1506,7 +1506,7 @@ try
TaskName = 'Test task'
TaskPath = '\Test\'
Enable = $false
- Verbose = $True
+ Verbose = $true
}
Mock -CommandName Get-ScheduledTask -MockWith {
@@ -1522,13 +1522,14 @@ try
Interval = "PT15M"
}
CimClass = @{
- CimClassName = 'MSFT_TaskEventTrigger'
+ CimClassName = 'MSFT_TaskSessionStateChangeTrigger'
}
}
Settings = [pscustomobject] @{
Enabled = $true
}
- } }
+ }
+ }
It 'Should return the correct values from Get-TargetResource' {
$result = Get-TargetResource @testParameters
@@ -1546,6 +1547,187 @@ try
Assert-MockCalled Register-ScheduledTask -Exactly -Times 1
}
}
+
+ Context 'When a scheduled task with an OnEvent scheduletype is in desired state' {
+ $testParameters = @{
+ TaskName = 'Test task'
+ TaskPath = '\Test\'
+ ScheduleType = 'OnEvent'
+ ActionExecutable = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
+ EventSubscription = ''
+ Delay = '00:01:00'
+ Enable = $true
+ Verbose = $true
+ }
+
+ Mock -CommandName Get-ScheduledTask -MockWith {
+ @{
+ TaskName = $testParameters.TaskName
+ TaskPath = $testParameters.TaskPath
+ Actions = [pscustomobject] @{
+ Execute = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
+ }
+ Triggers = [pscustomobject] @{
+ Delay = 'PT1M'
+ Subscription = $testParameters.EventSubscription
+ CimClass = @{
+ CimClassName = 'MSFT_TaskEventTrigger'
+ }
+ }
+ Settings = [pscustomobject] @{
+ Enabled = $true
+ }
+ }
+ }
+
+ It 'Should return the correct values from Get-TargetResource' {
+ $result = Get-TargetResource @testParameters
+ $result.Enable | Should -Be $true
+ $result.Ensure | Should -Be 'Present'
+ $result.ScheduleType | Should -Be 'OnEvent'
+ $result.EventSubscription | Should -Be $testParameters.EventSubscription
+ $result.Delay | Should -Be $testParameters.Delay
+ }
+
+ It 'Should return true from the test method' {
+ Test-TargetResource @testParameters | Should -Be $true
+ }
+ }
+
+ Context 'When a scheduled task with an OnEvent scheduletype needs to be created' {
+ $testParameters = @{
+ TaskName = 'Test task'
+ TaskPath = '\Test\'
+ ScheduleType = 'OnEvent'
+ ActionExecutable = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
+ EventSubscription = ''
+ Delay = '00:01:00'
+ Enable = $true
+ Verbose = $true
+ }
+
+ Mock -CommandName Get-ScheduledTask
+
+ It 'Should return the correct values from Get-TargetResource' {
+ $result = Get-TargetResource @testParameters
+ $result.Ensure | Should -Be 'Absent'
+ }
+
+ It 'Should return false from the test method' {
+ Test-TargetResource @testParameters | Should -Be $false
+ }
+
+ It 'Should register the new scheduled task' {
+ Set-TargetResource @testParameters
+ Assert-MockCalled Register-ScheduledTask -Exactly -Times 1 -Scope It
+ }
+ }
+
+ Context 'When a scheduled task with an OnEvent scheduletype needs to be updated' {
+ $testParameters = @{
+ TaskName = 'Test task'
+ TaskPath = '\Test\'
+ ScheduleType = 'OnEvent'
+ ActionExecutable = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
+ EventSubscription = ''
+ Delay = '00:05:00'
+ Enable = $true
+ Verbose = $true
+ }
+
+ Mock -CommandName Get-ScheduledTask -MockWith {
+ @{
+ TaskName = $testParameters.TaskName
+ TaskPath = $testParameters.TaskPath
+ Actions = [pscustomobject] @{
+ Execute = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
+ }
+ Triggers = [pscustomobject] @{
+ Delay = 'PT1M'
+ Subscription = ''
+ CimClass = @{
+ CimClassName = 'MSFT_TaskEventTrigger'
+ }
+ }
+ Settings = [pscustomobject] @{
+ Enabled = $true
+ }
+ }
+ }
+
+ It 'Should return the correct values from Get-TargetResource' {
+ $result = Get-TargetResource @testParameters
+ $result.Enable | Should -Be $true
+ $result.Ensure | Should -Be 'Present'
+ $result.ScheduleType | Should -Be 'OnEvent'
+ }
+
+ It 'Should return false from the test method' {
+ Test-TargetResource @testParameters | Should -Be $false
+ }
+
+ It 'Should not call Register-ScheduledTask on an already registered task' {
+ Set-TargetResource @testParameters
+ Assert-MockCalled Register-ScheduledTask -Times 0 -Scope It
+ }
+
+ It 'Should call Set-ScheduledTask to update the scheduled task with the new values' {
+ Set-TargetResource @testParameters
+ Assert-MockCalled Set-ScheduledTask -Times 1 -Scope It
+ }
+ }
+
+ Context 'When a scheduled task with an OnEvent scheduletype is used on combination with unsupported parameters for this scheduletype' {
+ $testParameters = @{
+ TaskName = 'Test task'
+ TaskPath = '\Test\'
+ ScheduleType = 'OnEvent'
+ ActionExecutable = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
+ EventSubscription = ''
+ RandomDelay = '01:00:00'
+ Delay = '00:01:00'
+ Enable = $true
+ Verbose = $true
+ }
+
+ Mock -CommandName Get-ScheduledTask -MockWith {
+ @{
+ TaskName = $testParameters.TaskName
+ TaskPath = $testParameters.TaskPath
+ Actions = [pscustomobject] @{
+ Execute = 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe'
+ }
+ Triggers = [pscustomobject] @{
+ Delay = 'PT1M'
+ Subscription = $testParameters.EventSubscription
+ CimClass = @{
+ CimClassName = 'MSFT_TaskEventTrigger'
+ }
+ }
+ Settings = [pscustomobject] @{
+ Enabled = $true
+ }
+ }
+ }
+
+ It 'Should return the correct values from Get-TargetResource' {
+ $result = Get-TargetResource @testParameters
+ $result.Enable | Should -Be $true
+ $result.Ensure | Should -Be 'Present'
+ $result.ScheduleType | Should -Be 'OnEvent'
+ $result.RandomDelay | Should -Be '00:00:00'
+ }
+
+ It 'Should return true from the test method - ignoring the RandomDelay parameter' {
+ Test-TargetResource @testParameters | Should -Be $true
+ }
+
+ $testParameters.EventSubscription = 'InvalidXML'
+
+ It 'When an EventSubscription cannot be parsed as valid XML an error is generated when changing the task' {
+ { Set-TargetResource @testParameters } | Should throw
+ }
+ }
}
}
#endregion