gjj*_*hh_ 6 windows powershell cmd scheduled-tasks windows-task-scheduler
我需要安排一个 PowerShell 任务,如下所示:
powershell.exe -file ..\Execute\execute.ps1
Run Code Online (Sandbox Code Playgroud)
我尝试将它分配给一个参数,$Argument然后将其传递给schtasks如下所示:
$Argument = "powershell.exe -file '..\Execute\execute.ps1'"
schtasks /create /tn "SOE_Checks" /tr $Argument /sc DAILY /st 05:00 /ru "System" /rl HIGHEST /f
Run Code Online (Sandbox Code Playgroud)
但是在运行上面的代码后,什么也没发生 - 虽然任务创建成功,但它似乎没有运行。
我也尝试将它分配给$Argument没有引号,它有效,但我收到以下警告:
ERROR: Invalid syntax. Value expected for '/tr'.
Type "SCHTASKS /CREATE /?" for usage.
Run Code Online (Sandbox Code Playgroud)
谁能让我知道我在这里做错了什么?(我知道我可以使用 PowerShell 完成此操作,New-ScheduledTaskAction但我希望它以这种方式工作)
只是想补充一点,如果我改变的文件路径的特定位置$Argument这样的,$Argument = "powershell.exe -file 'C:\SOE\Execute\execute.ps1'",它工作正常,没有任何警告,但这并不理想。
我已经阅读了这篇文章,但它对我不起作用
schtasks.exe使用执行创建的计划任务将工作目录设置为$env:windir\system32[1],因此除非您的脚本恰好位于..\Execute\execute.ps1相对于那里的位置,否则您的命令将无法按预期工作。
如果您不想将脚本路径直接硬编码到命令中,请动态构造命令,方法是在分配给时将相对路径解析为绝对$Argument路径:
$Argument = 'powershell.exe -file \"{0}\"' -f (Convert-Path ..\Execute\execute.ps1)
Run Code Online (Sandbox Code Playgroud)
请注意 - 不幸的是 - 需要转义嵌入的"as \",这是一个长期存在的错误,为了向后兼容性尚未修复 - 请参阅此 GitHub 文档问题了解背景。
Convert-Path将相对路径解析为绝对路径。
请注意,相对路径必须引用现有文件(或目录)。
同样,脚本内的相对路径也将相对于$env:windir\system32; 要使它们相对于脚本的目录,请首先通过Set-Location $PSScriptRoot在脚本开头执行来更改到脚本的目录。
注意:实际上,应用的规则与从 Windows“运行”对话框(按 )运行命令时适用的规则相同,您WinKey+R可以使用它来测试驱动命令(要传递到 的命令schtasks /tr,不带外部引号,而不是整个schtasks命令行) - 不过请注意,工作目录将是用户的主目录,并且您将无法'...'在 PowerShell CLI 的-File参数周围使用 - 引号 - 见下文):
cmd.exe执行过程中不参与,这意味着:
cmd.exe例如,您不必担心元字符(例如)的非双引号使用&,因此您甚至可以在作为参数(一部分)传递到 PowerShell CLI 的单引号字符串中使用这些字符。powershell.exe-Command
相反,不直接> c:\path\to\log.txt支持输出重定向(例如, )。
在调用 PowerShell CLI 的上下文中,这意味着:
使用 时-File,您无法在命令行上使用它们,而必须在脚本中执行它们。
但是-Command,通过 ,您可以使用它们,因为随后是PowerShell应用它们(但请注意,Windows PowerShell 的>操作员创建 UTF-16LE 文件)。
(虽然cmd.exe 不涉及)使用与中相同的语法形式对环境变量的引用进行了扩展cmd.exe (例如,%USERNAME%)
%%不起作用 - 附加值%被简单地视为文字,并且扩展仍然发生;例如,%%OS%%结果为%Windows_NT%.^%(意外地)防止扩展,但保留^- the^不会转义;相反,它“破坏”了变量名,在这种情况下,令牌保持原样;例如,^%OS^%结果为^%OS^%,即按原样保留。上述内容适用于命令,因为它们必须最终在计划任务中定义,就像您在任务计划程序 ( taskschd.msc) 中以交互方式看到或定义它们一样。
此外,要从命令行/PowerShell 脚本/批处理文件创建计划任务:
您必须引用整个命令并且
遵守调用 shell 关于转义和预先字符串插值的语法规则。
(你只能逃走如果命令仅包含一个不需要转义的单词,例如不包含空格或特殊字符且不传递任何参数的可执行文件的路径,则只能在不引用的情况下退出。)
当调用schtasks.exe[2]时,引用/tr整个参数,如下所示:
在 PowerShell 中"...",如果需要预先扩展(字符串插值)命令字符串,请使用;否则,使用'...'.
重要提示:需要转义嵌套 "为\",在外部引用的情况下"..."意味着嵌套"必须转义为\`"(sic)。
schtasks.exe它可以识别嵌入的 '...'引用并自动将其转换为"..."引用- 这就是为什么您的原始命令 ,"powershell.exe -file '..\Execute\execute.ps1'"有效,即使在直接调用中 PowerShell CLI不会'...'与 结合使用-File。来自cmd.exe(无论是直接还是来自批处理文件),您必须使用"...".
PowerShell 示例:
以下 PowerShell 命令创建并执行两个运行一次的计划任务,名为test1它们test2在下一个日历分钟开始时在调用用户的上下文中运行。(之后您必须手动删除这些任务。)
您可能需要等待最多 1 分钟才能看到调用启动,此时将为每个任务弹出一个新的控制台窗口。
# Create sample script test.ps1 in the current dir. that
# echoes its arguments and then waits for a keypress.
'"Hi, $Args."; Read-Host "Press ENTER to exit"' > test.ps1
# Find the start of the next calendar minute.
$nextFullMinute = ([datetime]::Now.AddMinutes(1).TimeOfDay.ToString('hh\:mm'))
# -File example:
# Invoke test.ps1 and pass it 'foo' as an argument.
# Note the escaped embedded "..." quoting around the script path
# and that with -File you can only pass literal arguments at
# invocation time).
schtasks.exe /create /f /tn test1 /sc once /st $nextFullMinute `
/tr "powershell -File \`"$PWD/test.ps1\`" foo" #`# (dummy comment to fix broken syntax highlighting)
# -Command example:
# Invoke test.ps1 and pass it $env:USERNAME as an argument.
# Note the '...' around the script path and the need to invoke it with
# &, as well as the ` before $env:USERNAME to prevent its premature expansion.
schtasks.exe /create /f /tn test2 /sc once /st $nextFullMinute `
/tr "powershell -Command & '$PWD/test.ps1' `$env:USERNAME"
"Tasks will execute at ${nextFullMinute}:00"
Run Code Online (Sandbox Code Playgroud)
[1] 请注意,任务计划程序 GUI 允许您配置工作目录,但此功能无法通过schtasks.exe实用程序使用。
[2] 这同样适用于传递给PowerShell cmdlet-Argument参数的值New-ScheduledTaskAction,但请注意,可执行文件名称/路径是通过-Execute参数单独指定的。
相比之下,Register-ScheduledJob用于创建计划的 PowerShell作业的cmdlet接受脚本块作为要运行的命令,这消除了引用问题。
| 归档时间: |
|
| 查看次数: |
4038 次 |
| 最近记录: |