情况
在我们的组织中,我创建了一个 GPO,用于创建计划任务。此任务在两个用户帐户登录时触发。
它执行一个 powershell 脚本,更改网络连接的 DNS 服务器。(使用 dnsmasq 为这些用户屏蔽一些网站。我知道这不是万无一失的解决方案,但它已经足够好了。)
计划任务的操作是该命令:
C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe
这些是参数:
-ExecutionPolicy Bypass –NoProfile –Command "& {C:\ProgramData\ORGNAME\scripts\SetDNS.ps1}" > C:\ProgramData\ORGNAME\scripts\SetDNS.log
如您所见,输出被发送到日志文件。
这是脚本的内容:
$wmi = get-wmiobject Win32_NetworkAdapterConfiguration -filter "ipenabled = 'true'"
foreach($adapter in $wmi)
{
if($adapter.description -NotLike "*VMware*")
{
$adapter.SetDNSServerSearchOrder("XXX.XXX.XXX.XXX")
}
}
invoke-expression -command "c:\windows\system32\ipconfig /flushdns"
问题
问题是,这个方法运行正常,大约 10 次中有 9 次都有效。当它不起作用时,任务调度程序仍会报告退出代码 0,但似乎脚本甚至没有开始执行,因为什么都没有发生,也没有创建日志文件。
一些额外的信息
- 该任务在 SYSTEM 帐户下运行
- 它以最高权限运行
- 当任务按需运行时,它工作正常
- 所有计算机均运行 Windows 7 企业版 (x64)
我尝试过的一些方法
我认为任务计划程序可能触发脚本太快并且某些东西可能尚未初始化,所以我尝试设置 30 秒的延迟。
每 5 分钟重新运行一次任务,持续 15 分钟。
当任务失败时重新启动该任务,这显然不起作用,因为 powershell.exe 似乎返回错误代码 0。
答案1
我认为任务计划程序报告的退出代码用于运行 powershell.exe 而不是您的脚本。
尝试将其改为这样:
-ExecutionPolicy Bypass –NoProfile –Command "& {C:\ProgramData\ORGNAME\scripts\SetDNS.ps1; exit $LastExitCode}" > C:\ProgramData\ORGNAME\scripts\SetDNS.log
$LastExitCode
有你的脚本的退出代码,你必须将它上升一个级别到任务调度程序。
Exit
在脚本中添加一些错误处理并使用语句设置实际的退出代码也是一个好主意。
答案2
从脚本参数中删除-Command
并改用-File
。 命令应该在您输入 powershell 命令但有一个脚本文件时使用。
细节这里