Cómo comprobar si el complemento de PowerShell ya está cargado antes de llamar a Add-PSSnapin

90

Tengo un grupo de scripts de PowerShell que a veces se ejecutan juntos, a veces uno a la vez. Cada uno de los scripts requiere que se cargue un complemento específico.

En este momento, cada script está llamando Add-PSSnapin XYZal principio.

Ahora, si ejecuto varios scripts consecutivos, los scripts posteriores arrojan:

No se puede agregar el complemento XYZ de Windows PowerShell porque ya se agregó. Verifique el nombre del complemento y vuelva a intentarlo.

¿Cómo puedo hacer que cada secuencia de comandos verifique si el complemento ya está cargado antes de llamar a Add-PSSnapin?

Joshuapoehls
fuente

Respuestas:

133

Debería poder hacerlo con algo como esto, donde consulta por el Snapin pero le dice a PowerShell que no se equivoque si no puede encontrarlo:

if ( (Get-PSSnapin -Name MySnapin -ErrorAction SilentlyContinue) -eq $null )
{
    Add-PsSnapin MySnapin
}
Scott Saad
fuente
¡Ah-hah! Esto es exactamente lo que necesitaba, ¡gracias! Había intentado algo similar a esto en mi experimento, pero no sabía acerca de la -ErrorAction SilentlyContinue.
Joshuapoehls
2
SilentlyContinue se debe a que Get-PSSnapin no devuelve nulo silenciosamente cuando no encuentra el complemento de forma predeterminada. Se equivoca.
Rich
1
Para los perezosos: este artículo proporciona un ejemplo de código completo sobre cómo comprobar también si un complemento está registrado antes de cargarlo.
herzbube
21

Scott ya te dio la respuesta. También puede cargarlo de todos modos e ignorar el error si ya está cargado:

Add-PSSnapin -Name <snapin> -ErrorAction SilentlyContinue
Shay Levy
fuente
6
Eso también continuaría silenciosamente si el complemento no se cargara por otras razones, como no estar instalado. Lo que podría ocasionar problemas difíciles de diagnosticar para las personas que utilizan su script.
Graham Ambrose
Bien, en ese caso podemos comprobar primero si el complemento está registrado.
Shay Levy
4

Sorprendentemente, nadie mencionó la forma nativa en que los scripts especifican dependencias: la #REQUIRES -PSSnapin Microsoft.PowerShell...directiva de comentario / preprocesador. De todos modos, podría requerir elevación con -RunAsAdministrator, módulos con -Modules Module1,Module2y una versión específica de Runspace.

Leer más escribiendo Get-Help about_requires

Alexey
fuente
Esta solución me parece la forma "correcta" de hacer esto.
Grax32
1
El problema que tuve con esto es que Powershell devuelve un error si el complemento requerido no está cargado y supongo que lo que todos querrían es que se cargue el complemento si no lo está.
Dwayne Driskill
1
Los módulos son más nuevos y son módulos los que se cargan automáticamente según sea necesario, no PSSnapins, tiene razón. Pero al menos nada se romperá o se ensuciará al ejecutar la parte del script que funciona sin el complemento.
Alexey
3

Probé la muestra de código de @ ScottSaad pero no funcionó para mí. No he descubierto exactamente por qué, pero la verificación no fue confiable, a veces tuvo éxito y otras no. Descubrí que usar un Where-Objectfiltrado en la Namepropiedad funcionaba mejor:

if ((Get-PSSnapin | ? { $_.Name -eq $SnapinName }) -eq $null) {
    Add-PSSnapin $SnapinName 
}

Código cortesía de esto .

Andy McCluggage
fuente
1

Scott Saads funciona, pero esto me parece algo más rápido. No lo he medido pero parece cargarse un poco más rápido ya que nunca produce un mensaje de error.

$snapinAdded = Get-PSSnapin | Select-String $snapinName
if (!$snapinAdded)
{
    Add-PSSnapin $snapinName
}
Kjetil Ytrehus
fuente