O script Powershell é executado em um loop infinito quando executado de uma determinada maneira

2

Estou usando o provedor Exec Powershell para o Puppet para executar alguns scripts do PowerShell. Estou tendo um problema com a maneira como ele executa meu script. O método de execução faz com que o script seja executado e acabado. Eu sou forçado a matar o processo sozinho, mas o script em si parece rodar normalmente.

Eu consegui reunir um exemplo simples e refinar a causa.

Etapas para reproduzir

  1. Crie C: \ backups \ scripts \ test.ps1 com o seguinte:

Tenho certeza de que o problema está relacionado à maneira como estou executando o SQLCMD.exe ou ao tempo de execução (cerca de um segundo)

    $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. Abra o CMD.exe, execute o seguinte comando, que funciona como esperado:

    C:\Users\Administrator>powershell.exe -Command C:\backups\scripts\test.ps1
    Updating...
    
    C:\Users\Administrator>
    
  2. Agora, em vez disso, execute o script como este, que é executado infinitamente. Esta é a sintaxe problemática usada pelo provedor Exec no Puppet:

    C:\Users\Administrator>powershell.exe -Command - < C:\backups\scripts\test.ps1
    Updating...
    Updating...
    Updating...
    Updating...
    
  3. Se eu adicionar exit; ao final de test.ps1, ele só será executado uma vez.

Minha pergunta original seria: como posso evitar isso? Mas adicionar exit faz isso para mim. A única questão restante é: Por que isso acontece?

EDITAR : Assim que você introduzir um erro / exceção de sintaxe no script (por exemplo, vírgula ausente), o script será executado infinitamente, emitindo a exceção a cada vez. Portanto, embora exit seja uma solução alternativa, ainda é perigoso, pois não funciona contra exceções.

Ambiente

  • Windows Server 2008 R2 Server Standard
  • Microsoft SQL Server Express 10.50.2500 com serviços avançados
  • Powershell 2.0
por Geekman 03.01.2014 / 11:07

1 resposta

2

O Powershell parece ser sensível ao que recebe como entrada padrão (usando < para redirecionar stdin). Pode estar recebendo caracteres que não está esperando. Eu recomendaria remover todas as novas linhas e salvar seu script no bloco de notas. Então, o seu script seria algo como isto:

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

Com os poucos testes que fiz, recebi comportamentos diferentes de acordo com a codificação, o espaço em branco e os caracteres usados. Pode ser apenas a maneira como o cmd redireciona a entrada.

Você também pode postar seu problema no projeto de fantoches do powershell no github.

Além disso, talvez você não queira usar o write-host, pois ele é um stdout para o console e pode ser um problema também.

Em uma nota ligeiramente não relacionada, tente isto:

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

Pressione ctrl-c e você verá algo assim:

PS C:\> PS C:\>

O Powershell definitivamente exibe um comportamento estranho quando se trata de redirecionamento de entrada.

    
por 03.01.2014 / 14:00