¿Hay alguna forma de suprimir las indicaciones interactivas en un script de PowerShell?

13

Al escribir scripts de PowerShell, noté que cuando ciertos cmdlets encuentran problemas, aparecen un mensaje interactivo, Remove-Item en un directorio no vacío como ejemplo. Esto es mortal cuando intento automatizar tareas, prefiero que la acción simplemente falle y arroje una excepción o devuelva un código de retorno incorrecto para que todo el script no esté bloqueado esperando una respuesta.

¿Hay alguna forma de obligar a PowerShell a fallar automáticamente en lugar de buscar la entrada del usuario en las acciones?

Chuu
fuente
Creo que debería cambiar el nombre de su pregunta "¿Cómo puedo hacer que Remove-Itemfalle rápidamente?"
Jay Bazuzi
1
Esto no se trata específicamente de Remove-Item, es solo un ejemplo ilustrativo. Hay muchos otros cmdlets que bloquearán la espera de la entrada del usuario en las condiciones adecuadas.
Chuu

Respuestas:

5

La solución propuesta por Eris efectivamente inicia otra instancia de PowerShell. Una forma alternativa de hacer esto, con una sintaxis más simple, es utilizar otra instancia de powershell.exe.

powershell.exe -NonInteractive -Command "Remove-Item 'D:\Temp\t'"
Damian Powell
fuente
2
Realmente me gusta la solución, pero me trae las pesadillas de escribir procedimientos almacenados confiables en TSQL antes de TRY / CATCH, lo que requería rodear literalmente cada consulta con repeticiones de detección de errores.
Chuu
4

Ver Get-Help about_Preference_Variables:

$ ConfirmPreference
------------------
    Determina si Windows PowerShell le solicita automáticamente
    confirmación antes de ejecutar un cmdlet o función.

...

Ninguno: Windows PowerShell no se solicita automáticamente.
                         Para solicitar la confirmación de un comando en particular, use
                         el parámetro Confirmar del cmdlet o función.

Entonces:

> $ConfirmPreference = 'None'
Jay Bazuzi
fuente
Encontré eso para ver el problema que tenía que establecer. $ ConfirmPreference = 'Low'
Guy Thomas
Esto no parece funcionar. Remove-Item en un directorio aún le da un mensaje después de configurar $ ConfirmPreference a 'None' o 'Low'
Chuu
Works for Remove-ADUser(Server 2012R)
velkoon
2

Ok, esto es realmente feo, pero la mostaza santa mancha que "funciona".

Cuestiones:

  • No he descubierto cómo continuar después del primer error.
  • En este caso, elimina los archivos sin formato, luego se detiene en la primera carpeta
  • No he descubierto cómo hacer que este cmdlet funcione si agrego el parámetro UseTransaction
  • Esto solo funcionará para el caso Simple (comandos que no hacen muchas cosas con el entorno actual). No he probado nada complejo

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

Salida:

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
fuente
La razón por la que no he marcado esto como una solución es que no he encontrado tiempo para probarlo. ¿Alguien ha implementado o probado este código además del autor?
Chuu
0

Todas las soluciones anteriores fallaron cuando creé un directorio, lo que significaba que se me solicitó que aprobara cada directorio que creó mi script, lo cual fue mucho. Lo que funcionó para mí fue apped | Out-null para canalizar los resultados a Out-Null

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

Tenga en cuenta que $ Directory es una cadena con la ruta completa al directorio que desea crear. Espero que esto ahorre algo de tiempo a alguien: P

Chris Sprague
fuente
-1

Sugiero dos técnicas

a) Anexar -force

b) Anexar -errorAction silently continue

Así es como investigo qué cmdlets admiten un parámetro particular

Get-Command | where { $_.parameters.keys -contains "erroraction"}
Guy Thomas
fuente
Una de las razones por las que comencé por este camino es que generalmente quiero hacer lo contrario de -force, es decir, algo como -siemprebackoffoff. Sin embargo, he descubierto que la mayoría de los comandos que admiten -force no parecen tener ninguna opción para retroceder.
Chuu
1
Como comentario, una abreviatura conveniente para -errorAction SilentlyContinuees -ea 0.
Jay Bazuzi