我有一个 powershell 脚本,它创建计划任务作为自动化过程的一部分,我的语法如下;
schtasks /create /s ServerName /u $username /p $password /ru $username /rp $password /sc once /sd $StartDate /st $StartTime /tn $taskname /tr "\\ServerName\c$\$TaskName\$Taskname.bat"
任务创建成功,但是执行时间到了,总是失败并出现错误(0X1)。
如果我单独运行批处理文件,它可以完美运行;所以我的计划任务创建错误。
然后我发现当我为它提供“起始”目录路径时它可以工作。
我的问题是,当任务属性中清楚地写着“可选”时,为什么我应该提供路径的起点?
我的另一个问题是如何提供起始路径?尝试了很多方法,但都失败了,没有自动化的方法吗?我应该手动更新每个任务吗?
答案1
我的问题是,当任务属性中清楚地写着“可选”时,为什么我应该提供路径的起点?
举例来说,假设我正在创建一个运行 Powershell 脚本的计划任务:
为什么这是错误的?首先,我们不确定 powershell.exe 是否能正确解析,因为我们不知道执行计划任务的用户是否正确设置了其 PATH 环境变量。根据您将任务设置为以谁的身份运行(无论是系统用户还是域用户),他们的 PATH 变量会有所不同。有时它可以正常工作,powershell.exe 可以正确启动,但为什么不继续进行猜测并指定 powershell.exe 可执行文件的完全限定路径名呢?
其次,script.ps1 在哪里?您没有指定。Powershell 将启动,其启动目录将是%WINDIR%\System32
。除非那是您存储脚本的地方(我希望不是),否则 Powershell 将无法找到它。
现在情况好多了,因为我们为可执行文件和脚本都指定了完全限定的路径名。但我们还没有明白“起始于(可选)”的用途。好吧,等一下,我们马上就明白了。
的内容script.ps1
如下:
"Hello world!" | Out-File test.txt
因此,如果我现在运行上述计划任务,启动 Powershell,运行 script.ps1,您认为 test.txt 会写入哪里?
如果您猜对了%WINDIR%\System32
,那么您就会得到一块饼干!
如果我想要转到 test.txt C:\Scripts
,那么我会C:\Scripts
在“开始于(可选)”字段中输入!
这就是为什么它是可选的。
我还应该指出,您也可以通过在脚本中使用完全限定的路径名来解决此问题,以便将内容放到您希望它们去的地方,而不必担心 PATH 变量和工作目录。
现在来谈谈第二个问题。
schtasks.exe 似乎没有添加计划任务的“开始于”或“工作目录”的功能。真糟糕。
您可以做的一件事是使用 Task Scheduler 2.0 任务的 XML,它允许您设置工作目录。这是我为这个问题创建的测试任务的 XML:
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2013-07-19T09:41:27.0446696</Date>
<Author>DOMAIN\user</Author>
</RegistrationInfo>
<Triggers />
<Principals>
<Principal id="Author">
<UserId>DOMAIN\user</UserId>
<LogonType>InteractiveToken</LogonType>
<RunLevel>LeastPrivilege</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>P3D</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command>
<Arguments>C:\Scripts\script.ps1</Arguments>
<WorkingDirectory>C:\Scripts</WorkingDirectory>
</Exec>
</Actions>
</Task>
您可以使用schtasks /XML
脚本从 XML 文件导入任务。
答案2
我自己也遇到过这种情况。就我而言,问题是由于脚本本身的错误造成的,尽管错误发生在脚本执行过程中永远不会到达的部分。
要解决该问题,您应该尝试以将要运行脚本的用户身份运行整个操作。例如,首先以目标用户身份(如果不是您自己)打开 PowerShell:
RunAs /user:domain\serviceaccount PowerShell.exe
然后在 PowerShell 中运行整个操作块并查看是否遇到任何错误:
PowerShell.exe -ExecutionPolicy Bypass -File "C:\Scripts\My-Automated-Task.ps1"