BSUK
BSUK

Reputation: 745

Single quotes in schtasks command

I'm trying to use SCHTASKS to create a scheduled task on Windows. The parameters include single quotes. If I create my task manually, it works. In the Windows Task Scheduler GUI, the "Details" (within the action tab) show up like this:

powershell (New-Object System.Net.WebClient).DownloadString ('http://mywebserver/myscript.ps1\') | powershell.exe -noprofile -

However, when I enter my SCHTASKS command...

schtasks.exe /Create /TN "My Task" /TR "powershell (New-Object System.Net.WebClient).DownloadString ('http://mywebserver/myscript.ps1\') | powershell.exe -noprofile -" /SC MINUTE /mo 60 /RL HIGHEST

This then appears in the GUI (note the interpretation of a single quote to a double one on the first, but not the second instance:

powershell (New-Object System.Net.WebClient).DownloadString ("http://mywebserver/myscript.ps1\') | powershell.exe -noprofile -

I've tried escaping it etc. (which works fine for double quotes but not for single) but can't seem to figure it out..?!

Many thanks in advance for any suggestions.

Upvotes: 4

Views: 4511

Answers (6)

Michael Conan
Michael Conan

Reputation: 11

Building on the XML approach, if you truly need single quotes in the final task argument, my workaround was to create the task without the arguments needing single quotes, then export the task XML (/query /xml /tn), delete the task (/delete /tn /f), update the XML file with the args and create again (/create /xml). Definitely roundabout but the only way I could get it to work

Upvotes: 1

Daniel
Daniel

Reputation: 329

Using the /XML switch of schtasks.exe is another way of working around this issue; depending on your needs you might need to create the xml file on the fly. I simply created the task manually, exported it, adapted the xml file and changed the schtasks line from using /TR to using /XML.

Upvotes: 0

fretje
fretje

Reputation: 8372

I stumbled upon the same problem recently.

I needed to add an action to a task with this command:

 Powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Object Net.WebClient).DownloadString('https://url/to/script.ps1'))"

It's perfectly possible to create a task with this command manually, but using the schtasks command, it's apparently impossible to render a single quote inside the arguments field of a task (at least not without a backslash in front of it, which makes it unusable).

So after some fiddling, I found a way to specify the arguments without using single quotes:

Powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Object Net.WebClient).DownloadString(\"https://url/to/script.ps1\"))"

And this also works from the task manager... Yay!

It took some more fiddling, but I got this to work using the schtasks command manually (in a command prompt, not in powershell) like this:

schtasks /Create /TN "My Task Name" /RU SYSTEM /SC DAILY /ST 23:00 /TR "Powershell -NoProfile -ExecutionPolicy Bypass -Command \"iex ((New-Object Net.WebClient).DownloadString(\\\"https://url/to/script.ps1\\\""))\""

Yes, those are tripple backslashes around the url... basically, a quote needs to be escaped by a backslash, and a backslash needs to be escaped by another backslash.

Now on to get this to work from powershell... Some more fiddling later, I came to this result:

schtasks /Create /TN "My Task Name" /RU SYSTEM /SC DAILY /ST 23:00 /TR "Powershell -NoProfile -ExecutionPolicy Bypass -Command \`"iex ((New-Object Net.WebClient).DownloadString(\\\`"https://url/to/script.ps1\\\`"))\`""

Which is basically another layer of escaping: the quotes need to be escaped by a backtick.

My head starts to spin, but I'm glad I tamed the beast :)

Upvotes: 4

AmitE
AmitE

Reputation: 894

The following can get you what you need. But it will run it as a single command rather than a command with args.

schtasks.exe /Create /TN "My Task" /TR ""\""powershell (New-Object System.Net.WebClient).DownloadString ('http://mywebserver/myscript.ps1\') "|" powershell.exe -noprofile -\"" /SC MINUTE /mo 60 /RL HIGHEST

Upvotes: 0

evilSnobu
evilSnobu

Reputation: 26314

Then i would suggest doing this instead:

schtasks.exe /F /Create /TN "My Task" /SC MINUTE /mo 60 /RL HIGHEST /TR "powershell.exe -ExecutionPolicy Bypass -NoProfile -File \\UNC\to\Script.ps1"

And having all execution inside the .ps1.

Note that you'll come as 'NT AUTHORITY\SYSTEM' to that UNC path, appropriate permissions are necessary.

Upvotes: 0

evilSnobu
evilSnobu

Reputation: 26314

PowerShell uses the unfortunate backtick (`) as the escape char. Backslash has no special meaning. Better yet, little known trick, use --%.

schtasks.exe --% /F /Create /TN "My Task" /TR "powershell (New-Object System.Net.WebClient).DownloadString('http://mywebserver/myscript.ps1') | powershell.exe -noprofile" /SC MINUTE /mo 60 /RL HIGHEST

Which basically means, "Dear PowerShell parser, find schtasks.exe in the path, run it and pass it whatever comes after '--%' EXACTLY as it is."

Upvotes: 1

Related Questions