Powershell脚本卡住,从批处理文件调用时不会退出

时间:2010-01-11 12:35:57

标签: windows powershell

我有一个连接到网站的PowerShell脚本,并解析其返回的数据(它是关于将以前上传的SQL文件导入到网站的数据库中)。 PowerShell脚本使用wget,稍后我可以用原生函数替换它。

导入过程嵌入在由名为scriptFTP的第三方程序执行的脚本中。

当我从一个.bat文件中调用它时,脚本运行正常:

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

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

  • PowerShell脚本已执行。我确认这是每次调用远程导入脚本时给自己发送一封电子邮件。
  • PowerShell似乎没有退出,脚本执行被卡住。我仍然可以使用Ctrl + C取消整个操作,但以下命令永远不会被执行。

当我将批处理文件更改为以下内容时:

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

工作,在新控制台中运行PowerShell脚本,但我无法获取PowerShell返回的错误级别。

我尝试直接从ScriptFTP调用PowerShell,绕过批处理文件,但结果相同:它只是卡住了。

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

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

有人有什么想法吗?

10 个答案:

答案 0 :(得分:22)

此变体可能适合您。

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-return-an-errorlevel.aspx

答案 1 :(得分:16)

尝试添加/ WAIT参数。它会使.bat等待PowerShell脚本完成。

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

答案 2 :(得分:16)

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

重要的是要追加

< nul

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

从Cygwin调用PowerShell时,请使用

< /dev/null

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

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

如果您的经历与我的不同,请发表评论。 - 戈登

答案 3 :(得分:9)

我们遇到了类似的问题。我们想从一个只有一个盒子的软件中调用 powershell app 来进入&#34; Command&#34;和&#34;参数&#34;但是虽然 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非常重要。我相信退出只是终止脚本,而不是关闭 Powershell 本身。

答案 4 :(得分:2)

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

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

不知道为什么这应该有效,但它确实......

答案 5 :(得分:1)

如果这正是您文件中的内容,那是因为您的报价不匹配。 Powershell正在等待最后的报价。

答案 6 :(得分:0)

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!

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

我遇到了确切的问题,我们试图将power shell脚本集成到另一个系统中,并且它一直发出超时错误。可能是因为戈登史密斯提到的问题,他的解决方案可能会奏效。但对我来说,我更喜欢从脚本本身完全控制我的脚本,而不是依赖于它的调用方式。

$ pid是使用PID构建的变量。下面将结束当前的PowerShell流程,并使其他流程完好无损。这样,任何人都可以正常调用您的脚本,它将按预期工作。

Stop-Process $pid

答案 9 :(得分:0)

您只需添加一个&#39;退出&#39;命令到.ps1脚本(或您希望的任何进程终止变体)的末尾。 Powershell将继续在脚本结束时运行,因为它没有被告知终止(当在PS或ISE中运行时,它将在脚本结束时自动终止,但在通过DOS shell运行时不会自动终止。)

相关问题