Búsqueda de sitios web

Módulos de PowerShell en un mundo de versiones cruzadas


El otro día estaba ayudando a un amigo a resolver algunas preguntas relacionadas con el módulo. Mientras lo ayudaba, me di cuenta de que sus preguntas y problemas no eran únicos. Ahora que muchos de nosotros ejecutamos Windows PowerShell 7 en paralelo, ¿cuáles son las implicaciones cuando se trata de utilizar módulos de PowerShell? ¿Cuáles son los posibles “errores”? ¿Y qué puedes hacer para reducir la probabilidad de problemas?

PowerShellObtener

Tanto Windows PowerShell como PowerShell dependen de comandos de módulos como Find-Module e Install-Module. Sin embargo, si necesita admitir versiones cruzadas de módulos, es posible que deba satisfacer un requisito crítico. Por cierto, utilice Windows PowerShell para ejecutar todos estos comandos a menos que se le indique lo contrario.

Abra Windows PowerShell y ejecute

Get-Module powershellget -ListAvailable

Si la única versión que ve es 1.0.0.1, necesita actualizar el módulo. El módulo PowerShellGet es donde se obtienen los comandos del módulo y, en un mundo de versiones cruzadas, necesita una versión posterior del módulo.

Sin embargo, no puedes simplemente ejecutar

Update-Module PowerShellGet

Si lo hace, obtendrá un error. La versión 1.0.0.1 es un módulo de sistema que viene con su versión de Windows 10. No se instaló en el sentido tradicional. Pero no hay problema. Aún puedes instalarlo.

Install-Module PowerShellGet -Force -Repository PSGallery

Estoy siendo muy conciso en el comando para instalar la versión de Microsoft. Verifiquemos.

Remove-Module PowerShellGet -ErrorAction Ignore
Import-Module PowerShellGet
Get-Module PowerShellGet

Deberías ver al menos la versión 2.2.5. Si es así, estás listo para continuar. Por cierto, ahora que ha usado Install-Module, si hay una actualización de versión posterior, puede usar Update-Module para instalarla. No se preocupe por la versión original del sistema. PowerShell utilizará automáticamente la última versión del módulo de forma predeterminada.

Ruta del módulo PS

La siguiente parte del rompecabezas es una variable ambiental llamada %PSModulePath%. Esta variable contiene todas las ubicaciones en las que PowerShell y Windows PowerShell buscan módulos. Esto es lo que hace posible la carga automática del módulo. Aquí es donde se pone interesante.

Aquí está mi variable sobre una instalación limpia de Windows 10.

Dividí el camino en el ";" delimitador para que sea más fácil de leer. Hay 3 ubicaciones predeterminadas. Una para el usuario actual, otra para todos los usuarios y otra para los módulos del sistema. En su mayor parte, ignoraremos cualquier cosa en la ruta del sistema. Cuando instale un nuevo módulo, irá a la ruta del usuario y a la de todos los usuarios. Más sobre esto en un momento.

Aquí ocurre lo mismo en PowerShell 7.1.

Otra forma de pensar en la ruta del sistema es que se encuentra en $PSHome. Mira de cerca. ¡PowerShell 7 también conoce el sistema Windows PowerShell y las ubicaciones de todos los usuarios! Esto significa que PowerShell puede "ver" los módulos instalados por Windows PowerShell. Sin embargo, Windows PowerShell no puede "ver" nada de lo instalado por PowerShell.

Módulo de instalación

Ahora que, con suerte, esto quedó claro, instalemos algunos módulos. En PowerShell, instalaré un módulo que sé que solo funciona en PowerShell 7.x.

install-module Bluebirdps -Scope AllUsers -force

Observe el parámetro -Scope. De forma predeterminada, los módulos instalados son por usuario. Pero en este caso quería instalar el módulo para Todos los usuarios. Esto significa que la cuenta utilizada para instalar el módulo necesita derechos de administrador en C:\Program Files. Es por eso que el valor predeterminado es la ubicación del usuario, para evitar la necesidad de credenciales de administrador. Mientras estoy en eso, instalaré otro módulo en PowerShell 7.

Install-Module PSReleaseTools -force

En Windows PowerShell, instalaré un módulo para todos los usuarios y otro que usará el alcance predeterminado.

Install-Module PSScriptTools -Scope AllUsers -force
Install-Module WTToolbox -force

Módulo de instalación

La siguiente pregunta debería ser: "¿Cómo puedo ver qué módulos están disponibles?". Un comando que puede utilizar, y que no conocía, es Get-InstalledModule. Esto es lo que obtengo en PowerShell.

Puede ver por la ubicación que un módulo es para el usuario y el otro es para todos los usuarios. Observe que no hay módulos de Windows PowerShell.

Esto es lo mismo desde el lado de Windows PowerShell.

No aparece nada de PowerShell 7. Pero hay un punto importante que quiero señalar. Anteriormente instalé el módulo WTToolBox sin especificar un alcance. El valor predeterminado es el alcance del usuario, pero observe la ubicación. Esto es lo que pasó. Estaba ejecutando Windows PowerShell como administrador, es decir, en una sesión elevada. En este contexto, el "usuario" es lo mismo que "todos los usuarios". En cierto modo, eso es algo bueno porque cualquier módulo de Windows PowerShell instalado para todos los usuarios se puede usar en PowerShell 7.x, suponiendo que sea compatible.

Conclusión clave n.º 1: Get-InstalledModule solo muestra los módulos instalados por versión de PowerShell.

Conclusión clave n.º 2: instalar un módulo como usuario elevado siempre instala el módulo para todos los usuarios.

Obtener módulo

Entonces, ¿cómo puedes “ver” qué módulos están disponibles? Utilice el módulo Get. De forma predeterminada, el módulo solo muestra los módulos cargados actualmente. El parámetro clave que debes recordar es -ListAvailable.

Get-Module busca las ubicaciones de PSModulePath, por eso funciona en PowerShell 7. Para "ver" todo, ejecute:

Get-Module -listavailable

Aquí hay un pequeño fragmento de código para inventariar los módulos disponibles.

$p = $env:PSModulePath -split ";"
 $m = Get-Module -ListAvailable
 foreach ($loc in $p) {
     [pscustomobject]@{
         Location = $loc
         Modules = ($m | where {$_.path -match $loc.replace("\","\\") } ).count
     }   
 }

Esta es una combinación de resultados de ambas versiones de PowerShell.

Conclusión clave n.º 3: si necesita utilizar un módulo tanto en Windows PowerShell como en PowerShell 7.x, instálelo para todos los usuarios en Windows PowerShell.

Resumen

Espero que este tutorial haya aclarado cualquier misterio o confusión. Antes de irte, déjame mencionar algunas cosas. En primer lugar, sólo porque PowerShell pueda "ver" un módulo de Windows PowerShell, no hay garantía de que funcione. No dejes que esto te desanime. La gran mayoría de los módulos de Windows PowerShell funcionan bien en PowerShell. Aquellos que no fallan probablemente fallan debido a una dependencia de .NET que no es compatible con .NET Core, que es bajo el cual se ejecuta PowerShell.

En segundo lugar, su variable PSModulePath puede ser diferente. Dependiendo de las aplicaciones o programas que instale, es posible que tenga ubicaciones adicionales. En mi escritorio principal, tengo instalado SQL Server Express, por lo que mi variable incluye C:\Program Files (x86)\Microsoft SQL Server\150\Tools\PowerShell\Modules\.

Técnicamente, podrías modificar la variable ambiental o ajustar las ubicaciones con un script de perfil. Puede hacer esto si desea incluir una ubicación personalizada. Pero desaconsejaría actualizar la variable para que Windows PowerShell pueda "ver" las ubicaciones de los módulos de PowerShell. Estoy trabajando bajo el supuesto de que si un módulo está instalado en PowerShell, requiere PowerShell. Por ejemplo, instalé el módulo BluebirdPS en PowerShell. Si modifiqué cosas para poder importarlas a Windows PowerShell, lo más probable es que falle. Si necesita módulos para funcionar en versiones cruzadas, instálelos en Windows PowerShell para todos los usuarios.

Le recomiendo que actualice PowerShellGet y luego se tome unos minutos para leer la ayuda y los ejemplos de los comandos del módulo.

Artículos relacionados