Powershell 脚本不通过计划任务运行
Posted
技术标签:
【中文标题】Powershell 脚本不通过计划任务运行【英文标题】:Powershell script does not run via Scheduled Tasks 【发布时间】:2013-08-18 01:42:38 【问题描述】:我的域控制器上有一个小脚本,它设置为通过 SMTP 向我发送有关最新安全事件 4740 的电子邮件。
脚本在手动执行时将按预期运行;但是,当设置为通过计划任务运行时,虽然它显示已执行,但没有任何反应(没有电子邮件)。
脚本如下:
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
$Event = Get-EventLog -LogName Security -InstanceId 4740 -Newest 5
$MailBody= $Event.Message + "`r`n`t" + $Event.TimeGenerated
$MailSubject= "Security Event 4740 - Detected"
$SmtpClient = New-Object system.net.mail.smtpClient
$SmtpClient.host = "smtp.domain.com"
$MailMessage = New-Object system.net.mail.mailmessage
$MailMessage.from = "fromemail@domain.com"
$MailMessage.To.add("toemail.domain.com")
$MailMessage.IsBodyhtml = 1
$MailMessage.Subject = $MailSubject
$MailMessage.Body = $MailBody
$SmtpClient.Send($MailMessage)
计划任务设置如下:
RunsAs:LOCAL SYSTEM
Trigger: On event - Log: Security, Event ID: 4740
Action: Start Program - C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Argument: -executionpolicy bypass c:\path\event4740.ps1
我还尝试了以下方法:
Trigger: On event - Log: Security, Event ID: 4740
Action: Start Program - C:\path\event4740.ps1
根据任务历史记录:任务已启动、操作已启动、已创建任务流程、操作已完成、任务已完成。我浏览了网站上的一些具有相同“问题”的各种链接,但它们似乎都有某种我没有的变量。我也尝试了一些提到的解决方案,认为它们可能有些相关,但可惜没有任何效果。我什至尝试删除我的计划任务并按照此处所述重置它:http://blogs.technet.com/b/heyscriptingguy/archive/2012/08/11/weekend-scripter-use-the-windows-task-scheduler-to-run-a-windows-powershell-script.aspx
有没有人遇到过此类错误或知道如何绕过此问题?
疑难解答:
我决定尝试通过计划任务调用 .bat 文件。我创建了一个简单的文件,它将当前日期/时间回显到受监控的文件夹。手动运行文件并通过 4740 事件触发的任务获得了预期的结果。将 .bat 文件改为手动调用 .ps1 文件。当被 4740 事件触发时,.bat 将不再运行。
【问题讨论】:
感谢@Amit 的提醒,尽管问题在没有受到批评或与印刷错误相关的情况下得到解决。 我明白了。我在这里提到这一点只是因为我打算在将来使用这个问题作为说明/参考,因为我将不可避免地向1 Picture > 1 Kiloword
的人解释。除了可能导致此类问题的 runas 帐户之外,任务计划程序中还有许多其他选项,您没有列出。错字是绝对相关的,因为 localsystem 和 localservice 在权利方面是截然相反的。此外,您的解决方法是在 域服务器 上永久锁定会话,这听起来确实是解决此问题的错误且不安全的方法。
通过完全限定 powershell.exe,我能够让脚本在任务管理器中运行,但存在同样的问题。 “C:\...\...\powershell.exe”作为程序/脚本。
【参考方案1】:
将您的操作更改为:
powershell -noprofile -executionpolicy bypass -file C:\path\event4740.ps1
在 Windows 2008 服务器 R2 上:在“常规”选项卡下的“任务计划程序”中 - 确保将“运行身份”用户设置为具有执行脚本所需的正确权限的帐户。
另外,我相信您已选中“仅在用户登录时运行”选项。将其更改为“无论用户是否登录都运行”。不选中“不存储密码”选项,您可能需要标记“以最高权限运行”选项。
【讨论】:
嘿科尔,感谢您的回复。我已经尝试过你的建议;但是,我遇到了同样的情况。我可以调用 4740 事件,任务计划程序显示它确认事件并启动该过程,但仍然没有发生任何事情。我之前也尝试过 -noexit 开关,但是当 Powershell 永远不会打开时似乎没有任何帮助。 接下来我要尝试更改的是 RunAs 本地系统。当您在 runas 中输入一个实际的管理员帐户时会发生什么,该帐户对发送 PC 和 smtp 服务器都具有权限? 对不起,它实际上是本地服务。由于当前存在安全限制和组策略,没有用户具有“作为批处理作业登录”权限。如果您认为这可能是问题所在,我可以注入一个帐户并重试。 我不能保证它会解决您的问题,但值得一试。该任务应该是 RunAs SYSTEM 或在管理员帐户下 注入我的用户帐户(管理员)并试一试。这一次,任务挂在“创建的任务进程”上,必须手动停止。【参考方案2】:找到适用于我的方案的成功解决方法:
不要注销,只需锁定会话!
由于此脚本在域控制器上运行,我通过远程桌面控制台登录到服务器,然后注销服务器以终止我的会话。在任务计划程序中设置任务时,我使用的用户帐户和本地服务无权在脱机模式下运行,或者严格登录以运行脚本。
感谢 Cole 提供的一些故障排除帮助,我开始考虑 RunAs 功能并决定尝试解决无法正常工作的登录问题。
从任务计划程序开始,我删除了手动创建的任务。使用 Server 2008 R2 中的新功能,我在事件查看器中导航到 4740 安全事件,并使用右键单击 > 将任务附加到此事件...并按照提示,在操作页面上指向我的脚本。创建任务后,我锁定了会话并终止了远程桌面控制台连接。在配置文件“锁定”且未注销的情况下,一切正常。
【讨论】:
【参考方案3】:除了上面的建议之外,我还遇到了错误,并在以下链接 http://blog.vanmeeuwen-online.nl/2012/12/error-value-2147942523-on-scheduled.html 上找到了解决方案。
这也有帮助:
在任务计划程序中,单击计划作业属性,然后单击设置。
在最后列出的选项中: “如果任务已经在运行,则适用以下规则:” 从下拉列表中选择“停止现有实例”。
【讨论】:
【参考方案4】:在尝试了很多时间之后......
任务调度程序:powershell.exe -noexit & .\your_script.ps1
一定要把你的脚本放在这个文件夹中:windows\system32
祝你好运!
【讨论】:
【参考方案5】:尽管您可能已经找到解决问题的方法,但我仍将发布此说明以帮助其他人。我遇到了类似的问题。 我基本上使用不同的域帐户来测试和比较。选中“无论用户是否登录都运行”,该任务运行得很好。
需要牢记并确保以下几点:
-
用于执行任务的帐户必须在服务器的本地安全策略下具有“作为批处理作业登录”权限(或者是本地管理员组的成员)。您必须指定运行脚本/bat 文件所需的帐户。
确保您输入的密码字符正确
如果您将 2008 R2 中的任务作为“无论用户是否登录都运行”来运行,它们不会以交互方式运行。如果在创建任务时在脚本上查找特定于用户配置文件的任何对象\资源,这可能会特别失败,因为 powershell 会话将需要该信息才能启动,否则它将启动并立即结束。
作为在运行脚本时将 $Path 定义为“无论用户是否登录都运行”的示例,我指定了一个映射驱动器。它会在任务开始时查找该驱动器,但是由于验证运行任务的用户帐户未登录并且在脚本上您指回它需要针对它工作的源\对象不存在任务将只是终止。
映射驱动器 (\server\share) x:\ 与实际 UNC 路径 \server\share
查看您的步骤、脚本、参数。有时即使您已经多次执行此过程,最小的部分也会产生很大的不同。在构建脚本或任务时,我在输入密码或分号时多次漏掉了一个字符。
检查此链接,希望您或其他人可以从此信息中受益:https://technet.microsoft.com/en-us/library/cc722152.aspx
【讨论】:
这是我在通过客户端 DLL 访问 TFS API 时遇到的问题。奇怪的是,它只与 Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore 相关。非常感谢! 这个答案成功结束了一整天的调试会话。确保我的任务仅在用户登录时运行是我脚本的答案;否则我的脚本运行“成功”并且没有错误,但仍然无法完成这项工作。谢谢!【参考方案6】:我遇到了与此几乎相同的问题,但在 Server 2012 R2 上略有不同。我在任务计划程序中有一个 powershell 脚本,它将 3 个文件从一个位置复制到另一个位置。如果我从 powershell 手动运行脚本,它就像一个魅力。但是当从任务计划程序运行时,它只复制前 2 个小文件,然后挂在第 3 个(大文件)。而且我也得到了“操作员或管理员拒绝请求”的结果。我在这个论坛上几乎做了所有事情。
这是场景以及我如何为我修复它。可能对其他人不起作用,但以防万一:
场景: 1.任务计划程序中的Powershell脚本 2.使用域帐户运行,该帐户是服务器上的本地管理员 3.选择“无论用户是否登录都运行” 4. 以最高权限运行
修复: 1. 我必须使用域帐户登录到服务器,以便它在 C:\Users 中创建本地配置文件。 2. 检查并确认用户有权访问我在脚本中提到的所有驱动器
我相信 #1 是我的主要解决方案。我希望这对其他人有用。
【讨论】:
您也可以使用-noprofile
运行,例如:powershell.exe -noprofile -ExecutionPolicy Bypass -File foo.ps1
【参考方案7】:
我认为这个问题的答案也很重要:
Why is my Scheduled Task updating its 'Last Run Time' correctly, and giving a 'Last Run Result' of '(0x0)', but still not actually working?
总结:Windows 2012 计划任务不看到正确的环境变量,包括PATH
,对于设置为运行任务的帐户。但是您可以对此进行测试,如果它正在发生,并且一旦您了解正在发生的事情,您就可以解决它。
【讨论】:
另外,不注销会改变这一点,并且基本上可以修复它,所以它可能(?)与这里关于不注销的答案有关?【参考方案8】:实现了ExecutionPolicy Bypass
参数以使计划任务正常工作。
Program: Powershell.exe
Add Arguments: -ExecutionPolicy Bypass -File C:\pscommandFile.ps1
【讨论】:
像“以管理员身份运行”一样运行脚本并不是 -ExecutionPolicy Bypass 标志的作用。该标志仅允许脚本运行而不管当前系统 PowerShell ExecutionPolicy。【参考方案9】:注意:请确保您选择创建基本任务操作而不是创建任务操作。
我找到了以下解决方案:
1) 让
powershell.exe
以管理员身份运行
-
右击
powershell.exe
图标
点击快捷键菜单下的属性
点击前进按钮;检查“以管理员身份运行”是
检查。
2) 在操作窗格下的任务计划程序窗口中添加 以下脚本作为新命令
%SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe -NoLogo -NonInteractive -ExecutionPolicy Bypass -noexit -File "C:\ps1\BackUp.ps1"
【讨论】:
这对我有用,它是文件名周围的引号,这很荒谬......程序脚本:C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
参数:--noprofile -executionpolicy unrestricted -noninteractive -file "path\to\my\powershellscriptps1"
和 Start In c:\MyPath\to\pwoershel\lscript
【参考方案10】:
如果您在 WIN 10 下遇到此问题,这可能会像对我一样解决您的问题。更新搞砸了任务调度程序。
http://answers.microsoft.com/en-us/windows/forum/windows_10-performance/anniversary-update-version-1607-build14393-breaks/d034ab52-5d49-4b92-976a-a1355b5a6e6d?page=2
这条评论解决了我的问题。
您关于“一次性”任务的提示效果很好 - 肯定会 足以作为解决方法,直到 MS 解决问题。唯一的 据我所知,“每日”的优势在于缺乏任意性 与运行时间关联的日期。这可能会让其他人感到困惑,因为 为什么将作业设置为 X 日期开始。
Trigger settings "Einmal" means "one-time", "Sofort" means "At once"
【讨论】:
【参考方案11】:在我的情况下(同样的问题)有助于在任务操作命令参数中添加 -NoProfile 并选中“以最高权限运行”复选框,因为在我的服务器上 UAC 处于启用状态。
关于它的更多信息 enter link description here
【讨论】:
【参考方案12】:对于这个问题,我有另一种可能适用于你们中的一些人的解决方案。
在我创建了我的 power shell (xyz.ps1) 脚本后,我在记事本中打开了它以进行后续编辑。因此,Windows 在我的 xyz.ps1 文件与 notepad.exe 之间建立了关联,并且调度程序试图在后台使用 notepad.exe 运行我的 power shell 脚本 (xyz.ps1),而不是在 Powershell 中执行它。我通过密切关注调度程序中的“显示所有正在运行的任务”部分发现了这个问题,这表明 notepad.exe 被用于运行 xyz.ps1 脚本。为了验证这一点,我在 Windows 资源管理器中右键单击我的 xyz.ps1 文件,转到“属性”,它在“打开方式”部分显示记事本。然后我将“打开方式”更改为 %SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe。这成功了。现在调度程序将使用 powershell.exe 执行我的 xyz.ps1 并给我想要的结果。
要找到您的 powershell.exe,请参阅这篇文章: https://www.powershelladmin.com/wiki/PowerShell_Executables_File_System_Locations
【讨论】:
【参考方案13】:如果您没有任何错误消息并且不知道问题所在 - 为什么 PowerShell 脚本不想从计划任务开始,请执行以下步骤以获得答案:
-
以已设置计划任务的用户身份运行 CMD 以执行 PowerShell 脚本
浏览到 PowerShell 脚本所在的文件夹
执行 PowerShell 脚本(删除所有阻止错误通知的语句(如果脚本中存在 $ErrorActionPreference= 'silentlycontinue'))
您应该能够看到所有错误通知。
如果我的脚本之一是:
“找不到类型 [System.ServiceProcess.ServiceController]。请确保已加载包含此类型的程序集。”
在这种情况下,我必须在脚本开头添加额外的行来加载缺少的程序集:
Add-Type -AssemblyName "System.ServiceProcess"
还有下一个错误:
使用“1”参数调用“GetServices”的异常:“无法在计算机''上打开服务控制管理器。此操作可能需要其他权限。”
select : 无法处理该属性,因为属性“数据库名称”已存在
【讨论】:
不错!简单而有效的 cmd.exe 来救援。这立即向我显示了一个错误,表明我在哪里愚蠢。 :)【参考方案14】:我遇到了非常相似的问题,当手动运行计划任务时,我一直在使用 powershell 脚本保留 VSC 窗口。刚刚关闭它,它开始按预期工作。
【讨论】:
【参考方案15】:还有一个可行的想法。这真的很愚蠢,但显然,默认的目标操作系统设置(屏幕右下角)是Vista / Windows Server 2008
。由于我们已经过了 10 年,您的 Powershell 脚本很可能与这些脚本不兼容。
将目标更改为 Windows Server 2016,如下面的屏幕截图所示,对我有用。
【讨论】:
【参考方案16】:我在运行这两个脚本时遇到了同样的问题。当我从任务计划程序手动执行它时,该脚本执行完美。 但它并没有在预定的时间自动执行。
以下解决方案对我有用
找到powershell exe的位置,右键点击安全选项,将“Authenticated users”添加到组或用户名中,并给予完全控制。
一旦完成,等待脚本执行。
【讨论】:
【参考方案17】:在我的情况下,它与 ps1 脚本中未签名的 .ps1 引用有关(您需要在文件属性中取消阻止它),我也将其添加为第一行:
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force
然后就成功了
【讨论】:
【参考方案18】:我对这个问题的解决方法是确保我使用 ps1 文件中所有文件名的完整路径。
【讨论】:
【参考方案19】:早上好,
我知道这是一个旧线程,但我只是在寻找类似问题时遇到了它 - 脚本成功运行但没有完成它的工作。我找不到对我有帮助的帖子,但我的问题是我以域管理员身份运行脚本。当我按照帖子的建议将域管理员添加到本地管理员组时,它就起作用了。我希望这可以帮助其他人解决我遇到的同样问题。
乔
【讨论】:
【参考方案20】:我有一个类似的问题,其中只有一半的脚本可以使用任务调度程序运行,但在手动运行脚本的同一帐户下可以正常运行。问题是我引用了我自己的模块。当我将这些函数直接添加到我的脚本文件中时,任务调度程序可以工作,但是当我使用模块任务调度程序时失败了。在相同帐户下运行的相同编码(模块)在没有任务调度程序的情况下也能正常工作。
我认为这是 Windows 如何处理运行时环境变量的某种类型的问题。当我通过完整路径(而不是模块名称)引用模块时,它从任务调度程序中工作。
【讨论】:
以上是关于Powershell 脚本不通过计划任务运行的主要内容,如果未能解决你的问题,请参考以下文章
powershell 用于运行powershell脚本的计划任务条目