Bir PowerShell modülünün kurulu olup olmadığını nasıl kontrol ederim?


92

Bir modülün olup olmadığını kontrol etmek için aşağıdakileri denedim:

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

Çıktı:

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

Bir hata alıyorum, ancak bir istisna atılmıyor, bu nedenle Module exists, olmamasına rağmen sonunda görüyoruz SomeModule.

Sisteme bir PowerShell modülünün takılı olup olmadığını tespit etmenin iyi bir yolu (tercihen bir hata oluşturmadan) var mı?


Yanıtlar:


119

Şu ListAvailableseçeneği kullanabilirsiniz Get-Module:

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

1
Önereceklerim: Import-Module NonexistingModule -ErrorAction SilentlyContinue IF ($ hata) {Yazma-Ana Bilgisayar 'Modülü mevcut değil'} ELSE {Yazma-Ana Bilgisayar 'Modülü var'} Ama sizin yolunuz daha iyi, daha zarif :)
Erik Blomgren

Bu harika çalışıyor. Teşekkürler. Kullanacağım Write-Warning "Module does not exist..." ;BreakAma bütün zor işi sen yaptın.
Craig.C

Kitaplıkları Import-Moduleve özel bir dll dosyası kullanarak içe aktarıyorsanız -ListAvailable, modülün yüklü olup olmadığını belirleme seçeneğini kullanmayın, çünkü listelenmeyecektir. Göre PowerShell 6 belgelerinde , "ListAvailable bu modüller mevcut oturumda yüklenir bile, PSModulePath ortam değişkeni bulunmayan modüller hakkında bilgi vermez".
Dave F

Bu, bir modülün Import-Module$env:PSModulePath
kurulup

35

ListAvailable seçeneği benim için çalışmıyor. Bunun yerine bu:

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

Ya da daha kısa olmak gerekirse:

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

@ oɔɯǝɹ -ListAvailable'in sadece mevcut olmadığını düşündüm, ancak hala Import-Module'ü deniyordum. Get-Module ile sorun yok
Craig.C

2
Modülün LOADED olup olmadığını kontrol edin (kendi başına yararlıdır - systemcentercentral.com/… ), ancak diğer cevap modülün var olup olmadığını kontrol etmez.
Michael Freidgeim

1
Bu, ListAvailable kullanmaktan çok daha hızlı yürütülür.
GaTechThomas

!Sürüme bağlı olarak powershell'de çalışmadığından oldukça emin misiniz?
Kolob Canyon

2
@KolobCanyon !bir takma addır -not, ancak genel olarak ps1 komut dosyalarında takma adların kullanılmasını önermem . @GaTechThomas ayrıca @MichaelFreidgeim tarafından belirtildiği gibi farklı bir davranışa sahiptir (yüklenen, ancak içe aktarılmayan modüller için doğru bir değer döndürmez).
AndreasHassing

27

Bir modül aşağıdaki durumlarda olabilir:

  • ithal
  • diskte (veya yerel ağda) mevcut
  • çevrimiçi galeride mevcut

Sadece bir PowerShell oturumunda kullanım için kullanılabilir olmasını istiyorsanız, işte bunu yapacak veya yapamazsa çıkacak bir işlev:

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

1
bu harika "hepsi bir arada" çözüm (Load-Module'ü yalnızca EXIT yerine $ true / $ false döndürecek şekilde değiştirdim)
Andrzej Martyna

17

Powershell'in mevcut sürümü bu amaca çok uygun bir Get-InstalledModuleişleve sahip (veya en azından benim durumumda yaptı).

Get-InstalledModule

Açıklama

Get-InstalledModuleCmdlet bir bilgisayara yüklenir PowerShell modülleri alır.

Bununla ilgili tek sorun, talep edilen modül mevcut değilse bir istisna atmasıdır, bu nedenle ErrorActionbu durumu bastırmak için uygun şekilde ayarlamamız gerekir .

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

    # Install it...
}

13

Sadece karşılaştığım bir şey olduğu için bunu tekrar gözden geçiriyorum ve cevaplarda bazı yanlış şeyler var (yorumlarda bahsedilmesine rağmen).

Yine de ilk şey. Orijinal sorular, bir PowerShell modülünün kurulu olup olmadığını nasıl anlayacağınızı sorar. Yüklenen kelime hakkında konuşmalıyız! PowerShell modüllerini kurmazsınız (zaten geleneksel şekilde yazılım yükleme yönteminiz değildir).

PowerShell modülleri ya kullanılabilir (yani, PowerShell modülü yolunda bulunurlar) veya içe aktarılırlar (oturumunuza aktarılırlar ve içerilen işlevleri çağırabilirsiniz). Bir modülü nerede saklayacağınızı bilmek istemeniz durumunda modül yolunuzu şu şekilde kontrol edebilirsiniz:

$env:psmodulepath

C: \ Program Files \ WindowsPowerShell \ Modules kullanmanın yaygınlaştığını iddia ediyorum ; tüm kullanıcılar tarafından kullanılabilir olduğundan daha sık, ancak modüllerinizi kendi oturumunuza kilitlemek istiyorsanız, bunları profilinize ekleyin. C: \ Kullanıcılar \% kullanıcı adı% \ Documents \ WindowsPowerShell \ Modules;

Pekala, iki eyalete geri dönelim.

Modül mevcut mu (orijinal soruda yüklü anlamına gelmek için kullanılabilir)?

Get-Module -Listavailable -Name <modulename>

Bu size bir modülün içe aktarılabilir olup olmadığını söyler.

Modül ithal edildi mi? (Bunu orijinal soruda 'var' kelimesinin cevabı olarak kullanıyorum).

Get-module -Name <modulename>

Bu, ya modül içe aktarılmadıysa boş bir yük ya da eğer öyleyse modülün tek satırlık bir açıklaması döndürür. Stack Overflow'da her zaman olduğu gibi, yukarıdaki komutları kendi modüllerinizde deneyin.


1
Modülü PowerShell'e kurabilirsiniz. PowerShellGet, Get-InstalledModuleaynı çıktıyı döndürmeyen bir komuta sahipGet-Module -ListAvailable
Igor,

9

Komut dosyalarımda varsayılan olmayan bir modül kullandığımda aşağıdaki işlevi çağırıyorum. Modül adının yanında minimum bir sürüm de belirtebilirsiniz.

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

kullanım örneği:

Install-ModuleIfNotInstalled 'CosmosDB' '2.1.3.528'

Lütfen işe yarayıp yaramadığını bilmeme izin ver


4

İfadeyi kullanabilirsiniz #Requires(PowerShell 3.0'dan modülleri destekler).

#Requires ifadesi, PowerShell sürümü, modülleri, ek bileşenleri ve modülü ve ek bileşen sürümü önkoşulları karşılanmadığı sürece bir komut dosyasının çalışmasını engeller.

Yani senaryonun üst kısmına şunu eklemeniz yeterlidir: #Requires -Module <ModuleName>

Gerekli modüller geçerli oturumda değilse, PowerShell bunları içe aktarır.

Modüller içe aktarılamıyorsa, PowerShell bir sonlandırma hatası atar.


3

IMHO, bir modül olup olmadığını kontrol etmek arasında fark var:

1) yüklü veya 2) içe aktarılmış:

Kurulu olup olmadığını kontrol etmek için:

Seçenek 1: Parametre Get-Moduleile kullanmak -ListAvailable:

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

Seçenek 2: $errorNesneyi kullanma :

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

İçe aktarılıp aktarılmadığını kontrol etmek için:

Parametre Get-Moduleile kullanmak -Name( yine de varsayılan olduğu için atlayabilirsiniz ):

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

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

Cmdlet'inizin Import-Modulesonlandırma hatası olmadığına dikkat edilmelidir , bu nedenle istisna yakalanmaz, bu nedenle catch ifadeniz ne olursa olsun yazdığınız yeni ifadeyi asla geri döndürmez.

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

Yukarıdan:

"Sonlandırma hatası, bir ifadenin çalışmasını durdurur. PowerShell, bir sonlandırma hatasını bir şekilde işlemezse, PowerShell ayrıca işlevi veya betiği geçerli ardışık düzen kullanarak çalıştırmayı durdurur. C # gibi diğer dillerde, sonlandırma hataları istisnalar olarak adlandırılır . Hatalar hakkında daha fazla bilgi için about_Errors bölümüne bakın. "

Şu şekilde yazılmalıdır:

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

Hangi döndürür:

nope

Ve gerçekten eksiksiz olmak istiyorsanız, önerilen diğer cmdlet'leri eklemeniz Get-Module -ListAvailable -Nameve Get-Module -Namediğer işlevleri / cmdlet'leri çalıştırmadan önce çok dikkatli olmanız gerekir. Ve eğer psgallery'den veya başka bir yerden kurulmuşsa, Find-Moduleyeni bir sürüm olup olmadığını görmek için bir cmdlet de çalıştırabilirsiniz .


2

Kullanabilirsiniz Get-InstalledModule

If (-not(Get-InstalledModule SomeModule -ErrorAction silentlycontinue)) {
  Write-Host "Module does not exist"
}
Else {
  Write-Host "Module exists"
}

Burada birçok iyi cevap var, ancak bu yeni basit yöntemle, bu muhtemelen kabul edilen yeni cevap olmalı.
not2qubit

1
  • Modülün yüklü olup olmadığını ilk test edin
  • Sonra içe aktar

''

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
}

''


1

Linux geçmişinden geliyor. Grep'e benzer bir şey kullanmayı tercih ederim, bu yüzden Select-String kullanıyorum. Yani birisi tam modül adından emin olmasa bile. Baş harflerini sağlayabilir ve modülün var olup olmadığını belirleyebilirler.

Get-Module -ListAvailable -All | Select-String Module_Name(modül adının bir parçası olabilir)


1

AZ modülünün kurulu olup olmadığını kontrol etmek için kod:

$checkModule = "AZ"

$Installedmodules = Get-InstalledModule

if ($Installedmodules.name -contains $checkModule)
{

    "$checkModule is installed "

}

else {

    "$checkModule is not installed"

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.