Powershell: ¿Cómo puedo evitar que se muestren errores en un script?

92

Cuando mi script de PowerShell intenta, por ejemplo, crear un objeto de SQL Server para un servidor que no existe ("bla" en mi caso), PowerShell muestra muchos errores de PowerShell en rojo.

Dado que mi secuencia de comandos verifica el valor de $?después de tales llamadas y muestra y registra errores, prefiero que no se muestren también las varias líneas de errores de PowerShell.

¿Cómo puedo desactivar los que se muestran en mi secuencia de comandos?

Andrew J. Brehm
fuente

Respuestas:

132

Tienes unas cuantas opciones. La más sencilla implica el uso de la ErrorActionconfiguración.

-Erroractiones un parámetro universal para todos los cmdlets. Si hay comandos especiales que desea ignorar, puede usarlos, -erroraction 'silentlycontinue'que básicamente ignorarán todos los mensajes de error generados por ese comando. También puede usar el Ignorevalor (en PowerShell 3+):

A diferencia de SilentlyContinue, Ignore no agrega el mensaje de error a la variable automática $ Error.

Si desea ignorar todos los errores en un script, puede usar la variable del sistema $ErrorActionPreferencey hacer lo mismo:$ErrorActionPreference= 'silentlycontinue'

Consulte about_CommonParameters para obtener más información sobre -ErrorAction. Consulte about_preference_variables para obtener más información sobre $ ErrorActionPreference.

JNK
fuente
¿Necesita comillas simples en -erroracción 'silenciosamente continuar'? Intellisese muestra opciones y no agrega comillas simples.
PAS
1
Si el formato anterior no funciona para usted, consulte el enlace proporcionado anteriormente. Tuve que formatear como -ErrorAction:SilentlyContinueen PS 5.1. Estaba llamando a mi cmdlet desde el lote, así que no sé si eso hace una diferencia. Pero buena información cuando sabe que se puede producir un error aceptable.
David
--rm. \ Windows.old \ -Force -Recurse -Verbose -ErrorAction SilentlyContinue -WarningAction SilentlyContinue </code>
Tertius Geldenhuys
18

Windows PowerShell proporciona dos mecanismos para informar errores: un mecanismo para terminar errores y otro mecanismo para errores que no terminan .

El código CmdLets interno puede llamar a un ThrowTerminatingErrormétodo cuando se produce un error que no permite o no debe permitir que el cmdlet continúe procesando sus objetos de entrada. El autor de la secuencia de comandos puede utilizar una excepción para detectar estos errores.

EX:

try
{
  Your database code
}
catch
{
  Error reporting/logging
}

El código CmdLets interno puede llamar a un WriteErrormétodo para informar errores no finales cuando el cmdlet puede continuar procesando los objetos de entrada. El guionista puede utilizar la opción -ErrorAction para ocultar los mensajes o utilizar $ErrorActionPreferencepara configurar todo el comportamiento del script.

JPBlanc
fuente
8

Tuve un problema similar al intentar resolver los nombres de host usando [system.net.dns]. Si la IP no se resolvió, .Net arrojó un error de terminación. Para evitar el error de terminación y aún retener el control de la salida, creé una función usando TRAP.

P.EJ

Function Get-IP 
{PARAM   ([string]$HostName="")
PROCESS {TRAP 
             {"" ;continue} 
             [system.net.dns]::gethostaddresses($HostName)
        }
}
DW
fuente
3

Estás muy desviado aquí.

Ya tienes un mensaje de error grande y agradable. ¿Por qué diablos querría escribir código que verifique $?explícitamente después de cada comando ? Esto es enormemente engorroso y propenso a errores. La solución correcta es dejar de comprobar$? .

En su lugar, use el mecanismo integrado de PowerShell para explotar por usted. Lo habilita estableciendo la preferencia de error en el nivel más alto:

$ErrorActionPreference = 'Stop'

Pongo esto en la parte superior de cada script que escribo, y ahora no tengo que comprobarlo $?. Esto hace que mi código sea mucho más simple y confiable.

Si se encuentra con situaciones en las que realmente necesita deshabilitar este comportamiento, puede mostrar catchel error o pasar una configuración a una función en particular usando el archivo common -ErrorAction. En su caso, probablemente desee que su proceso se detenga en el primer error, detecte el error y luego regístrelo.

Tenga en cuenta que esto no maneja el caso cuando los ejecutables externos fallan (código de salida distinto de cero, convencionalmente), por lo que aún debe verificar $LASTEXITCODEsi invoca alguno. A pesar de esta limitación, la configuración aún ahorra mucho código y esfuerzo.

Fiabilidad adicional

También puede considerar usar el modo estricto :

Set-StrictMode -Version Latest

Esto evita que PowerShell proceda silenciosamente cuando usa una variable inexistente y en otras situaciones extrañas. (Consulte el -Versionparámetro para obtener detalles sobre lo que restringe).

La combinación de estas dos configuraciones hace que PowerShell sea mucho más un lenguaje a prueba de fallas, lo que hace que la programación en él sea mucho más fácil.

jpmc26
fuente
2

Agregue -ErrorAction SilentlyContinuea su guión y estará listo para comenzar.

Jayant Rajwani
fuente
2

En algunos casos, puede canalizar después del comando un Out-Null

command | Out-Null
Baya
fuente
-1

Si desea suprimir el mensaje de error de PowerShell para un cmdlet, pero aún desea detectar el error, use "-erroraction 'silenntlyStop'"

Mikkel Vejlby
fuente
No existe tal acción. Aunque hay una acción de parada.
Marvin Dickhaus
Pero permite suprimir el mensaje de error rojo y aún usar el comando / sección de captura cuando se usa New-Item -ItemType directory(PowerShell v2.0)
Milan Kerslager
@MilanKerslager podría mostrar amablemente un ejemplo de código, ya que yo, y todos los demás, creemos que no existe tal ActionPreference como 'SilentlyStop'
FSCKur
Estoy razonablemente seguro de que Mikkel se refería a Continuar silenciosamente en lugar de Detener silenciosamente, porque eso tiene mucho más sentido en el contenido de lo que quieres que esté haciendo.
John