it-swarm.com.de

Wie überprüfe ich, ob ein PowerShell-Modul installiert ist?

Um zu prüfen, ob ein Modul existiert, habe ich folgendes versucht:

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

Die Ausgabe ist:

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

Ich erhalte eine Fehlermeldung, aber es wird keine Ausnahme ausgelöst. Am Ende sehen wir Module exists, obwohl SomeModule nicht vorhanden ist.

Gibt es eine gute Möglichkeit (vorzugsweise ohne einen Fehler zu generieren), um festzustellen, ob ein PowerShell-Modul auf dem System installiert ist?

44

Sie können die Option ListAvailable von Get-Module verwenden:

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

Die ListAvailable-Option funktioniert für mich nicht. Stattdessen tut dies:

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

Oder, um es kurz zu fassen:

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

Ein Modul könnte sich in folgenden Zuständen befinden:

  • importiert
  • auf der Festplatte (oder im lokalen Netzwerk) verfügbar
  • in der Online-Galerie verfügbar

Wenn Sie nur das verdammte Ding in einer PowerShell-Sitzung zur Verfügung haben möchten, können Sie dies mit einer Funktion tun oder beenden, wenn dies nicht möglich ist:

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

Ich denke nur noch einmal darüber nach, denn es ist etwas, dem ich gerade gegenübergestanden habe, und die Antworten enthalten einige falsche Informationen (obwohl dies in den Kommentaren erwähnt wird). 

Das erste aber. Die ursprüngliche Frage fragt, wie Sie feststellen können, ob ein PowerShell-Modul installiert ist. Wir müssen über das installierte Wort sprechen! Sie installieren keine PowerShell-Module (ohnehin nicht auf die herkömmliche Art und Weise, wie Sie Software installieren).

PowerShell-Module sind entweder verfügbar (d. H. Sie befinden sich im Pfad des PowerShell-Moduls), oder sie werden importiert (sie werden in Ihre Sitzung importiert und Sie können die enthaltenen Funktionen aufrufen). So prüfen Sie Ihren Modulpfad, wenn Sie wissen möchten, wo ein Modul gespeichert werden soll:

$env:psmodulepath

Ich würde behaupten, dass es üblich ist, C:\Programme\WindowsPowerShell\Modules zu verwenden. öfter, weil es für alle Benutzer verfügbar ist. Wenn Sie jedoch Ihre Module für Ihre eigene Sitzung sperren möchten, nehmen Sie sie in Ihr Profil auf. C:\Benutzer \% Benutzername%\Dokumente\WindowsPowerShell\Modules;

Okay, zurück zu den beiden Staaten.

Ist das Modul verfügbar (bedeutet, dass es in der ursprünglichen Frage installiert wurde)?

Get-Module -Listavailable -Name <modulename>

Dadurch erfahren Sie, ob ein Modul für den Import verfügbar ist.

Ist das Modul importiert? (Ich verwende dies als Antwort für das Wort "existiert" in der ursprünglichen Frage).

Get-module -Name <modulename>

Dies gibt entweder eine leere Ladung von nichts zurück, wenn das Modul nicht importiert wird, oder eine einzeilige Beschreibung des Moduls, falls dies der Fall ist. Versuchen Sie wie immer bei Stack Overflow die obigen Befehle für Ihre eigenen Module.

7
bytejunkie

IMHO gibt es einen Unterschied zwischen der Prüfung, ob ein Modul

1) installiert oder 2) importiert:

Um zu überprüfen, ob installiert ist:

Option 1: Verwenden von Get-Module mit -ListAvailable-Parameter:

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

Option 2: $error-Objekt verwenden:

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

Um zu prüfen, ob importiert wird:

Verwenden Sie Get-Module mit dem -Name-Parameter (den Sie auslassen können, da es sich dabei um default handelt)

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

Die aktuelle Version von Powershell hat eine Get-InstalledModule-Funktion , die gut zu diesem Zweck passt (oder zumindest in meinem Fall).

Get-InstalledModule

Beschreibung

Mit dem Cmdlet Get-InstalledModule werden auf einem Computer installierte PowerShell-Module abgerufen.

Das einzige Problem dabei ist, dass eine Ausnahme ausgelöst wird, wenn das angeforderte Modul nicht vorhanden ist. Daher müssen Sie ErrorAction entsprechend einstellen, um diesen Fall zu unterdrücken.

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

    # Install it...
}
1
NightOwl888

Ich komme aus dem Linux-Hintergrund. Ich würde es vorziehen, etwas Ähnliches wie grep zu verwenden, daher verwende ich Select-String. Also auch wenn sich jemand des vollständigen Modulnamens nicht sicher ist. Sie können die Initialen bereitstellen und feststellen, ob das Modul vorhanden ist oder nicht.

Get-Module -ListAvailable -All | Select-String Module_Name (kann Teil des Modulnamens sein)

0
010 M
  • Testen Sie zunächst, ob das Modul geladen ist
  • Dann importieren

`` `

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

Es sollte darauf hingewiesen werden, dass Ihr Cmdlet Import-Module keinen Abschlussfehler aufweist. Daher wird die Ausnahme nicht abgefangen, unabhängig davon, welche catch-Anweisung die neu geschriebene Anweisung zurückgibt.

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

Von Oben:

"Ein Beendigungsfehler stoppt die Ausführung einer Anweisung. Wenn PowerShell einen Beendigungsfehler in keiner Weise behandelt, beendet PowerShell auch die Ausführung der Funktion oder des Skripts mit der aktuellen Pipeline. In anderen Sprachen, z. B. C #, werden Beendigungsfehler als Ausnahmen bezeichnet Weitere Informationen zu Fehlern finden Sie unter about_Errors. "

Es sollte geschrieben werden als:

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

Welches gibt zurück:

nope

Und wenn Sie wirklich gründlich sein möchten, sollten Sie die anderen vorgeschlagenen Cmdlets Get-Module -ListAvailable -Name und Get-Module -Name hinzufügen, um besonders vorsichtig zu sein, bevor Sie andere Funktionen/Cmdlets ausführen. Und wenn es von psgallery oder anderswo installiert wurde, können Sie auch ein Find-Module-Cmdlet ausführen, um festzustellen, ob eine neue Version verfügbar ist.

0
mwtilton

Wenn ich in meinen Skripten nicht standardmäßige Module verwende, rufe ich die folgende Funktion auf. Neben dem Modulnamen können Sie eine Mindestversion angeben.

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

anwendungsbeispiel:

Install-ModuleIfNotInstalled 'CosmosDB' '2.1.3.528'

Bitte lassen Sie mich wissen, ob es nützlich ist (oder nicht)

0
TJ Galama