PowerShellモジュールがインストールされているかどうかを確認するにはどうすればよいですか?


97

モジュールが存在するかどうかを確認するために、次のことを試しました。

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

出力は次のとおりです。

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

エラーが発生しますが、例外はスローされないためModule existsSomeModule存在しませんが、最終的には表示されます。

PowerShellモジュールがシステムにインストールされているかどうかを検出するための良い方法はありますか(できればエラーを生成せずに)?


回答:


126

次のListAvailableオプションを使用できますGet-Module

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

1
私は提案するつもりでした:Import-Module NonexistingModule -ErrorAction SilentlyContinue IF($ error){Write-Host 'モジュールは存在しません'} ELSE {Write-Host 'モジュールは存在します'}しかし、あなたのやり方はより良く、よりエレガントです:)
Erik Blomgren 2015

これはうまくいきます。ありがとう。私が使用しますWrite-Warning "Module does not exist..." ;Breakしかし、あなたはすべての大変な仕事をしました。
Craig.C 2016

Import-Moduleとカスタムdllファイルを使用してライブラリをインポート-ListAvailableする場合は、モジュールがリストされないため、モジュールがインストールされているかどうかを判断するオプションを使用しないでください。PowerShell 6のドキュメントによると、「ListAvailableは、PSModulePath環境変数に見つからないモジュールに関する情報を、それらのモジュールが現在のセッションで読み込まれている場合でも返しません」。
デイブ

これは、モジュールがインストールされているかどうかを判断するのではなく(つまり、まだインストールされていImport-Moduleない特定の場所を指定せずに、モジュールをすぐにインストールできるかどうかを判断するだけです)$env:PSModulePath
SlogmeisterExtraordinaire20年

34

ListAvailableオプションが機能しません。代わりにこれは行います:

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

または、より簡潔にするために:

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

@oɔɯǝɹ-ListAvailableは単に利用できないと思いましたが、それでもImport-Moduleを試していました。Get-Moduleを使用すれば問題あり
ません

3
モジュールLOADED(それ自体で便利です--systemcentercentral.com/…)かどうかを確認しますが、他の回答ではモジュールが存在するかどうかを確認しません。
Michael Freidgeim 2017年

1
これは、ListAvailableを使用するよりもはるかに高速に実行されます。
GaTechThomas 2017

!バージョンによっては、PowerShellで機能しないことはかなり確かですか?
コロブキャニオン2017

2
@KolobCanyonはの!エイリアスです-notが、一般的にps1スクリプトでエイリアスを使用することはお勧めしません。@GaTechThomasは、@ MichaelFreidgeimで指定されているように、動作も異なります(インストールされているが、インポートされていないモジュールの真の値は返しません)。
AndreasHassing 2018年

28

モジュールは次の状態になる可能性があります。

  • インポート
  • ディスク(またはローカルネットワーク)で利用可能
  • オンラインギャラリーで入手可能

PowerShellセッションで使用できるようにしたいだけの場合は、これを実行するか、実行できない場合に終了する関数を次に示します。

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
これは優れた「オールインワン」ソリューションです(Load-Moduleを変更して、EXITではなく$ true / $ falseを返すようにしました)
Andrzej Martyna 2018

これは美しいです。
ショーン

17

Powershellの現在のバージョンには、この目的によく合うGet-InstalledModule機能があります(または、少なくとも私の場合はそうしました)。

Get-InstalledModule

説明

Get-InstalledModuleコマンドレットは、コンピュータにインストールされているのPowerShellモジュールを取得します。

唯一の問題は、要求されているモジュールが存在しない場合に例外がスローErrorActionされることです。そのため、そのケースを抑制するために適切に設定する必要があります。

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

    # Install it...
}

13

これは私が直面したばかりのことであり、回答に間違ったものがいくつかあるので、これを再検討してください(コメントに記載されていますが)。

しかし、最初に。元の質問は、PowerShellモジュールがインストールされているかどうかを確認する方法を尋ねています。インストールされている単語について話す必要があります!PowerShellモジュールはインストールしません(とにかくソフトウェアをインストールする従来の方法ではありません)。

PowerShellモジュールは、使用可能(つまり、PowerShellモジュールパス上にある)またはインポートされます(セッションにインポートされ、含まれている関数を呼び出すことができます)。モジュールの保存場所を知りたい場合は、モジュールパスを確認する方法は次のとおりです。

$env:psmodulepath

C:\ Program Files \ WindowsPowerShell \ Modulesを使用することが一般的になりつつあると私は主張します。多くの場合、すべてのユーザーが利用できるためですが、モジュールを自分のセッションにロックダウンする場合は、それらをプロファイルに含めてください。C:\ Users \%username%\ Documents \ WindowsPowerShell \ Modules;

了解しました。2つの状態に戻ります。

モジュールは利用可能ですか(利用可能を使用して、元の質問にインストールされていることを意味します)?

Get-Module -Listavailable -Name <modulename>

これにより、モジュールがインポート可能かどうかがわかります。

モジュールはインポートされていますか?(私はこれを元の質問の「存在する」という単語の答えとして使用しています)。

Get-module -Name <modulename>

これにより、モジュールがインポートされていない場合は何もない空のロードが返され、インポートされている場合はモジュールの1行の説明が返されます。Stack Overflowの場合と同様に、独自のモジュールで上記のコマンドを試してください。


1
PowerShellにモジュールをインストールできます。PowerShellGetは、コマンドがあるGet-InstalledModuleのと同じ出力を返すされていませんGet-Module -ListAvailable
イゴール

9

スクリプトでデフォルト以外のモジュールを使用する場合は、以下の関数を呼び出します。モジュール名の横に、最小バージョンを指定できます。

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

使用例:

Install-ModuleIfNotInstalled 'CosmosDB' '2.1.3.528'

役に立つかどうか教えてください


4

この#Requiresステートメントを使用できます(PowerShell 3.0のモジュールをサポートします)。

#Requiresステートメントは、PowerShellのバージョン、モジュール、スナップイン、およびモジュールとスナップインのバージョンの前提条件が満たされない限り、スクリプトが実行されないようにします。

したがって、スクリプトの先頭に、単に追加します #Requires -Module <ModuleName>

必要なモジュールが現在のセッションにない場合、PowerShellはそれらをインポートします。

モジュールをインポートできない場合、PowerShellは終了エラーをスローします。


3

私見ですが、モジュールが次のいずれであるかを確認することには違いがあります。

1)インストール済み、または2)インポート済み:

インストールされているかどうかを確認するには:

オプション1:パラメーターで使用Get-Moduleする-ListAvailable

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

オプション2:$errorオブジェクトの使用:

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

インポートされたかどうかを確認するには:

使用Get-Moduleして-Name(そのまま使用すると、省略可能なパラメータデフォルトとにかく):

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

コマンドレットにImport-Moduleは終了エラーがないため、例外がキャッチされないため、catchステートメントが何であっても、記述した新しいステートメントが返されることはありません。

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

上から:

「終了エラーはステートメントの実行を停止します。PowerShellが何らかの方法で終了エラーを処理しない場合、PowerShellは現在のパイプラインを使用した関数またはスクリプトの実行も停止します。C#などの他の言語では、終了エラーは例外と呼ばれます。 。エラーの詳細については、about_Errorsを参照してください。」

次のように書く必要があります。

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

どちらが返されますか:

nope

また、本当に徹底したい場合は、他の関数/コマンドレットを実行する前に、他の推奨コマンドレットGet-Module -ListAvailable -Nameを追加し、特に注意する必要がありますGet-Module -Name。また、psgalleryまたは他の場所からインストールされている場合は、Find-Moduleコマンドレットを実行して、新しいバージョンが利用可能かどうかを確認することもできます。


3

あなたは使用することができます Get-InstalledModule

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

ここには多くの良い答えがありますが、この新しい簡単な方法では、これがおそらく新しく受け入れられた答えになるはずです。
not2qubit

1
  • モジュールがロードされているかどうかの最初のテスト
  • 次にインポート

`` `

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のバックグラウンドから来ています。grepに似たものを使用したいので、Select-Stringを使用します。したがって、誰かが完全なモジュール名を知らなくても。彼らはイニシャルを提供し、モジュールが存在するかどうかを判断できます。

Get-Module -ListAvailable -All | Select-String Module_Name(モジュール名の一部にすることができます)


1

AZモジュールがインストールされているかどうかを確認するコードは次のとおりです。

$checkModule = "AZ"

$Installedmodules = Get-InstalledModule

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

    "$checkModule is installed "

}

else {

    "$checkModule is not installed"

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.