Existe uma maneira de suprimir qualquer prompt interativo em um script do PowerShell?

13

Ao escrever scripts do PowerShell, notei que quando certos cmdlets encontram problemas, eles exibem um prompt interativo, o exemplo Remove-Item em um diretório não vazio. Isso é mortal ao tentar automatizar tarefas; prefiro que a ação falhe e gere uma exceção ou retorne um código de retorno incorreto para que o script inteiro não fique bloqueado aguardando uma resposta.

Existe alguma maneira de forçar o PowerShell a falhar automaticamente, em vez de buscar a entrada do usuário em ações?

Chuu
fonte
Eu acho que você deve renomear sua pergunta "Como posso fazer com que Remove-Itemfalhe rápido?"
Jay Bazuzi
1
Isso não é especificamente sobre Remove-Item, é apenas um exemplo ilustrativo. Existem muitos outros cmdlets que bloquearão a espera da entrada do usuário nas condições corretas.
Chuu 27/03

Respostas:

5

A solução proposta por Eris efetivamente inicia outra instância do PowerShell. Uma maneira alternativa de fazer isso, com sintaxe mais simples, é desembolsar para outra instância do powershell.exe.

powershell.exe -NonInteractive -Command "Remove-Item 'D:\Temp\t'"
Damian Powell
fonte
2
Eu realmente gosto da solução, mas ela traz de volta pesadelos ao escrever procedimentos armazenados confiáveis ​​no TSQL antes de TRY / CATCH, que exigiam literalmente todas as consultas com clichê de detecção de erros.
Chuu
4

Veja Get-Help about_Preference_Variables:

$ ConfirmPreference
------------------
    Determina se o Windows PowerShell solicita automaticamente que você
    confirmação antes de executar um cmdlet ou função.

...

Nenhum: o Windows PowerShell não solicita automaticamente.
                         Para solicitar a confirmação de um comando específico, use
                         o parâmetro Confirm do cmdlet ou função.

Então:

> $ConfirmPreference = 'None'
Jay Bazuzi
fonte
Eu descobri que para ver o problema que eu tinha que definir. $ ConfirmPreference = 'Low'
Guy Thomas
Isso não parece funcionar. Remove-Item em um diretório ainda lhe dá um aviso depois de definir $ ConfirmPreference como 'Nenhum' ou 'Baixa'
Chuu
Funciona para Remove-ADUser(Server 2012R)
velkoon
2

Ok, isso é realmente feio, mas manchas de mostarda sagrada "funciona".

Problemas:

  • Eu não descobri como continuar após o primeiro erro
  • Nesse caso, ele remove os arquivos simples e para na primeira pasta
  • Eu não descobri como fazer esse cmdlet funcionar se eu adicionar o parâmetro UseTransaction
  • Isso funcionará apenas no caso Simple (comandos que não fazem muita coisa com o ambiente atual). Eu não testei nada complexo

    $MyPS = [Powershell]::Create()
    $MyPS.Commands.AddCommand("Remove-Item")
    $MyPS.Commands.AddParameter("Path", "D:\Temp\t")
    $MyPS.Invoke()

Resultado:

Commands                                                                                                                 
--------                                                                                                                 
{Remove-Item}                                                                                                            
{Remove-Item}                                                                                                            
Exception calling "Invoke" with "0" argument(s): "A command that prompts the user failed because the host program or the 
command type does not support user interaction. The host was attempting to request confirmation with the following 
message: The item at D:\Temp\t has children and the Recurse parameter was not specified. If you continue, all children 
will be removed with the item. Are you sure you want to continue?"
At line:19 char:1
+ $MyPS.Invoke()
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : CmdletInvocationException
Eris
fonte
A razão pela qual não marquei isso como uma solução é que não encontrei tempo para testá-lo. Alguém implantou ou testou esse código além do autor?
Chuu 30/10/2013
0

Todas as soluções acima falharam para mim quando eu criei um diretório, o que significava que fui solicitado a OK em todos os diretórios criados pelo meu script - o que foi muito. O que funcionou para mim foi aumentar | Nulo de saída para canalizar os resultados para Nulo de saída

New-Item -ItemType Directory -Path $directory -Force:$true | Out-Null

Observe que $ Directory é uma string com o caminho completo para o diretório que você deseja criar. Espero que isso economize tempo para alguém: P

Chris Sprague
fonte
-1

Eu sugiro duas técnicas

a) Anexar -force

b) Anexar -errorAction silently continue

É assim que pesquiso quais cmdlets suportam um parâmetro específico

Get-Command | where { $_.parameters.keys -contains "erroraction"}
Guy Thomas
fonte
Uma das razões pelas quais eu comecei nesse caminho é que geralmente quero fazer o oposto de -force, ou seja, algo como -alwaysbackoff. Descobri que a maioria dos comandos que suportam -force parece não ter opção para recuar.
Chuu 24/03
1
Como um aparte, uma abreviação conveniente para -errorAction SilentlyContinueis -ea 0.
Jay Bazuzi