Created
March 21, 2025 05:38
-
-
Save jborean93/d9459f4f871f287a01a6b76ccbe224db to your computer and use it in GitHub Desktop.
PowerShell script to create a state change, idle, or event trigger
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright: (c) 2025, Jordan Borean (@jborean93) <[email protected]> | |
# MIT License (see LICENSE or https://opensource.org/licenses/MIT) | |
Function New-CommonTaskTriggerProp { | |
[OutputType([hashtable])] | |
[CmdletBinding()] | |
param ( | |
[Parameter()] | |
[switch] | |
$Disable, | |
[Parameter()] | |
[TimeSpan] | |
$ExecutionTimeLimit, | |
[Parameter()] | |
[DateTime] | |
$StartBoundary, | |
[Parameter()] | |
[DateTime] | |
$EndBoundary, | |
[Parameter()] | |
[TimeSpan] | |
$RepetitionInterval, | |
[Parameter()] | |
[TimeSpan] | |
$RepetitionDuration, | |
[Parameter()] | |
[switch] | |
$RepetitionStopAtEnd, | |
[Parameter(ValueFromRemainingArguments)] | |
[object[]] | |
$UnboundArguments | |
) | |
$triggerProps = @{} | |
if ($Disable) { | |
$triggerProps.Enabled = $false | |
} | |
if ($ExecutionTimeLimit) { | |
$triggerProps.ExecutionTimeLimit = [System.Xml.XmlConvert]::ToString($ExecutionTimeLimit) | |
} | |
if ($StartBoundary) { | |
$triggerProps.StartBoundary = [System.Xml.XmlConvert]::ToString($StartBoundary) | |
} | |
if ($EndBoundary) { | |
$triggerProps.EndBoundary = [System.Xml.XmlConvert]::ToString($EndBoundary) | |
} | |
if ($RepetitionInterval) { | |
$repetitionClass = Get-CimClass -Namespace root\Microsoft\Windows\TaskScheduler -ClassName MSFT_TaskRepetitionPattern | |
$repetitionProps = @{ | |
Interval = [System.Xml.XmlConvert]::ToString($RepetitionInterval) | |
} | |
if ($RepetitionDuration) { | |
$repetitionProps.Duration = [System.Xml.XmlConvert]::ToString($RepetitionDuration) | |
} | |
if ($RepetitionStopAtEnd) { | |
$repetitionProps.StopAtDurationEnd = $true | |
} | |
$triggerProps.Repetition = $repetitionClass | New-CimInstance -Property $repetitionProps -ClientOnly | |
} | |
elseif ($RepetitionDuration -or $RepetitionStopAtEnd) { | |
throw '-RepetitionDuration and -RepetitionStopAtEnd require -RepetitionInterval to be set' | |
} | |
$triggerProps | |
} | |
Function New-ScheduledTaskStateChangeTrigger { | |
<# | |
.SYNOPSIS | |
Creates a scheduled task state change trigger object. | |
.DESCRIPTION | |
The New-ScheduledTaskStateTrigger function creates a scheduled task state change trigger object. | |
You can use a state change trigger to trigger in response to state change events. | |
.PARAMETER StateChange | |
The state change to trigger on. Valid values are: | |
- ConsoleConnect | |
- ConsoleDisconnect | |
- RemoteConnect | |
- RemoteDisconnect | |
- SessionLock | |
- SessionUnlock | |
.PARAMETER UserId | |
If set, the state change will only trigger if done by/for the specified user. Otherwise if unset, the trigger will trigger for all users. | |
.PARAMETER Delay | |
The time to wait after the state change before triggering the task. | |
.PARAMETER Disable | |
Creates the trigger but sets it as disabled. | |
.PARAMETER ExecutionTimeLimit | |
The total time that the task can run for, if it exceeds this time, the task will be stopped. | |
.PARAMETER StartBoundary | |
The DateTime from when this trigger is active. | |
.PARAMETER EndBoundary | |
The DateTime until when this trigger is active. | |
.PARAMETER RepetitionInterval | |
The time between each repeat of the trigger. | |
.PARAMETER RepetitionDuration | |
How long to repeat the trigger for, if set the -RepetitionInterval must also be set. | |
.PARAMETER RepetitionStopAtEnd | |
Stop all the running tasks triggered at the end of -RepetitionDuration. If set the -RepetitionInterval must also be set. | |
#> | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory)] | |
[ValidateSet('ConsoleConnect', 'ConsoleDisconnect', 'RemoteConnect', 'RemoteDisconnect', 'SessionLock', 'SessionUnlock')] | |
[string] | |
$StateChange, | |
[Parameter()] | |
[string] | |
$UserId, | |
[Parameter()] | |
[TimeSpan] | |
$Delay, | |
[Parameter()] | |
[switch] | |
$Disable, | |
[Parameter()] | |
[TimeSpan] | |
$ExecutionTimeLimit, | |
[Parameter()] | |
[DateTime] | |
$StartBoundary, | |
[Parameter()] | |
[DateTime] | |
$EndBoundary, | |
[Parameter()] | |
[TimeSpan] | |
$RepetitionInterval, | |
[Parameter()] | |
[TimeSpan] | |
$RepetitionDuration, | |
[Parameter()] | |
[switch] | |
$RepetitionStopAtEnd | |
) | |
$ErrorActionPreference = 'Stop' | |
try { | |
$triggerProps = New-CommonTaskTriggerProp @PSBoundParameters | |
$triggerProps.StateChange = switch ($StateChange) { | |
ConsoleConnect { 1 } | |
ConsoleDisconnect { 2 } | |
RemoteConnect { 3 } | |
RemoteDisconnect { 4 } | |
SessionLock { 7 } | |
SessionUnlock { 8 } | |
} | |
if ($UserId) { | |
$triggerProps.UserId = $UserId | |
} | |
if ($Delay) { | |
$triggerProps.Delay = [System.Xml.XmlConvert]::ToString($Delay) | |
} | |
$triggerClass = Get-CimClass -Namespace root\Microsoft\Windows\TaskScheduler -ClassName MSFT_TaskSessionStateChangeTrigger | |
$triggerClass | New-CimInstance -Property $triggerProps -ClientOnly | |
} | |
catch { | |
$PSCmdlet.WriteError($_) | |
} | |
} | |
Function New-ScheduledTaskEventTrigger { | |
<# | |
.SYNOPSIS | |
Creates a scheduled task state change trigger object. | |
.DESCRIPTION | |
The New-ScheduledTaskEventTrigger function creates a scheduled event trigger. | |
You can use an event trigger to trigger in response to certain events. | |
.PARAMETER Subscription | |
The event subscription to trigger on. The value is in the format of an XPath string. | |
.PARAMETER Query | |
A hashtable/dictionary of the value queries to use in the subscription. | |
.PARAMETER Delay | |
The time to wait after the state change before triggering the task. | |
.PARAMETER Disable | |
Creates the trigger but sets it as disabled. | |
.PARAMETER ExecutionTimeLimit | |
The total time that the task can run for, if it exceeds this time, the task will be stopped. | |
.PARAMETER StartBoundary | |
The DateTime from when this trigger is active. | |
.PARAMETER EndBoundary | |
The DateTime until when this trigger is active. | |
.PARAMETER RepetitionInterval | |
The time between each repeat of the trigger. | |
.PARAMETER RepetitionDuration | |
How long to repeat the trigger for, if set the -RepetitionInterval must also be set. | |
.PARAMETER RepetitionStopAtEnd | |
Stop all the running tasks triggered at the end of -RepetitionDuration. If set the -RepetitionInterval must also be set. | |
#> | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory)] | |
[string] | |
$Subscription, | |
[Parameter()] | |
[System.Collections.IDictionary] | |
$ValueQuery, | |
[Parameter()] | |
[TimeSpan] | |
$Delay, | |
[Parameter()] | |
[switch] | |
$Disable, | |
[Parameter()] | |
[TimeSpan] | |
$ExecutionTimeLimit, | |
[Parameter()] | |
[DateTime] | |
$StartBoundary, | |
[Parameter()] | |
[DateTime] | |
$EndBoundary, | |
[Parameter()] | |
[TimeSpan] | |
$RepetitionInterval, | |
[Parameter()] | |
[TimeSpan] | |
$RepetitionDuration, | |
[Parameter()] | |
[switch] | |
$RepetitionStopAtEnd | |
) | |
$ErrorActionPreference = 'Stop' | |
try { | |
$triggerProps = New-CommonTaskTriggerProp @PSBoundParameters | |
$triggerProps.Subscription = $Subscription | |
if ($ValueQuery.Count) { | |
$vqClass = Get-CimClass -Namespace root\Microsoft\Windows\TaskScheduler -ClassName MSFT_TaskNamedValue | |
$triggerProps.ValueQueries = [CimInstance[]]@( | |
foreach ($q in $ValueQuery.GetEnumerator()) { | |
$vqClass | New-CimInstance -Property @{ | |
Name = $q.Key | |
Value = $q.Value | |
} -ClientOnly | |
} | |
) | |
} | |
if ($Delay) { | |
$triggerProps.Delay = [System.Xml.XmlConvert]::ToString($Delay) | |
} | |
$triggerClass = Get-CimClass -Namespace root\Microsoft\Windows\TaskScheduler -ClassName MSFT_TaskEventTrigger | |
$triggerClass | New-CimInstance -Property $triggerProps -ClientOnly | |
} | |
catch { | |
$PSCmdlet.WriteError($_) | |
} | |
} | |
Function New-ScheduledTaskIdleTrigger { | |
<# | |
.SYNOPSIS | |
Creates a scheduled task on idle trigger object. | |
.DESCRIPTION | |
The New-ScheduledTaskIdleTrigger function creates a scheduled task on idle trigger object. | |
You can use the task settings to define the idle conditions that need to be met for this trigger. | |
.PARAMETER Disable | |
Creates the trigger but sets it as disabled. | |
.PARAMETER ExecutionTimeLimit | |
The total time that the task can run for, if it exceeds this time, the task will be stopped. | |
.PARAMETER StartBoundary | |
The DateTime from when this trigger is active. | |
.PARAMETER EndBoundary | |
The DateTime until when this trigger is active. | |
.PARAMETER RepetitionInterval | |
The time between each repeat of the trigger. | |
.PARAMETER RepetitionDuration | |
How long to repeat the trigger for, if set the -RepetitionInterval must also be set. | |
.PARAMETER RepetitionStopAtEnd | |
Stop all the running tasks triggered at the end of -RepetitionDuration. If set the -RepetitionInterval must also be set. | |
#> | |
[CmdletBinding()] | |
param ( | |
[Parameter()] | |
[switch] | |
$Disable, | |
[Parameter()] | |
[TimeSpan] | |
$ExecutionTimeLimit, | |
[Parameter()] | |
[DateTime] | |
$StartBoundary, | |
[Parameter()] | |
[DateTime] | |
$EndBoundary, | |
[Parameter()] | |
[TimeSpan] | |
$RepetitionInterval, | |
[Parameter()] | |
[TimeSpan] | |
$RepetitionDuration, | |
[Parameter()] | |
[switch] | |
$RepetitionStopAtEnd | |
) | |
$ErrorActionPreference = 'Stop' | |
try { | |
$triggerProps = New-CommonTaskTriggerProp @PSBoundParameters | |
$triggerClass = Get-CimClass -Namespace root\Microsoft\Windows\TaskScheduler -ClassName MSFT_TaskIdleTrigger | |
$triggerClass | New-CimInstance -Property $triggerProps -ClientOnly | |
} | |
catch { | |
$PSCmdlet.WriteError($_) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment