Suppose you found or created one of those valuable scripts but want to run it on a schedule or even schedule itself. Whilst there is this wonderful Powershell Pack that includes a module to utilize the task scheduler from Powershell, this article uses the standard “Schtasks” utility. We assume some familiarity with the task scheduler, use “Schtasks /?” to find more information on its usage.

There are two things to pay attention to; the length of the schedule command and spaces in path names.

A command cannot exceed 260 characters. Running a Powershell command from the DPM binary path requires ~80 character script path, similar for the console initialization file and a few dozen for the complete “Schtasks” command. So we have a ~200 character command line leaving ample room for parameters you may need to pass to the scheduled script. Here are some ways to overcome that;

  • Put the command to schedule in a CMD file and schedule the CMD as command
  • Write script parameters to a file and read that file from inside the script rather than passing those on the command line 
  • Use the Powershell Pack which builds a task using multiple Powershell statements rather than a single command line (but requires installation of the Powershell Pack free download)
  • Reduce the command by facilitating Powershell requirements from within the script itself rather than using the “–PSconsolefile” parameter. This is demonstrated in the sample script below.
    Please note that a console file typically does more than just loading a required snap-in or module like the sample script does. Ensure that this is sufficient for the scheduled script. 

There is a challenge in scheduling commands with spaces in the path names or parameters.  The sample script is best used “as is” with regards to the amount of escaped quotes. These are necessary because quotes get removed during interpretation by the current Powershell, by the task scheduler and again by Powershell at execution time. This sample executes as ‘Local System’ which suites most situations but see also “Schtasks create /?” for other options.

To schedule itself run script with the –schedule switch as;
.\script.ps1 –schedule

To schedule another script run as;
.\script.ps1 –schedule  “<path>\ScriptToSchedule.Ps1”

param ([switch] $schedule, [string]$ScriptToSchedule=””)

# If the snapin is the only thing you need… load DPM snap-in regardless and clear the error
Add-PSSnapin -name Microsoft.DataProtectionManager.PowerShell -erroraction SilentlyContinue
$Error.Clear()

if ($schedule) {

# Note that we do not use –PSconsolefile because we loaded
# the required snap-in ourselves and have no other needs

if ($ScriptToSchedule –eq “”) {
$taskname = $myinvocation.mycommand.definition -replace '\W','_'
$thisscript = "`"`"`"`"powershell`"`"`" -noninteractive -nologo -command `"`"`"&{$($myinvocation.mycommand.definition)}`"`"`""
}
else {
if (!(Test-Path $scripttoschedule)) {Throw "File not found!";exit}
$taskname = $ScriptToSchedule -replace '\W','_'
$thisscript = "`"`"`"`"powershell`"`"`" -noninteractive -nologo -command `"`"`"&{$ScriptToSchedule}`"`"`""
}
$msg = $null
$msg = @(schtasks /create /F /TN $taskname /SC "DAILY" /RU "System" /ST 06:00 /TR "$thisscript")
if ($msg -inotmatch "SUCCESS") {Throw "ERROR: scheduler reported a failure"}
else {
schtasks /Query /TN "$taskname" /V /FO LIST
}
exit
}

Write-Host "Whatever the script is supposed to be doing goes here"

Having dealt with various conditions my personal favorite method is writing a parameter file and read the parameter file from within the scheduled task. This way you can easily stay below 260 characters and no special consideration or limitations on parameter data.