web-dev-qa-db-fra.com

Comment vérifier si un module PowerShell est installé?

Pour vérifier si un module existe, j'ai essayé ce qui suit:

try {
    Import-Module SomeModule
    Write-Host "Module exists"
} 
catch {
    Write-Host "Module does not exist"
}

La sortie est:

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

Je reçois une erreur, mais aucune exception n'est levée, nous voyons donc Module exists à la fin, bien que SomeModule n'existe pas.

Existe-t-il un bon moyen (de préférence sans générer d'erreur) de détecter si un module PowerShell est installé sur le système?

44
Klemens Schindler

Vous pouvez utiliser l'option ListAvailable de Get-Module:

if (Get-Module -ListAvailable -Name SomeModule) {
    Write-Host "Module exists"
} 
else {
    Write-Host "Module does not exist"
}
71
Klemens Schindler

L'option ListAvailable ne fonctionne pas pour moi. Au lieu de cela cela:

if (-not (Get-Module -Name "<moduleNameHere>")) {
    # module is not loaded
}

Ou, pour être plus succinct:

if (!(Get-Module "<moduleNameHere>")) {
    # module is not loaded
}
20
tloyd

Un module peut être dans les états suivants:

  • importé
  • disponible sur disque (ou réseau local)
  • disponible dans la galerie en ligne

Si vous voulez simplement que la chose soit disponible dans une session PowerShell, voici une fonction qui le fera ou la quittera si elle ne peut pas le faire:

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
7
Rod

Je reviens sur cela car c'est quelque chose que je viens de regarder et il y a des trucs incorrects dans les réponses (bien que ce soit mentionné dans les commentaires). 

Première chose cependant. Les questions initiales demandent comment savoir si un module PowerShell est installé. Nous devons parler du mot installé! Vous n'installez pas de modules PowerShell (de toute façon, vous n'installez pas de logiciel).

Les modules PowerShell sont soit disponibles (c'est-à-dire qu'ils se trouvent sur le chemin du module PowerShell), soit importés (ils sont importés dans votre session et vous pouvez appeler les fonctions contenues). Voici comment vérifier votre chemin de module, au cas où vous voudriez savoir où stocker un module:

$env:psmodulepath

Je dirais qu'il est devenu courant d'utiliser C:\Program Files\WindowsPowerShell\Modules; plus souvent car il est disponible pour tous les utilisateurs, mais si vous souhaitez verrouiller vos modules sur votre propre session, incluez-les dans votre profil. C:\Utilisateurs \% nom d'utilisateur%\Documents\WindowsPowerShell\Modules;

Bon, revenons aux deux états.

Le module est-il disponible (utiliser signifie signifie installé dans la question d'origine)?

Get-Module -Listavailable -Name <modulename>

Cela vous indique si un module est disponible pour l'importation.

Le module est-il importé? (J'utilise ceci comme réponse pour le mot "existe" dans la question initiale).

Get-module -Name <modulename>

Cela retournera soit une charge vide de rien si le module n'est pas importé, soit une description du module sur une ligne si c'est le cas. Comme toujours sur Stack Overflow, essayez les commandes ci-dessus sur vos propres modules.

7
bytejunkie

IMHO, il y a une différence entre vérifier si un module est:

1) installé ou 2) importé:

Pour vérifier si installé:

Option 1: Utilisation de Get-Module avec le paramètre -ListAvailable:

If(Get-Module -ListAvailable -Name "<ModuleName>"){'Module is installed'}
Else{'Module is NOT installed'}

Option 2: Utiliser l'objet $error:

$error.clear()
Import-Module "<ModuleName>" -ErrorAction SilentlyContinue
If($error){Write-Host 'Module is NOT installed'}
Else{Write-Host 'Module is installed'}

Pour vérifier si importé:

Utilisation de Get-Module avec le paramètre -Name (que vous pouvez omettre car il s’agit de toute façon de default):

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)."
}
2
Eddie Kumar

La version actuelle de Powershell a une fonction Get-InstalledModule qui convient bien à cet usage (ou du moins elle l’a fait dans mon cas).

Get-InstalledModule

La description

La cmdlet Get-InstalledModule obtient les modules PowerShell installés sur un ordinateur.

Le seul problème avec cela est qu'il lève une exception si le module demandé n'existe pas. Nous devons donc définir ErrorAction de manière appropriée pour supprimer ce cas.

if (Get-InstalledModule `
    -Name "AzureRm.Profile" `
    -MinimumVersion 5.0 ` # Optionally specify minimum version to have
    -ErrorAction SilentlyContinue) -eq $null) {

    # Install it...
}
1
NightOwl888

Venant de fond Linux. Je préférerais utiliser quelque chose de similaire à grep, donc j'utilise Select-String. Donc, même si quelqu'un n'est pas sûr du nom complet du module. Ils peuvent fournir les initiales et déterminer si le module existe ou non.

Get-Module -ListAvailable -All | Select-String Module_Name (peut faire partie du nom du module)

0
010 M
  • Premier test si le module est chargé
  • Puis importer

`` `

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
}

`` `

0
Juliano Barbosa
try {
    Import-Module SomeModule
    Write-Host "Module exists"
} 
catch {
    Write-Host "Module does not exist"
}

Il convient de souligner que votre cmdlet Import-Module n'a pas d'erreur de fin. Par conséquent, l'exception n'est pas interceptée. Par conséquent, votre instruction catch ne renverra jamais la nouvelle instruction que vous avez écrite.

( https://docs.Microsoft.com/en-us/powershell/module/Microsoft.powershell.core/about/about_try_catch_finally?view=powershell-6

D'en haut:

"Une erreur de terminaison arrête l'exécution d'une instruction. Si PowerShell ne gère pas une erreur de terminaison, PowerShell cesse également d'exécuter la fonction ou le script à l'aide du pipeline en cours. Dans d'autres langages, tels que C #, les erreurs de terminaison sont appelées exceptions. Pour plus d'informations sur les erreurs, consultez about_Errors. "

Il devrait être écrit comme:

Try {
    Import-Module SomeModule -Force -Erroraction stop
    Write-Host "yep"
}
Catch {
    Write-Host "nope"
}

Qui retourne:

nope

Et si vous voulez vraiment être minutieux, vous devez ajouter les autres cmdlets suggérées Get-Module -ListAvailable -Name et Get-Module -Name pour être extrêmement prudent, avant d'exécuter d'autres fonctions/cmdlets. Et s'il est installé à partir de psgallery ou ailleurs, vous pouvez également exécuter une cmdlet Find-Module pour voir si une nouvelle version est disponible.

0
mwtilton

Lorsque j'utilise un module autre que celui par défaut dans mes scripts, j'appelle la fonction ci-dessous. En plus du nom du module, vous pouvez fournir une version minimale.

# 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
        } 
    }
}

exemple d'utilisation:

Install-ModuleIfNotInstalled 'CosmosDB' '2.1.3.528'

S'il vous plaît laissez-moi savoir si c'est utile (ou pas)

0
TJ Galama