PowerShell 모듈이 설치되었는지 어떻게 확인합니까?


92

모듈이 있는지 확인하기 위해 다음을 시도했습니다.

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 exists결국 볼 수 SomeModule있습니다.

PowerShell 모듈이 시스템에 설치되어 있는지 감지하는 좋은 방법 (가급적이면 오류를 생성하지 않음)이 있습니까?


답변:


119

다음 ListAvailable옵션을 사용할 수 있습니다 Get-Module.

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

1
나는 suggets를하려고했다 : Import-Module NonexistingModule -ErrorAction SilentlyContinue IF ($ error) {Write-Host 'Module does not exist'} ELSE {Write-Host 'Module does exist'}하지만 당신의 방식은 더 낫고 우아합니다 :)
Erik Blomgren 2015

이것은 훌륭하게 작동합니다. 감사. 내가 사용 할게요 Write-Warning "Module does not exist..." ;Break하지만 당신은 모든 노력을 다했습니다.
Craig.C

Import-Module및 사용자 정의 dll 파일을 사용하여 라이브러리를 가져 오는 -ListAvailable경우 모듈이 나열되지 않으므로 모듈이 설치되었는지 확인 하는 옵션을 사용하지 마십시오 . PowerShell 6 설명서 에 따르면 "ListAvailable은 PSModulePath 환경 변수에서 찾을 수없는 모듈에 대한 정보를 반환하지 않습니다. 해당 모듈이 현재 세션에서로드 된 경우에도 마찬가지입니다."
Dave F

이것은 모듈이 설치되었는지 여부를 결정하지 않습니다 (예 Import-Module$env:PSModulePath
:)

35

ListAvailable 옵션이 작동하지 않습니다. 대신 다음을 수행합니다.

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

또는 더 간결하게 :

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

@ oɔɯǝɹ -ListAvailable은 단순히 사용할 수 없다고 생각했지만 여전히 Import-Module을 시도하고있었습니다. GET-모듈 그것의 벌금
Craig.C

2
모듈 LOADED (그 자체로 유용합니다 -systemcentercentral.com/… )는 확인하지만 다른 답변은 모듈이 있는지 확인하지 않습니다.
Michael Freidgeim

1
이것은 ListAvailable을 사용하는 것보다 훨씬 빠르게 실행됩니다.
GaTechThomas

!버전에 따라 powershell에서 작동하지 않는 것이 확실 합니까?
Kolob Canyon

2
@KolobCanyon은의 !별칭 -not이지만 일반적으로 ps1 스크립트에서 별칭을 사용하지 않는 것이 좋습니다. @GaTechThomas는 또한 @MichaelFreidgeim에서 지정한대로 다른 동작을 가지고 있습니다 (설치된 모듈에 대해 정확한 값을 반환하지는 않지만 가져온 모듈에 대해서는 반환하지 않음).
AndreasHassing

27

모듈의 상태는 다음과 같습니다.

  • 수입
  • 디스크 (또는 로컬 네트워크)에서 사용 가능
  • 온라인 갤러리에서 사용 가능

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
이 "올인원"솔루션 중대하다 (I는 부하 모듈 변경했습니다 $ true를 반환 / 대신 EXIT의 $ false)를
의 Andrzej 마르티나

17

현재 버전의 Powershell에는 이 목적에 잘 맞는 Get-InstalledModule기능 이 있습니다 (또는 적어도 제 경우에는 그랬습니다).

Get-InstalledModule

기술

Get-InstalledModulecmdlet은 컴퓨터에 설치되어 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;

좋습니다. 두 주로 돌아갑니다.

모듈을 사용할 수 있습니까 (원래 질문에서 설치됨을 의미하는 사용 가능)?

Get-Module -Listavailable -Name <modulename>

이는 모듈을 가져올 수 있는지 여부를 알려줍니다.

모듈을 가져 왔습니까? (원래 질문에서 '존재한다'라는 단어에 대한 답으로 이것을 사용하고 있습니다.)

Get-module -Name <modulename>

이는 모듈을 가져 오지 않은 경우 아무것도없는 빈로드를 반환하고있는 경우 모듈에 대한 한 줄 설명을 반환합니다. Stack Overflow에서와 마찬가지로 자신의 모듈에서 위의 명령을 시도하십시오.


1
PowerShell에서 모듈을 설치할 수 있습니다. PowerShellGet에는 Get-InstalledModule다음과 같은 출력을 반환하지 않는 명령 이 있습니다Get-Module -ListAvailable
Igor

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

IMHO, 모듈이 다음과 같은지 확인하는 데 차이가 있습니다.

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

귀하의 cmdlet은 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

당신은 정말 철저하기를 원한다면 당신은 다른 제안하는 cmdlet에 추가해야합니다 Get-Module -ListAvailable -NameGet-Module -Name기타 기능 / cmdlet을 실행하기 전에 신중 추가 될 수 있습니다. psgallery 또는 다른 곳에서 설치된 경우 Find-Modulecmdlet을 실행하여 사용 가능한 새 버전이 있는지 확인할 수도 있습니다.


2

당신은 사용할 수 있습니다 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.