我有一个连接到网站的PowerShell脚本,并解析其返回的数据(它是关于将以前上传的SQL文件导入到网站的数据库中)。 PowerShell脚本使用wget
,稍后我可以用原生函数替换它。
导入过程嵌入在由名为scriptFTP的第三方程序执行的脚本中。
当我从一个.bat文件中调用它时,脚本运行正常:
powershell "& "C:\data\etc\run_import_script.ps1"
exit %ERRORLEVEL%
但是,当我从更大的ScriptFTP上下文中调用此.bat文件时,会发生以下情况:
当我将批处理文件更改为以下内容时:
start powershell "& "C:\data\etc\run_import_script.ps1"
exit %ERRORLEVEL%
工作,在新控制台中运行PowerShell脚本,但我无法获取PowerShell返回的错误级别。
我尝试直接从ScriptFTP调用PowerShell,绕过批处理文件,但结果相同:它只是卡住了。
我没有显示使用Write-Output
或Write-Host
的PowerShell脚本所做的任何输出。
所有程序都在同一个用户下运行,我。
有人有什么想法吗?
答案 0 :(得分:22)
此变体可能适合您。
powershell -NoProfile -Command "C:\data\etc\run_import_script.ps1; exit $LASTEXITCODE" < NUL
答案 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运行时不会自动终止。)