Para comprobar si existe un módulo, he intentado lo siguiente:
try {
Import-Module SomeModule
Write-Host "Module exists"
}
catch {
Write-Host "Module does not exist"
}
La salida es:
Import-Module : The specified module 'SomeModule' was not loaded because no valid module file was found in any module directory.
At D:\keytalk\Software\Client\TestProjects\Export\test.ps1:2 char:5
+ Import-Module SomeModule
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (SomeModule:String) [Import-Module], FileNotFoundException
+ FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
Module exists
Recibo un error, pero no se lanza ninguna excepción, por lo que vemos Module exists
al final, aunque SomeModule
no existe.
¿Existe una buena manera (preferiblemente sin generar un error) para detectar si un módulo de PowerShell está instalado en el sistema?
powershell
Klemens Schindler
fuente
fuente
Respuestas:
Puede utilizar la
ListAvailable
opción deGet-Module
:if (Get-Module -ListAvailable -Name SomeModule) { Write-Host "Module exists" } else { Write-Host "Module does not exist" }
fuente
Write-Warning "Module does not exist..." ;Break
Pero has hecho todo el trabajo duro.Import-Module
un archivo dll personalizado, no use la-ListAvailable
opción para determinar si el módulo está instalado porque no aparecerá en la lista. Según la documentación de PowerShell 6 , "ListAvailable no devuelve información sobre los módulos que no se encuentran en la variable de entorno PSModulePath, incluso si esos módulos se cargan en la sesión actual".Import-Module
) solo determina si el módulo está disponible de inmediato para ser instalado sin especificar una ubicación específica que aún no se encuentra en$env:PSModulePath
La opción ListAvailable no me funciona. En cambio, esto hace:
if (-not (Get-Module -Name "<moduleNameHere>")) { # module is not loaded }
O, para ser más sucinto:
if (!(Get-Module "<moduleNameHere>")) { # module is not loaded }
fuente
!
que no funciona en PowerShell dependiendo de la versión?!
es un alias de-not
, pero no recomendaría usar alias en los scripts de ps1 en general. @GaTechThomas también tiene un comportamiento diferente, según lo especificado por @MichaelFreidgeim (no devuelve un valor verdadero para los módulos instalados, pero no importados).Un módulo puede estar en los siguientes estados:
Si solo desea tener la maldita cosa disponible en una sesión de PowerShell para su uso, aquí hay una función que lo hará o saldrá si no puede hacerlo:
function Load-Module ($m) { # If module is imported say that and do nothing if (Get-Module | Where-Object {$_.Name -eq $m}) { write-host "Module $m is already imported." } else { # If module is not imported, but available on disk then import if (Get-Module -ListAvailable | Where-Object {$_.Name -eq $m}) { Import-Module $m -Verbose } else { # If module is not imported, not available on disk, but is in online gallery then install and import if (Find-Module -Name $m | Where-Object {$_.Name -eq $m}) { Install-Module -Name $m -Force -Verbose -Scope CurrentUser Import-Module $m -Verbose } else { # If module is not imported, not available and not in online gallery then abort write-host "Module $m not imported, not available and not in online gallery, exiting." EXIT 1 } } } } Load-Module "ModuleName" # Use "PoshRSJob" to test it out
fuente
La versión actual de Powershell tiene una
Get-InstalledModule
función que se adapta bien a este propósito (o al menos lo hizo en mi caso).El único problema con esto es que genera una excepción si el módulo que se solicita no existe, por lo que debemos configurarlo
ErrorAction
adecuadamente para suprimir ese caso.if ((Get-InstalledModule ` -Name "AzureRm.Profile" ` -MinimumVersion 5.0 ` # Optionally specify minimum version to have -ErrorAction SilentlyContinue) -eq $null) { # Install it... }
fuente
Simplemente revisando esto, ya que es algo que acabo de enfrentar y hay algunas cosas incorrectas en las respuestas (aunque se menciona en los comentarios).
Aunque lo primero. Las preguntas originales preguntan cómo saber si un módulo de PowerShell está instalado. ¡Tenemos que hablar de la palabra instalada! No instala módulos de PowerShell (no de la forma tradicional en que instala el software de todos modos).
Los módulos de PowerShell están disponibles (es decir, están en la ruta del módulo de PowerShell) o se importan (se importan a su sesión y puede llamar a las funciones que contiene). Así es como verificar la ruta de su módulo, en caso de que quiera saber dónde almacenar un módulo:
$env:psmodulepath
Yo diría que se está volviendo común usar C: \ Archivos de programa \ WindowsPowerShell \ Modules; más a menudo debido a que está disponible para todos los usuarios, pero si desea bloquear sus módulos en su propia sesión, inclúyalos en su perfil.C: \ Users \% username% \ Documents \ WindowsPowerShell \ Modules;
Muy bien, volvamos a los dos estados.
¿Está disponible el módulo (usando disponible para significar instalado en la pregunta original)?
Esto le indica si un módulo está disponible para importar.
¿Se importa el módulo? (Estoy usando esto como la respuesta para la palabra 'existe' en la pregunta original).
Esto devolverá una carga vacía de nada si el módulo no se importa, o una descripción de una línea del módulo si lo es. Como siempre en Stack Overflow, pruebe los comandos anteriores en sus propios módulos.
fuente
Get-InstalledModule
que no devuelve el mismo resultado queGet-Module -ListAvailable
Cuando utilizo módulos no predeterminados en mis scripts, llamo a la función a continuación. Además del nombre del módulo, puede proporcionar una versión mínima.
# See https://www.powershellgallery.com/ for module and version info Function Install-ModuleIfNotInstalled( [string] [Parameter(Mandatory = $true)] $moduleName, [string] $minimalVersion ) { $module = Get-Module -Name $moduleName -ListAvailable |` Where-Object { $null -eq $minimalVersion -or $minimalVersion -ge $_.Version } |` Select-Object -Last 1 if ($null -ne $module) { Write-Verbose ('Module {0} (v{1}) is available.' -f $moduleName, $module.Version) } else { Import-Module -Name 'PowershellGet' $installedModule = Get-InstalledModule -Name $moduleName -ErrorAction SilentlyContinue if ($null -ne $installedModule) { Write-Verbose ('Module [{0}] (v {1}) is installed.' -f $moduleName, $installedModule.Version) } if ($null -eq $installedModule -or ($null -ne $minimalVersion -and $installedModule.Version -lt $minimalVersion)) { Write-Verbose ('Module {0} min.vers {1}: not installed; check if nuget v2.8.5.201 or later is installed.' -f $moduleName, $minimalVersion) #First check if package provider NuGet is installed. Incase an older version is installed the required version is installed explicitly if ((Get-PackageProvider -Name NuGet -Force).Version -lt '2.8.5.201') { Write-Warning ('Module {0} min.vers {1}: Install nuget!' -f $moduleName, $minimalVersion) Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Scope CurrentUser -Force } $optionalArgs = New-Object -TypeName Hashtable if ($null -ne $minimalVersion) { $optionalArgs['RequiredVersion'] = $minimalVersion } Write-Warning ('Install module {0} (version [{1}]) within scope of the current user.' -f $moduleName, $minimalVersion) Install-Module -Name $moduleName @optionalArgs -Scope CurrentUser -Force -Verbose } } }
ejemplo de uso:
Install-ModuleIfNotInstalled 'CosmosDB' '2.1.3.528'
Por favor, avíseme si es útil (o no)
fuente
Puede usar la
#Requires
declaración (admite módulos de PowerShell 3.0).Entonces, en la parte superior del script, simplemente agregue
#Requires -Module <ModuleName>
fuente
En mi humilde opinión, hay una diferencia entre verificar si un módulo es:
1) instalado o 2) importado:
Para comprobar si está instalado:
Opción 1: Uso
Get-Module
con-ListAvailable
parámetro:If(Get-Module -ListAvailable -Name "<ModuleName>"){'Module is installed'} Else{'Module is NOT installed'}
Opción 2: Usar
$error
objeto:$error.clear() Import-Module "<ModuleName>" -ErrorAction SilentlyContinue If($error){Write-Host 'Module is NOT installed'} Else{Write-Host 'Module is installed'}
Para comprobar si es importado:
Usando
Get-Module
con el-Name
parámetro (que puede omitir ya que es predeterminado de todos modos):if ((Get-Module -Name "<ModuleName>")) { Write-Host "Module is already imported (i.e. its cmdlets are available to be used.)" } else { Write-Warning "Module is NOT imported (must be installed before importing)." }
fuente
try { Import-Module SomeModule Write-Host "Module exists" } catch { Write-Host "Module does not exist" }
Cabe señalar que su cmdlet
Import-Module
no tiene un error de terminación, por lo tanto, la excepción no se detecta, por lo que, independientemente de cuál sea su declaración de captura, nunca devolverá la nueva declaración que ha escrito.( https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-6
Desde arriba:
Debería escribirse como:
Try { Import-Module SomeModule -Force -Erroraction stop Write-Host "yep" } Catch { Write-Host "nope" }
Que devuelve:
Y si realmente desea ser minucioso, debe agregar los otros cmdlets sugeridos
Get-Module -ListAvailable -Name
yGet-Module -Name
ser más cauteloso antes de ejecutar otras funciones / cmdlets. Y si está instalado desde psgallery o en otro lugar, también puede ejecutar unFind-Module
cmdlet para ver si hay una nueva versión disponible.fuente
Puedes usar el
Get-InstalledModule
If (-not(Get-InstalledModule SomeModule -ErrorAction silentlycontinue)) { Write-Host "Module does not exist" } Else { Write-Host "Module exists" }
fuente
''
if (Get-Module -ListAvailable -Name <<MODULE_NAME>>) { Write-Verbose -Message "<<MODULE_NAME>> Module does not exist." -Verbose } if (!(Get-Module -Name <<MODULE_NAME>>)) { Get-Module -ListAvailable <<MODULE_NAME>> | Import-Module | Out-Null }
''
fuente
Procedente de Linux. Preferiría usar algo similar a grep, por lo tanto, uso Select-String. Entonces, incluso si alguien no está seguro del nombre completo del módulo. Pueden proporcionar las iniciales y determinar si el módulo existe o no.
Get-Module -ListAvailable -All | Select-String Module_Name
(puede ser parte del nombre del módulo)fuente
Aquí está el código para verificar si el módulo AZ está instalado o no:
$checkModule = "AZ" $Installedmodules = Get-InstalledModule if ($Installedmodules.name -contains $checkModule) { "$checkModule is installed " } else { "$checkModule is not installed" }
fuente