Para verificar se existe um módulo, tentei o seguinte:
try {
Import-Module SomeModule
Write-Host "Module exists"
}
catch {
Write-Host "Module does not exist"
}
O resultado é:
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
Eu recebo um erro, mas nenhuma exceção é lançada, então vemos Module exists
no final, embora SomeModule
não exista.
Existe uma boa maneira (de preferência sem gerar um erro) para detectar se um módulo PowerShell está instalado no sistema?
powershell
Klemens Schindler
fonte
fonte
Respostas:
Você pode usar a
ListAvailable
opção deGet-Module
:if (Get-Module -ListAvailable -Name SomeModule) { Write-Host "Module exists" } else { Write-Host "Module does not exist" }
fonte
Write-Warning "Module does not exist..." ;Break
Mas você fez todo o trabalho duro.Import-Module
um arquivo dll personalizado, não use a-ListAvailable
opção para determinar se o módulo está instalado porque ele não será listado. De acordo com a documentação do PowerShell 6 , "ListAvailable não retorna informações sobre módulos que não são encontrados na variável de ambiente PSModulePath, mesmo se esses módulos forem carregados na sessão atual".Import-Module
), apenas determina se o módulo está imediatamente disponível para ser instalado sem especificar um local específico ainda não em$env:PSModulePath
A opção ListAvailable não funciona para mim. Em vez disso:
if (-not (Get-Module -Name "<moduleNameHere>")) { # module is not loaded }
Ou, para ser mais sucinto:
if (!(Get-Module "<moduleNameHere>")) { # module is not loaded }
fonte
!
que não funciona no PowerShell dependendo da versão?!
é um alias para-not
, mas eu não recomendaria usar aliases em scripts ps1 em geral. @GaTechThomas também possui um comportamento diferente, conforme especificado por @MichaelFreidgeim (não retorna um valor verdadeiro para os módulos instalados, mas não importados).Um módulo pode estar nos seguintes estados:
Se você apenas deseja ter o danado disponível em uma sessão do PowerShell para uso, aqui está uma função que fará isso ou sairá se não puder fazer isso:
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
fonte
A versão atual do Powershell tem uma
Get-InstalledModule
função que se adapta bem a esse propósito (ou pelo menos no meu caso).O único problema com ele é que ele lança uma exceção se o módulo que está sendo solicitado não existir, portanto, precisamos definir
ErrorAction
adequadamente para suprimir esse caso.if ((Get-InstalledModule ` -Name "AzureRm.Profile" ` -MinimumVersion 5.0 ` # Optionally specify minimum version to have -ErrorAction SilentlyContinue) -eq $null) { # Install it... }
fonte
Apenas revisitando isso, pois é algo que acabei de enfrentar e há algumas coisas incorretas nas respostas (embora sejam mencionadas nos comentários).
Mas a primeira coisa. As perguntas originais perguntam como saber se um módulo PowerShell está instalado. Precisamos falar sobre a palavra instalada! Você não instala módulos do PowerShell (não da maneira tradicional de instalar o software).
Os módulos do PowerShell estão disponíveis (ou seja, estão no caminho do módulo do PowerShell) ou são importados (são importados para a sua sessão e você pode chamar as funções contidas). Veja como verificar o caminho do módulo, caso você queira saber onde armazenar um módulo:
$env:psmodulepath
Eu diria que está se tornando comum usar C: \ Arquivos de Programas \ WindowsPowerShell \ Modules; mais frequentemente devido a estar disponível para todos os usuários, mas se você quiser bloquear seus módulos para sua própria sessão, inclua-os em seu perfil. C: \ Users \% username% \ Documents \ WindowsPowerShell \ Modules;
Tudo bem, de volta aos dois estados.
O módulo está disponível (usando disponível para significar instalado na questão original)?
Get-Module -Listavailable -Name <modulename>
Isso informa se um módulo está disponível para importação.
O módulo é importado? (Estou usando isso como a resposta para a palavra 'existe' na pergunta original).
Get-module -Name <modulename>
Isso retornará um carregamento vazio de nada se o módulo não for importado ou uma descrição de uma linha do módulo se for. Como sempre no Stack Overflow, tente os comandos acima em seus próprios módulos.
fonte
Get-InstalledModule
que não está retornando a mesma saída queGet-Module -ListAvailable
Quando eu uso módulos não padrão em meus scripts, chamo a função abaixo. Ao lado do nome do módulo, você pode fornecer uma versão 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 } } }
exemplo de uso:
Install-ModuleIfNotInstalled 'CosmosDB' '2.1.3.528'
Por favor, deixe-me saber se é útil (ou não)
fonte
Você pode usar a
#Requires
instrução (oferece suporte a módulos do PowerShell 3.0).Portanto, no início do script, basta adicionar
#Requires -Module <ModuleName>
fonte
IMHO, há diferença entre verificar se um módulo é:
1) instalado ou 2) importado:
Para verificar se instalado:
Opção 1: usando
Get-Module
com o-ListAvailable
parâmetro:If(Get-Module -ListAvailable -Name "<ModuleName>"){'Module is installed'} Else{'Module is NOT installed'}
Opção 2: usando o
$error
objeto:$error.clear() Import-Module "<ModuleName>" -ErrorAction SilentlyContinue If($error){Write-Host 'Module is NOT installed'} Else{Write-Host 'Module is installed'}
Para verificar se importado:
Usando
Get-Module
com-Name
parâmetro (que você pode omitir, pois é o padrão de qualquer maneira):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)." }
fonte
try { Import-Module SomeModule Write-Host "Module exists" } catch { Write-Host "Module does not exist" }
Deve-se observar que seu cmdlet
Import-Module
não tem erro de encerramento, portanto, a exceção não está sendo capturada, portanto, não importa qual seja sua instrução catch nunca retornará a nova instrução que você escreveu.( https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-6
De cima:
Deve ser escrito como:
Try { Import-Module SomeModule -Force -Erroraction stop Write-Host "yep" } Catch { Write-Host "nope" }
Que retorna:
E se você realmente deseja ser completo, deve adicionar os outros cmdlets sugeridos
Get-Module -ListAvailable -Name
eGet-Module -Name
ser extremamente cauteloso antes de executar outras funções / cmdlets. E se for instalado de psgallery ou de outro lugar, você também pode executar umFind-Module
cmdlet para ver se há uma nova versão disponível.fonte
Você pode usar o
Get-InstalledModule
If (-not(Get-InstalledModule SomeModule -ErrorAction silentlycontinue)) { Write-Host "Module does not exist" } Else { Write-Host "Module exists" }
fonte
`` `
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 }
`` `
fonte
Vindo de experiência em Linux. Eu preferiria usar algo semelhante ao grep, portanto, uso Select-String. Portanto, mesmo se alguém não tiver certeza do nome completo do módulo. Eles podem fornecer as iniciais e determinar se o módulo existe ou não.
Get-Module -ListAvailable -All | Select-String Module_Name
(pode ser uma parte do nome do módulo)fonte
Aqui está o código para verificar se o módulo AZ está instalado ou não:
$checkModule = "AZ" $Installedmodules = Get-InstalledModule if ($Installedmodules.name -contains $checkModule) { "$checkModule is installed " } else { "$checkModule is not installed" }
fonte