windows Powershell 脚本不通过计划任务运行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18259951/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 10:47:19  来源:igfitidea点击:

Powershell script does not run via Scheduled Tasks

windowspowershellscheduled-tasks

提问by ThinkSpace

I have a small script on my Domain Controller that is setup to email me via SMTP about the latest Security Event 4740.

我的域控制器上有一个小脚本,该脚本设置为通过 SMTP 向我发送有关最新安全事件 4740 的电子邮件。

The script, when executed manually, will run as intended; however, when setup to run via Scheduled Tasks, and although it shows to have been executed, nothing happens (no email).

手动执行时,脚本将按预期运行;但是,当设置为通过计划任务运行时,尽管它显示已执行,但没有任何反应(没有电子邮件)。

The script is as follows:

脚本如下:

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 = "[email protected]"
$MailMessage.To.add("toemail.domain.com")
$MailMessage.IsBodyHtml = 1
$MailMessage.Subject = $MailSubject
$MailMessage.Body = $MailBody
$SmtpClient.Send($MailMessage)

Scheduled Task is setup as follows:

计划任务设置如下:

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

I have also tried the following:

我还尝试了以下方法:

Trigger: On event - Log: Security, Event ID: 4740

Action:  Start Program - C:\path\event4740.ps1

According to the Tasks History: Task Started, Action Started, Created Task Process, Action Completed, Task Completed. I have looked through some various links on the site with the same 'issue' but they all seem to have some sort of variable that I do not have. I have also tried some of the mentioned solutions thinking they may be somewhat related, but alas nothing is working. I have even tried removing my Scheduled Task and resetting it as mentioned here: http://blogs.technet.com/b/heyscriptingguy/archive/2012/08/11/weekend-scripter-use-the-windows-task-scheduler-to-run-a-windows-powershell-script.aspx

根据任务历史记录:任务已启动、操作已启动、已创建任务流程、操作已完成、任务已完成。我浏览了网站上具有相同“问题”的一些不同链接,但它们似乎都有某种我没有的变量。我也尝试了一些提到的解决方案,认为它们可能有些相关,但是没有任何效果。我什至尝试删除我的计划任务并按照此处所述重置它:http: //blogs.technet.com/b/heyscriptingguy/archive/2012/08/11/weekend-scripter-use-the-windows-task-scheduler -to-run-a-windows-powershell-script.aspx

Has anyone run into this type of error before or know how to bypass this issue?

有没有人遇到过这种类型的错误或知道如何绕过这个问题?

Troubleshooting:

故障排除:

I decided to try an call a .bat file via a scheduled task. I created a simple file that would echo the current date/time to a monitored folder. Running the file manually and via a task triggered by the 4740 Event achieved desired results. Changing the .bat file to instead call the .ps1 file worked manually. When triggered by the 4740 Event, now the .bat will no longer run.

我决定尝试通过计划任务调用 .bat 文件。我创建了一个简单的文件,它将当前日期/时间回显到一个受监控的文件夹。手动和通过 4740 事件触发的任务运行文件达到了预期的结果。将 .bat 文件更改为手动调用 .ps1 文件。当由 4740 事件触发时,现在 .bat 将不再运行。

采纳答案by ThinkSpace

Found successful workaround that is applicable for my scenario:

找到了适用于我的场景的成功解决方法:

Don't log off, just lock the session!

不要注销,只需锁定会话!

Since this script is running on a Domain Controller, I am logging in to the server via the Remote Desktop console and then log off of the server to terminate my session. When setting up the Task in the Task Scheduler, I was using user accounts and local services that did not have access to run in an offline mode, or logon strictly to run a script.

由于此脚本在域控制器上运行,我通过远程桌面控制台登录到服务器,然后从服务器注销以终止我的会话。在任务计划程序中设置任务时,我使用的用户帐户和本地服务无权在离线模式下运行,或严格登录以运行脚本。

Thanks to some troubleshooting assistance from Cole, I got to thinking about the RunAs function and decided to try and work around the non-functioning logons.

感谢 Cole 提供的一些故障排除帮助,我开始考虑 RunAs 功能并决定尝试解决无法运行的登录问题。

Starting in the Task Scheduler, I deleted my manually created Tasks. Using the new function in Server 2008 R2, I navigated to a 4740 Security Event in the Event Viewer, and used the right-click > Attach Task to this Event... and followed the prompts, pointing to my script on the Action page. After the Task was created, I locked my session and terminated my Remote Desktop Console connection. WIth the profile 'Locked' and not logged off, everything works like it should.

从任务计划程序开始,我删除了手动创建的任务。使用 Server 2008 R2 中的新功能,我导航到事件查看器中的 4740 安全事件,并使用右键单击 > 将任务附加到此事件...并按照提示操作,在操作页面上指向我的脚本。创建任务后,我锁定了会话并终止了远程桌面控制台连接。在配置文件“锁定”且未注销的情况下,一切正常。

回答by Cole9350

Change your Action to:

将您的操作更改为:

powershell -noprofile -executionpolicy bypass -file C:\path\event4740.ps1

powershell -noprofile -executionpolicy bypass -file C:\path\event4740.ps1

On a Windows 2008 server R2: In Task Scheduler under the General Tab - Make sure the 'Run As' user is set to an account with the right permissions it takes to execute the script.

在 Windows 2008 服务器 R2 上:在常规选项卡下的任务计划程序中 - 确保将“运行身份”用户设置为具有执行脚本所需的正确权限的帐户。

Also, I believe you have the "Run only when user is logged on" Option checked off. Change that to "Run whether user is logged on or not". Leave the Do Not Store password option unchecked, and you'll probably need the "Run with Highest Privileges" option marked.

另外,我相信您已选中“仅在用户登录时运行”选项。将其更改为“无论用户是否登录都运行”。不选中“不存储密码”选项,您可能需要标记“以最高权限运行”选项。

回答by Prognox

Although you may have already found a resolution to your issue, I'm still going to post this note to benefit someone else. I ran into a similar issue. I basically used a different domain account to test and compare. The task ran just fine with "Run whether user is logged on or not" checked.

尽管您可能已经找到了问题的解决方案,但我仍将发布此说明以让其他人受益。我遇到了类似的问题。我基本上使用不同的域帐户进行测试和比较。该任务运行得很好,选中了“无论用户是否登录都运行”。

A couple of things to keep in mind and make sure of:

要记住并确保以下几点:

  1. The account being use to execute task must have "Logon as batch job" rights under the local security policy of the server (or be member of local Admin group). You must specified the account you need to run scripts/bat files.
  2. Make sure you are entering the correct password characters
  3. Tasks in 2008 R2 don't run interactively specially if you run them as "Run whether user is logged on or not". This will likely fail specially if on the script you are looking for any objects\resource specific to a user-profile when the task was created as the powershell session will need that info to start, otherwise it will start and immediately end. As an example for defining $Path when running script as "Run whether user is logged on or not" and I specify a mapped drive. It would look for that drive when the task kicks off, but since the user account validated to run task is not logged in and on the script you are referring back to a source\object that it needs to work against it is not present task will just terminate. mapped drive (\server\share) x:\ vs. Actual UNC path \server\share
  4. Review your steps, script, arguments. Sometimes the smallest piece can make a big difference even if you have done this process many times. I have missed several times a character when entering the password or a semi-colon sometimes when building script or task.
  1. 用于执行任务的帐户必须具有服务器本地安全策略下的“作为批处理作业登录”权限(或者是本地管理员组的成员)。您必须指定运行脚本/bat 文件所需的帐户。
  2. 确保输入正确的密码字符
  3. 如果您将 2008 R2 中的任务作为“无论用户是否登录都运行”来运行它们,则它们不会专门以交互方式运行。如果在创建任务时在脚本上查找特定于用户配置文件的任何对象\资源,这可能会特别失败,因为 powershell 会话将需要该信息才能启动,否则它将启动并立即结束。作为在运行脚本时将 $Path 定义为“无论用户是否登录都运行”的示例,我指定了一个映射驱动器。它会在任务开始时查找该驱动器,但由于验证为运行任务的用户帐户未登录,并且在脚本上,您正在引用它需要对其进行处理的源\对象不存在任务将只是终止。映射驱动器 (\server\share) x:\ 与实际 UNC 路径 \server\share
  4. 查看您的步骤、脚本、参数。有时,即使您已经多次执行此过程,最小的部分也可以产生很大的不同。在构建脚本或任务时,有时我在输入密码或分号时错过了几次字符。

Check this link and hopefully you or someone else can benefit from this info: https://technet.microsoft.com/en-us/library/cc722152.aspx

检查此链接,希望您或其他人可以从此信息中受益:https: //technet.microsoft.com/en-us/library/cc722152.aspx

回答by Case 303

To achieve "Run as Administrator" functionality I implemented the flag:

为了实现“以管理员身份运行”功能,我实现了以下标志:

-ExecutionPolicy Bypass

Which only seems to take effect when executing Powershell files. So I dropped my command into .ps1 file, run it with -ExecutionPolicy Bypass, and now my scheduled task is behaving as expected.

这似乎只在执行 Powershell 文件时生效。所以我把我的命令放到 .ps1 文件中,用 -ExecutionPolicy Bypass 运行它,现在我的计划任务按预期运行。

Program: Powershell.exe
Add Arguments: -ExecutionPolicy Bypass -File C:\pscommandFile.ps1

回答by Denis Besic

In addition to advices from above I was getting error and found solution on following link http://blog.vanmeeuwen-online.nl/2012/12/error-value-2147942523-on-scheduled.html.

除了上面的建议之外,我还遇到了错误,并在以下链接http://blog.vanmeeuwen-online.nl/2012/12/error-value-2147942523-on-scheduled.html上找到了解决方案。

Also this can help:

这也可以帮助:

In task scheduler, click on the scheduled job properties, then settings.

在任务计划程序中,单击计划作业属性,然后单击设置。

In the last listed option: "if the task is already running, the following rule applies:" Select "stop the existing instance" from the drop down list.

在最后列出的选项中:“如果任务已在运行,则适用以下规则:”从下拉列表中选择“停止现有实例”。

回答by MikeBeaton

I think the answer to this is relevant too:

我认为这个答案也很重要:

Why is my Scheduled Task updating its 'Last Run Time' correctly, and giving a 'Last Run Result' of '(0x0)', but still not actually working?

为什么我的计划任务正确更新了它的“上次运行时间”,并给出了“(0x0)”的“上次运行结果”,但仍然没有实际工作?

Summary:Windows 2012 Scheduled Tasks do notsee the correct environment variables, including PATH, for the account which the task is set to run as. But you can test for this, and if it is happening, and once you understand what is happening, you can work around it.

摘要:Windows 2012 计划任务没有看到正确的环境变量,包括PATH设置为运行任务的帐户的 。但是您可以对此进行测试,如果它正在发生,一旦您了解正在发生的事情,您就可以解决它。

回答by MUhammad Samiul Haq

NOTE: Please ensure that you select Create a Basic task Action and NOT the Create Task Action.

注意:请确保您选择创建基本任务操作而不是创建任务操作。

I found the following solution:

我找到了以下解决方案:

1) Make powershell.exerun as administrator for this

1)powershell.exe为此以管理员身份运行

  1. right-click on the powershell.exeicon
  2. click on properties under the shortcut key menu
  3. click on the advance button; check that "run as administrator" is checked.
  1. 右键单击powershell.exe图标
  2. 点击快捷键菜单下的属性
  3. 点击前进按钮;检查“以管理员身份运行”是否已选中。

2) in the task scheduler window under the action pane add the following script as a new command

2)在操作窗格下的任务计划程序窗口中添加以下脚本作为新命令

%SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe -NoLogo -NonInteractive -ExecutionPolicy Bypass -noexit -File "C:\ps1\BackUp.ps1"

enter image description here

在此处输入图片说明

回答by Tomasz Wieczorkowski

If you don't have any error messages and don't know what the problem is - why PowerShell scripts don't want to start from a Scheduled Task do the following steps to get the answer:

如果您没有任何错误消息并且不知道问题出在哪里 - 为什么 PowerShell 脚本不想从计划任务启动,请执行以下步骤以获得答案:

  1. Run CMD as a user who has been set for Scheduled Task to execute the PowerShell script
  2. Browse to the folder where the PowerShell script is located
  3. Execute the PowerShell script (remove all statements that block the error notifications if any exists inside of the script like $ErrorActionPreference= 'silentlycontinue')
  1. 以已设置定时任务的用户身份运行CMD执行PowerShell脚本
  2. 浏览到 PowerShell 脚本所在的文件夹
  3. 执行 PowerShell 脚本(如果脚本中存在任何阻止错误通知的语句,如 $ErrorActionPreference= 'silentlycontinue',则删除所有语句)

You should be able to see all error notifications.

您应该能够看到所有错误通知。

In case of one of my script it was:

如果我的脚本之一是:

"Unable to find type [System.ServiceProcess.ServiceController]. Make sure that the assembly that contains this type is loaded."

“无法找到类型 [System.ServiceProcess.ServiceController]。确保加载了包含此类型的程序集。”

And in this case I have to add additional line at the begining of the script to load the missing assembly:

在这种情况下,我必须在脚本的开头添加额外的行来加载缺少的程序集:

Add-Type -AssemblyName "System.ServiceProcess"

添加类型 -AssemblyName "System.ServiceProcess"

And next errors:

和下一个错误:

Exception calling "GetServices" with "1" argument(s): "Cannot open Service Control Manager on computer ''. This operation might require other privileges."

使用“1”个参数调用“GetServices”时出现异常:“无法打开计算机“上的服务控制管理器”。此操作可能需要其他权限。

select : The property cannot be processed because the property "Database Name" already exists

select : 无法处理该属性,因为属性“数据库名称”已存在

回答by Viral

I had very similar issue, i was keeping the VSC window with powershell script all the time when running the schedule task manually. Just closed it and it started working as expected.

我有非常相似的问题,我在手动运行计划任务时一直使用 powershell 脚本保留 VSC 窗口。刚刚关闭它,它开始按预期工作。

回答by Vadim Berman

One more idea that worked. It's really silly, but, apparently, the default target OS setting (bottom right corner of the screen) is Vista / Windows Server 2008. As we're past the 10 year mark, it is likely that your Powershell script will not be compatible to these.

另一个有效的想法。这真的很愚蠢,但是,显然,默认的目标操作系统设置(屏幕右下角)是Vista / Windows Server 2008. 由于我们已经过了 10 年,您的 Powershell 脚本很可能与这些不兼容。

Changing the target to Windows Server 2016, as shown on the screenshot below, did the trick for me.

将目标更改为 Windows Server 2016,如下面的屏幕截图所示,对我有用。

Change the setting on the screenshot

更改屏幕截图上的设置