我们有一个计划任务,它是一个 powershell 脚本。该脚本针对 SQL 数据库执行许多操作,这些数据库的访问通过集成安全性进行控制。因此,这些操作中的每一个都必须由在适当的 Windows AD 凭据下执行的进程执行,并且必须使用多组凭据。
细节:
powershell任务在任务计划程序中调用如下:
cmd.exe /C ""powershell.exe" -Noninteractive "C:\someDir\SomeScript.ps1" >"C:\logDir\SomeScript.log" 2>&1"
换句话说,被调用的cmd.exe
是Program/script
,行的剩余部分是Add arguments (optional):
部分。(我们这样调用的原因与当前问题无关,部分原因是我们在开发的脚本库中构建日志的方式。)
在计划任务设置(General
)中,我们选择Run whether user is logged in or not
和Run with highest privileges
。运行该任务的用户 ID(我们称之为ad\admin1
)具有本地管理员权限。
在脚本中SomeScript.ps1
,我们通过以下方式调用不同凭据下的其他脚本
Start-Process $explicitPowershellExe -NonInteractive -Credential $credential -Wait -ArgumentList @( '-file', $scriptForSqlOperations )
凭证$credential
属于不同于 的用户ad\admin1
。此调用默默地无法启动 powershell,尽管没有生成任何错误。powershell 无法启动的唯一线索是“windows 日志”=> 系统中的事件:
应用程序弹出窗口:powershell.exe - 应用程序错误:应用程序无法正确启动 (0xc0000142)。单击“确定”关闭应用程序。
请注意,我们可以在计划任务之外运行该脚本,没有任何问题。无论以何种方式运行SomeScript.ps1
,在用户登录会话中运行该脚本ad\admin1
都会成功。例如,在cmd.exe
控制台(以管理员身份运行)中,我们可以运行精确的线
cmd.exe /C ""powershell.exe" -Noninteractive "C:\someDir\SomeScript.ps1" >"C:\logDir\SomeScript.log" 2>&1"
并且成功了,或者我们可以更简单地运行
powershell -Noninteractive "C:\someDir\SomeScript.ps1"
在命令提示符下,一切正常。因此,问题显然出在 TaskScheduler 设置cmd.exe
其运行的进程的方式上。
有人知道问题可能是什么以及如何解决它吗? 我怀疑这是计划任务中模拟的一些安全限制???
谢谢。
答案1
确保您尝试执行的每个用户都具有“作为批处理作业登录”的权限。
- 打开
gpedit.msc
并导航至Computer Configuration\Windows Settings\Security Settings\Local Policies\User Rights Assignment
- 将每个用户添加到
Log on as a batch job
右侧。 - 跑步
gpupdate
- 再次尝试你的任务。
答案2
我认为阻止使用计划任务中的其他凭据执行的关键设置start-process
(其中帐户权限不是问题)是"Run whether user is logged on or not".
使用该"Run only when user is logged on"
设置确实有效,但如果您当时未登录运行该作业的系统,这当然是一个问题。此外,我无法说这个限制是否仅限于命令start-process
。其他 Windows PS 命令也允许传递凭据,但像您一样,如果没有使用替代设置,我也无法成功启动进程。我还没有找到这个限制的明确解释。
答案3
您还可以使用 PowerShell 授予“作为服务登录”权限。
可以使用此处在 Microsoft 脚本中心发布的脚本来存档: https://gallery.technet.microsoft.com/scriptcenter/Grant-Log-on-as-a-service-11a50893#content
.”.\Add Account To LogonAsService.ps1″ “DOMAIN\Account”
将“DOMAIN\Account”替换为您要添加到策略的帐户的名称。
查看此处的来源以了解更多信息:https://www.get-itsolutions.com/log-on-as-batch-job-rights/
谢谢
答案4
您找到解决方案了吗?
我正在尝试做同样的事情 - 从计划任务中以不同的帐户启动其他进程。运行计划任务的帐户以及用于启动其他进程的帐户位于服务器上的本地管理员组中。
我通过创建另一个计划任务然后运行它解决了这个问题。我的脚本不是使用带有凭据对象的启动进程,而是作为计划任务启动,它会创建一个没有触发器的新计划任务,要运行的操作是另一个脚本,新任务以其他用户帐户的身份运行。然后它会运行新的计划任务,并在完成后删除计划任务。
新计划任务运行的操作首先创建一个包含进程详细信息的文件,以便原始脚本可以跟踪其正在运行并根据需要获取其他详细信息。
这有点像“鲁布·戈德堡”的解决方案,但它确实有效。