Windows-Server-2008

Powershell腳本以某種方式執行時會無限循環執行

  • January 3, 2014

我正在使用 Puppet 的 Exec Powershell 提供程序來執行一些 powershell 腳本。我對它執行我的腳本的方式有疑問。執行方法導致腳本反復執行。我被迫自己殺死程序,但腳本本身似乎執行正常。

我已經能夠整理一個簡單的例子,並縮小原因。

重現步驟

  1. 使用以下內容創建C:\backups\scripts\test.ps1

我很確定這個問題與我執行 SQLCMD.exe 的方式有關,或者與執行所需的時間有關(大約一秒鐘)

   $instance = '';
   $latest_output = "Hi";

   $cmd = "sqlcmd.exe -E -S .$instance -h -1 -m 1 -Q `"SET NOCOUNT ON; USE [master]; SELECT @@VERSION;`"";

   $output = [string](cmd.exe /C "$cmd");
   $output = $output.Trim(' ');

   if ($output -eq $latest_output)
   {
       Write-Host "Up to date.";
   }
   else
   {
       Write-Host "Updating...";
   }
  1. 打開 CMD.exe,執行以下命令,按預期工作:
C:\Users\Administrator>powershell.exe -Command C:\backups\scripts\test.ps1
Updating...

C:\Users\Administrator>
  1. 現在改為像這樣執行腳本,它會無限執行。這是 Puppet 中的 Exec 提供程序使用的有問題的語法:
C:\Users\Administrator>powershell.exe -Command - < C:\backups\scripts\test.ps1
Updating...
Updating...
Updating...
Updating...
  1. 如果我添加exit;到 test.ps1 的末尾,它只會執行一次。

我最初的問題是,我怎樣才能避免這種情況?但是添加exit對我來說是這樣的。剩下的唯一問題是:為什麼會發生這種情況?

編輯:一旦您將語法錯誤/異常帶入腳本(例如缺少逗號),腳本將無限執行,每次都拋出異常。因此,雖然exit是一種解決方法,但它仍然很危險,因為它不適用於異常。

環境

  • Windows 2008 R2 伺服器標準版
  • 具有高級服務的 Microsoft SQL Server Express 10.50.2500
  • 電源外殼 2.0

Powershell 似乎對它作為標準輸入接收的內容很敏感(使用 < 來重定向標準輸入)。它可能正在接收它不期望的字元。我建議刪除所有換行符並將腳本保存在記事本中。所以你的腳本看起來像這樣:

$instance = ''; $latest_output = "Hi"; $cmd = "etc...

通過我所做的少數測試,我收到了根據所使用的編碼、空格和字元不同的行為。可能只是cmd 重定向輸入的方式。

您可能還希望將您的問題發佈到 github 中的powershell puppet 項目

此外,您可能不想使用 write-host,因為它是控制台的標準輸出,也可能是問題。

在稍微不相關的註釋上試試這個:

$psi = New-Object System.Diagnostics.ProcessStartInfo;
$psi.FileName = "powershell.exe"
$psi.UseShellExecute = $false
$psi.RedirectStandardInput = $true
$p = [System.Diagnostics.Process]::Start($psi)

點擊 ctrl-c 然後你應該看到如下內容:

PS C:\&gt; PS C:\&gt;

當涉及到輸入重定向時,Powershell 肯定會表現出奇怪的行為。

引用自:https://serverfault.com/questions/564803