In this example, we will use the command-line utility “schtasks.exe” to create a scheduled task.
There are three steps involved:
- Create a command string
- Execute the command
- Determine status (successful or failed)
If running interactively from PowerShell (or the DOS command shell), you could do something like this:
schtasks.exe /Create /TN myTask /SC ONSTART /TR notepad.exe
This sample will setup a scheduled task that runs notepad every time you logon. That’s not something I’d ever want to do but it makes for a very simplistic example.
Note that schtasks.exe has many command-line options; use “schtasks /?” for details.
When you run the sample above, you get immediate feedback as to whether or not the command was successful. However, if running via a PowerShell script, you might want to capture this status automatically.
Capturing output to a variable can help with this…
$myCmd = "schtasks.exe /Create /TN myTask /SC ONSTART /F /TR notepad.exe" $result = invoke-expression $myCmd write-host $result
But schtasks.exe (like many other programs) writes errors to StdErr which will not be captured to your variable.
There are couple of ways to solve this, one of which is to play with the powershell $error array, parsing its contents for the most recent entry to see if it relates to the command you issued. This seems rather messy and possibly inaccurate since multiple errors from other commands can also be written to the array.
Another way is to invoke the command from a DOS command shell and redirect stderr to stdout and capture both to a PowerShell variable (if you’ve worked with the DOS command shell, you may be familiar with this: 2>&1 ).
$myCmd = "schtasks.exe /Create /TN myTask /SC ONSTART /F /TR notepad.exe" $result = invoke-expression "cmd.exe /c `"`"$myCmd 2>&1`"`"" write-host $result
So in this example (above) we have simply wrapped the whole thing in a DOS command shell (cmd.exe /c) and forced stderr to be written to stdout.
Pay careful attention to the quotes when doing this. Note that cmd.exe needs to have the task scheduler command wrapped in a pair of quotes and you need to escape those quotes using a back-tick character ( ` ).
If your command-to-run through task scheduler has any spaces in it, that too will need to be wrapped in quotes.
Just remember to use a pair of quotes around the part that is passed to cmd.exe and wrap the program-to-run via the /TR switch in its own separate quotes.
Finally, here is an example showing how to create a scheduled task that will run a PowerShell script upon startup of your computer.
example to create a scheduled task that will run a PowerShell script:
1 2 3 4 5 | $myScript = "`"powershell.exe -file c:\scripts\myScript.ps1`"" $taskSetup = "`"`"schtasks.exe /Create /TN myTask /SC ONSTART /F /TR $myScript 2>&1`"`"" $result = invoke-expression "cmd.exe /c $taskSetup" "Successful : {0}" -f ($result -like "*SUCCESS*") $result |
Remember:
- Single Quotes around the PowerShell invocation
- Double Quotes around the Command-line arguments
- You can pass the entire command-string to the invoke-expression cmdlet without using any variables, BUT it makes for a very long string and easy to get your all-important quotation marks mixed up.
~~ To see a complete listing of all command-line options for schtasks.exe, open a command window and enter “schtasks /?” Please Note: The options for this command vary a bit depending on your Windows Version – always make sure that your command is valid by testing it interactively. ~~
I’m getting this:
Invoke-Expression : Ampersand not allowed. The & operator is reserved for future use; use “&” to pass ampersand as a string.
Wrapping the ampersand in quotes or curly brackets doesn’t seem to help. Am I missing anything?
Hey A,
You’re doing it right but somehow my posting software munged the powershell code and replaced important characters with HTML replacements, namely the ampersand and greater-than characters. I’ve fixed it now so a simple cut-and-paste from the article should work for you.
Thanks for catching that!