Powershell脚本卡住了,从batch file调用时不会退出

我有一个PowerShell脚本连接到一个网站,并parsing其返回的数据(这是关于导入一个以前上传的SQL文件到网站的数据库)。 PowerShell脚本使用wget ,稍后我可能会用本机函数replace。

导入过程被embedded到由第三方程序scriptFTP执行的脚本中。

当我从一个单一的.bat文件调用它时,脚本运行良好,如下所示:

 powershell "& "C:\data\etc\run_import_script.ps1" exit %ERRORLEVEL% 

但是,当我从较大的ScriptFTP上下文中调用该.bat文件时,会发生以下情况:

  • PowerShell脚本被执行 。 我证实了这一点,每次远程导入脚本被调用时,我都会给自己发一封电子邮件。
  • PowerShell似乎没有退出,脚本执行卡住了 。 我仍然可以用Ctrl + C取消整个事情,但是下面的命令永远不会被执行。

当我将batch file更改为以下内容时:

 start powershell "& "C:\data\etc\run_import_script.ps1" exit %ERRORLEVEL% 

工作 ,在新的控制台中运行PowerShell脚本,但我不能抓住PowerShell返回的错误级别。

我试图直接从ScriptFTP调用PowerShell,绕过batch file,但结果相同:它只是卡住了。

我没有PowerShell脚本使用Write-OutputWrite-Host任何输出不显示。

所有程序在同一个用户下运行,我。

有没有人有什么想法做什么?

Solutions Collecting From Web of "Powershell脚本卡住了,从batch file调用时不会退出"

尝试添加/ WAIT参数。 它将保持.bat等待,直到PowerShell脚本完成。

 START /WAIT powershell "& "C:\data\etc\run_import_script.ps1" 

这个变体可能适合你。

 powershell -NoProfile -Command "C:\data\etc\run_import_script.ps1; exit $LASTEXITCODE" < NUL 

取自http://thepowershellguy.com/blogs/posh/archive/2008/05/20/hey-powershell-guy-how-can-i-run-a-powershell-script-from-cmd-exe-and-返回-AN-errorlevel.aspx

根据我的经验,PowerShell.exe可以使用-File开关以可预测的方式轻松地从批处理文件或shell脚本内运行脚本。 一个不需要使用开始命令。

重要的是要追加

 < nul 

到批处理文件中的命令行。 我的研究显示,PowerShell运行通过-File开关指示的脚本中的命令,然后等待来自标准输入的其他PowerShell命令 (我对-Command开关的简短实验表现出类似的行为)。 通过将标准输入重定向到nul,一旦PowerShell完成执行脚本并从标准输入读取“文件结束”,PowerShell就会退出。

从Cygwin调用PowerShell时,请使用

 < /dev/null 

例如,我使用shell变量从Cygwin运行PowerShell脚本,如下所示:

 PowerShell.exe -ExecutionPolicy RemoteSigned -File $_powershellscriptpath $_firstscriptparameter < /dev/null 

如果你的经验与我的不同,请发表评论。 – 戈登

我们有类似的问题。 我们想从一个只有一个盒子的软件中调用PowerShell应用程序来输入“Command”和“Parameters”,但是虽然PowerShell运行成功(我可以看到受影响的文件已经更新)。

最后我的同事帮我弄明白了命令需要:

 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 

和参数:

 -ExecutionPolicy unrestricted -Command "& {C:\scripts\apps\EDI\Test.ps1; [Environment]::Exit(1)}" 

在我们的例子中,使用[Environment]::Exit(1)而不是Exit 1 。 我相信Exit仅仅是终止脚本,而不是关闭Powershell本身。

如果要捕获powershell.exe命令的输出,则还可以使用/ B参数来强制进程在同一个命令shell中运行。

我们刚刚看到这个问题的一个非常奇怪的例子。 包含调用powershell.exe -command ...批处理文件在本地运行良好,但在批处理文件在msdeploy -postSync命令的上下文中运行时如上所述停止。 在尝试使用process.Kill()强制PowerShell退出之后,我们点亮了使用START /WAIT /B PowerShell.exe ..

不知道为什么这应该工作,但它确实…

如果这正是你的文件,这是因为你有不匹配的引号。 Powershell正在等待最后的报价。

至少我认为PowerShell在以这种方式被调用时会有奇怪的行为。 简而言之,它不会将传递给powershell.exe的命令行参数视为脚本运行。 相反,它把它们当作命令来运行。 这是因为powershell.exe的默认值是-command – 请参阅powershell.exe /? 了解更多信息。

 C:\>powershell "'Hello'" Hello 

你需要做的是构建一个聪明的输入字符串来“源”你想运行的脚本:

 C:\>powershell ". .\test.ps1" Hello, World! 

至于输出,一旦你得到脚本正确运行,它应该只是一个捕获STDOUT或任何结果适合您的脚本的问题。

完整的例子

test.bat的

 @echo off powershell.exe ". .\test.ps1" 

test.ps1

 "Hello, World!" 

调用该命令:

 test.bat > test.txt 

并验证输出是否被捕获:

 C:\>type test.txt Hello, World! 

我打赌的问题是Powershell进程继续执行脚本后运行 。 这意味着它没有退出,因此没有退出代码。 当我尝试从C#运行一个Powershell脚本时,遇到类似的问题,它完成时会执行任何操作,除非它永远不会结束。

Hacky,但我找到的唯一解决方案是将Stop-Process -processname powershell放在.ps1脚本的末尾。 这会杀死PowerShell进程(以及不幸打开的所有PowerShell窗口),但似乎正常工作。 也可能为你的脚本工作。

我有确切的问题,我们正在尝试将Power Shell脚本集成到另一个系统中,并持续发生超时错误。 可能是因为戈登史密斯提到的问题,他的解决方案可能会奏效。 但对我而言,我更喜欢从脚本本身完全控制我的脚本,而不依赖于它被调用的方式。

$ pid是建立在变量与PID。 以下将结束当前的PowerShell进程,并保持其他的完整。 这样任何人都可以像平常那样调用你的脚本,它将按预期工作。

 Stop-Process $pid 

您可以简单地在.ps1脚本的末尾添加一个“退出”命令(或者您希望的任何进程终止的变体)。 Powershell将继续运行在脚本的末尾,因为它还没有被告知终止(当在PS或ISE中运行时,它将在脚本结束时自动终止,但不通过DOS shell运行)。