Skip to content

Instantly share code, notes, and snippets.

@jborean93
Created March 21, 2025 05:38
Show Gist options
  • Save jborean93/d9459f4f871f287a01a6b76ccbe224db to your computer and use it in GitHub Desktop.
Save jborean93/d9459f4f871f287a01a6b76ccbe224db to your computer and use it in GitHub Desktop.
PowerShell script to create a state change, idle, or event trigger
# 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