Skip to content

Commit

Permalink
Merge pull request #132 from PlagueHO/Issue-74
Browse files Browse the repository at this point in the history
BREAKING CHANGE: xScheduledTask: Add support for disabling built-in tasks - Fixes #74
  • Loading branch information
PlagueHO authored Jan 14, 2018
2 parents f3e2043 + a3c635f commit 8cc11cf
Show file tree
Hide file tree
Showing 9 changed files with 961 additions and 475 deletions.
83 changes: 69 additions & 14 deletions DSCResources/MSFT_xScheduledTask/MSFT_xScheduledTask.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ function Get-TargetResource
[System.String]
$Description,

[Parameter(Mandatory = $true)]
[Parameter()]
[System.String]
$ActionExecutable,

Expand All @@ -232,7 +232,7 @@ function Get-TargetResource
[System.String]
$ActionWorkingPath,

[Parameter(Mandatory = $true)]
[Parameter()]
[System.String]
[ValidateSet('Once', 'Daily', 'Weekly', 'AtStartup', 'AtLogOn')]
$ScheduleType,
Expand Down Expand Up @@ -390,10 +390,9 @@ function Get-TargetResource
Write-Verbose -Message ($script:localizedData.TaskNotFoundMessage -f $TaskName, $TaskPath)

return @{
TaskName = $TaskName
ActionExecutable = $ActionExecutable
Ensure = 'Absent'
ScheduleType = $ScheduleType
TaskName = $TaskName
TaskPath = $TaskPath
Ensure = 'Absent'
}
}
else
Expand Down Expand Up @@ -685,7 +684,7 @@ function Set-TargetResource
[System.String]
$Description,

[Parameter(Mandatory = $true)]
[Parameter()]
[System.String]
$ActionExecutable,

Expand All @@ -697,7 +696,7 @@ function Set-TargetResource
[System.String]
$ActionWorkingPath,

[Parameter(Mandatory = $true)]
[Parameter()]
[System.String]
[ValidateSet('Once', 'Daily', 'Weekly', 'AtStartup', 'AtLogOn')]
$ScheduleType,
Expand Down Expand Up @@ -861,6 +860,21 @@ function Set-TargetResource

if ($Ensure -eq 'Present')
{
<#
If the scheduled task already exists and is enabled but it needs to be disabled
and the action executable isn't specified then disable the task
#>
if ($currentValues.Ensure -eq 'Present' `
-and $currentValues.Enable `
-and -not $Enable `
-and -not $PSBoundParameters.ContainsKey('ActionExecutable'))
{
Write-Verbose -Message ($script:localizedData.DisablingExistingScheduledTask -f $TaskName, $TaskPath)
Disable-ScheduledTask -TaskName $TaskName -TaskPath $TaskPath

return
}

if ($RepetitionDuration -lt $RepeatInterval)
{
New-InvalidArgumentException `
Expand Down Expand Up @@ -889,6 +903,7 @@ function Set-TargetResource
-ArgumentName DaysOfWeek
}

# Configure the action
$actionParameters = @{
Execute = $ActionExecutable
}
Expand All @@ -905,6 +920,11 @@ function Set-TargetResource

$action = New-ScheduledTaskAction @actionParameters

$scheduledTaskArguments += @{
Action = $action
}

# Configure the settings
$settingParameters = @{
DisallowDemandStart = $DisallowDemandStart
DisallowHardTerminate = $DisallowHardTerminate
Expand Down Expand Up @@ -952,6 +972,10 @@ function Set-TargetResource

$setting = New-ScheduledTaskSettingsSet @settingParameters

$scheduledTaskArguments += @{
Settings = $setting
}

<#
On Windows Server 2012 R2 setting a blank timespan for ExecutionTimeLimit
does not result in the PT0S timespan value being set. So set this
Expand All @@ -963,6 +987,7 @@ function Set-TargetResource
$setting.ExecutionTimeLimit = 'PT0S'
}

# Configure the trigger
$triggerParameters = @{}

if ($RandomDelay -gt [System.TimeSpan]::FromSeconds(0))
Expand Down Expand Up @@ -1098,6 +1123,10 @@ function Set-TargetResource
}
}

$scheduledTaskArguments += @{
Trigger = $trigger
}

# Prepare the register arguments
$registerArguments = @{
TaskName = $TaskName
Expand Down Expand Up @@ -1146,10 +1175,7 @@ function Set-TargetResource

$principal = New-ScheduledTaskPrincipal @principalArguments

$scheduledTaskArguments = @{
Action = $action
Trigger = $trigger
Settings = $setting
$scheduledTaskArguments += @{
Principal = $principal
}

Expand Down Expand Up @@ -1363,7 +1389,7 @@ function Test-TargetResource
[System.String]
$Description,

[Parameter(Mandatory = $true)]
[Parameter()]
[System.String]
$ActionExecutable,

Expand All @@ -1375,7 +1401,7 @@ function Test-TargetResource
[System.String]
$ActionWorkingPath,

[Parameter(Mandatory = $true)]
[Parameter()]
[System.String]
[ValidateSet('Once', 'Daily', 'Weekly', 'AtStartup', 'AtLogOn')]
$ScheduleType,
Expand Down Expand Up @@ -1726,3 +1752,32 @@ function ConvertTo-TimeSpanStringFromScheduledTaskString

return (New-TimeSpan -Days $days -Hours $hours -Minutes $minutes -Seconds $seconds).ToString()
}

<#
.SYNOPSIS
Helper function to disable an existing scheduled task.
.PARAMETER TaskName
The name of the task to disable.
.PARAMETER TaskPath
The path to the task to disable.
#>
function Disable-ScheduledTask
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.String]
$TaskName,

[Parameter()]
[System.String]
$TaskPath = '\'
)

$existingTask = Get-ScheduledTask @PSBoundParameters
$existingTask.Settings.Enabled = $false
$null = $existingTask | Register-ScheduledTask @PSBoundParameters -Force
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ class MSFT_xScheduledTask : OMI_BaseResource
[Key, Description("The name of the task")] string TaskName;
[Write, Description("The path to the task - defaults to the root directory")] string TaskPath;
[Write, Description("The task description")] string Description;
[Required, Description("The path to the .exe for this task")] string ActionExecutable;
[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;
[Required, 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"}, Values{"Once", "Daily", "Weekly", "AtStartup", "AtLogOn"}] 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ ConvertFrom-StringData @'
TriggerTypeError = Trigger type '{0}' not recognized.
DetectedScheduleTypeMessage = Detected schedule type '{0}' for first trigger.
SetScheduledTaskMessage = Setting scheduled task '{0}' in '{1}'.
DisablingExistingScheduledTask = Disabling existing scheduled task '{0}' in '{1}'.
RepetitionDurationLessThanIntervalError = Repetition duration '{0}' is less than repetition interval '{1}'. Please set RepeatInterval to a value lower or equal to RepetitionDuration.
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}'.
Expand Down
26 changes: 26 additions & 0 deletions Examples/xScheduledTask/11-DisableABuiltInTask.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<#
.EXAMPLE
This example disables the built-in scheduled task called
'CreateExplorerShellUnelevatedTask'.
#>
Configuration Example
{
param
(
[Parameter()]
[System.String[]]
$NodeName = 'localhost'
)

Import-DscResource -ModuleName xComputerManagement

Node $NodeName
{
xScheduledTask DisableCreateExplorerShellUnelevatedTask
{
TaskName = 'CreateExplorerShellUnelevatedTask'
TaskPath = '\'
Enable = $false
}
}
}
26 changes: 26 additions & 0 deletions Examples/xScheduledTask/12-DeleteABuiltInTask.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<#
.EXAMPLE
This example deletes the built-in scheduled task called
'CreateExplorerShellUnelevatedTask'.
#>
Configuration Example
{
param
(
[Parameter()]
[System.String[]]
$NodeName = 'localhost'
)

Import-DscResource -ModuleName xComputerManagement

Node $NodeName
{
xScheduledTask DeleteCreateExplorerShellUnelevatedTask
{
TaskName = 'CreateExplorerShellUnelevatedTask'
TaskPath = '\'
Ensure = 'Absent'
}
}
}
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ xScheduledTask has the following properties:
* [Run a PowerShell script every 15 minutes indefinitely on a server](/Examples/xScheduledTask/8-RunPowerShellTaskEvery15MinutesIndefinitely.ps1)
* [Run a PowerShell script once as a specified user with highest privileges](/Examples/xScheduledTask/9-RunPowerShellTaskOnceAsUserWithHighestPriveleges.ps1)
* [Run a PowerShell script once as a specified user only when the user is logged on](/Examples/xScheduledTask/10-RunPowerShellTaskOnceAsUserInteractiveOnly.ps1)
* [Disable a built-in scheduled task](/Examples/xScheduledTask/11-DisableABuiltInTask.ps1)
* [Delete a built-in scheduled task](/Examples/xScheduledTask/12-DeleteABuiltInTask.ps1)

## xPowerPlan

Expand Down Expand Up @@ -217,7 +219,14 @@ xVirtualMemory has the following properties:

### Unreleased

* BREAKING CHANGE: xScheduledTask:
* Breaking change because `Get-TargetResource` no longer outputs
`ActionExecutable` and `ScheduleType` properties when the scheduled
task does not exist. It will also include `TaskPath` in output when
scheduled task does not exist.
* xScheduledTask:
* Add support to disable built-in scheduled tasks - See [Issue #74](https://github.com/PowerShell/xComputerManagement/issues/74).
* Fix unit test mocked schedule task object structure.
* Fix error message when trigger type is unknown - See [Issue #121](https://github.com/PowerShell/xComputerManagement/issues/121).
* Moved strings into separate strings file.
* Updated to meet HQRM guidelines.
Expand Down
28 changes: 28 additions & 0 deletions Tests/Integration/MSFT_xScheduledTask.Config.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,31 @@ Configuration xScheduledTaskExecuteAsDel
}
}
}

Configuration xScheduledTaskDisableBuiltIn
{
Import-DscResource -ModuleName xComputerManagement
node 'localhost'
{
xScheduledTask xScheduledTaskDisableBuiltIn
{
TaskName = 'Test task builtin'
TaskPath = '\xComputerManagement\'
Enable = $false
}
}
}

Configuration xScheduledTaskRemoveBuiltIn
{
Import-DscResource -ModuleName xComputerManagement
node 'localhost'
{
xScheduledTask xScheduledTaskRemoveBuiltIn
{
TaskName = 'Test task builtin'
TaskPath = '\xComputerManagement\'
Ensure = 'Absent'
}
}
}
Loading

1 comment on commit 8cc11cf

@EDockus
Copy link

@EDockus EDockus commented on 8cc11cf May 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is causing issues on Server 2016 at the moment. There already is a built-in Disable-ScheduledTask function and this helper one is not working on some system scheduled task. Removing it from the module fixed the problem for me.

Please sign in to comment.