从批处理脚本调用Powershell脚本,但需要批处理脚本等待Powershell脚本完成。

3

我有一个批处理脚本,其中包含以下代码:

这是批处理脚本(Test.bat):

call powershell.exe -executionpolicy remotesigned -File TheScriptToBeExecuted.ps1

exit /b

这个 Powershell 脚本 (TheScriptToBeExecuted.ps1) 中已经内置了一些等待时间。但是当调用该文件时,批处理脚本并不会等待 Powershell 脚本完成。

我曾尝试过:

START /wait powershell.exe -executionpolicy remotesigned -File TheScriptToBeExecuted.ps1

毫无效果��

当我双击Test.bat文件时,它似乎在等待。我查看了很多答案,但没有找到与此问题相对应的答案。

请帮忙解决。


2
不要使用CALLSTART命令。这些命令对于你要做的事情没有必要。 - Squashman
1
你不能使用timeout、pause或Choice /T xxx /C /N yn /D n /M "Y/N"吗? - T3RR0R
@T3RR0R,我们所有的逻辑都在PowerShell中,但是作为公司PowerShell脚本的标准,我们只是使用批处理文件来调用它们。 - NoRestartOnUpdate
当然可以,但使用Choice /T或timeout,您可以继续执行一个函数来测试PowerShell脚本是否仍处于活动状态,这意味着不需要直接用户交互。我假设这些批处理是以类似vbscript的方式静默运行的? vbs也可以用于监视powershell的进程状态,并调用另一个静默批处理程序来强制输入到主批处理程序中,以便在关闭powershell脚本后继续执行。 - T3RR0R
@Squashman,还是没有运气。 - NoRestartOnUpdate
显示剩余8条评论
4个回答

1
start /wait powershell.exe -executionpolicy remotesigned -File TheScriptToBeExecuted.ps1 | ECHO > nul

尝试上述方法。该命令会等待脚本执行完成,而不会出现“终止批处理提示”。如果不需要显示或与脚本交互,则使用 start /min /wait 命令,或者选择以下方法:

start /wait powershell.exe -executionpolicy remotesigned -WindowStyle Hidden -File TheScriptToBeExecuted.ps1 | ECHO > nul

-WindowStyle Value
Sets the window style for the session. Valid values are Normal, Minimized, Maximized and Hidden.

* | * 管道符号用于将命令输出传递给其他命令,但由于您刚开始使用 powershell.exe,且没有在利用类似以下命令的上下文中使用它,所以这不应该是一个问题。

powershell -command "((Get-date).AddDays(0)).ToString(':dd:MM:yyyy') | set-content 'captureVar.txt'" && set /p Yesterday=<captureVar.txt

它在我测试的脚本中有效,但没有经过彻底的测试。 让我知道它的表现如何。


我之前尝试过上述两个选项,并且如我所提到的,它们独立运行良好,也就是说,当我双击.bat文件时,它绝对会等待Powershell脚本完成后再继续执行,然而,我们从我们的主机作业调度程序(Stonebranch)调用Test.bat脚本时,完全相同的批处理脚本却不等待Powershell脚本完成,它基本上在调用进程后奇怪地退出! - NoRestartOnUpdate
所以最终我在代码中解决了这个问题,为Powershell脚本编写了一个输出文件,在执行完成后进行输出,批处理脚本会查找该文件,如果找不到它会等待几分钟然后再次检查,直到找到该文件。这正是我想要避免的,并且我希望有一种非常简单的方式来等待PS脚本完成。 - NoRestartOnUpdate
我刚刚通过从USB上的批处理启动ps1的批处理调用进行了测试,结果有些灾难性。不仅批处理没有等待,而且PowerShell脚本也没有正确执行。我需要研究一下从非本地目录调用的行为,以了解这里发生了什么。 - T3RR0R

0
powershell -ExecutionPolicy ByPass -command ". 'C:\path\TheScriptToBeExecuted.ps1'"

这应该可以了,如果不行,我们会在末尾添加< NUL

powershell -ExecutionPolicy ByPass -command ". 'C:\path\TheScriptToBeExecuted.ps1'" < NUL

通过使用点号源,我们在上述解决方案中使用powershell引用在cmd窗口中打开powershell。然后,句点允许脚本在cmd窗口中运行。我进行了双重测试,并制作了一个包含start-sleep -s 3的.ps1文件,上述内容确实等待powershell脚本完成。
方法2 使用Start /wait
START /wait PowerShell.exe "& "'C:\path\TheScriptToBeExecuted.ps1'"

这个方法无法在cmd窗口中运行。它会打开一个powershell终端并在其中运行,然后返回到bat文件。


谢谢Shadoe2020,问题在于我需要批处理脚本在继续之前等待PowerShell脚本完成,这在独立运行时完全正常,但当从我们的作业调度程序调用时,它只调用PowerShell脚本并继续执行。 - NoRestartOnUpdate

0

我认为问题更有可能出现在“TheScriptToBeExecuted.ps1”文件中,而不是在你的bat文件中。实际上,几个PowerShell命令都是异步的。 我测试了一个不同步的“Sleep-Start”使用以下代码,而且bat文件正在等待它的结束。 这是我在我的.bat文件中使用的代码

REM RUNTEST.BAT
time /T
echo started
powershell -executionpolicy remotesigned -File C:\Users\Alex\Desktop\DA_PROVARE\test.ps1
time /T
echo done
exit /b

ps1内容只有一行,如下:

Start-Sleep -Seconds 25

0
你面临的问题可能是由于计划程序运行的账户引起的。我曾经遇到过类似的问题,当.bat和/或.ps1被计划程序或其他工具启动时,它们的行为不同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接