Làm cách nào để kiểm tra xem mô-đun PowerShell đã được cài đặt chưa?


92

Để kiểm tra xem mô-đun có tồn tại hay không, tôi đã thử như sau:

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

Đầu ra là:

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

Tôi nhận được một lỗi, nhưng không có ngoại lệ nào được ném ra, vì vậy chúng tôi thấy Module existscuối cùng, mặc dù SomeModulekhông tồn tại.

Có cách nào tốt (tốt nhất là không tạo ra lỗi) để phát hiện xem mô-đun PowerShell đã được cài đặt trên hệ thống không?


Câu trả lời:


120

Bạn có thể sử dụng ListAvailabletùy chọn của Get-Module:

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

1
Tôi đã định sử dụng suggets: Import-Module NonexistingModule -ErrorAction SilentlyContinue IF ($ error) {Write-Host 'Mô-đun không tồn tại'} ELSE {Write-Host 'Mô-đun không tồn tại'} Nhưng cách của bạn tốt hơn, thanh lịch hơn :)
Erik Blomgren

Điều này hoạt động tuyệt vời. Cảm ơn. Tôi sẽ sử dụng Write-Warning "Module does not exist..." ;BreakNhưng bạn đã làm tất cả công việc khó khăn.
Craig.C

Nếu bạn đang nhập thư viện bằng cách sử dụng Import-Modulevà tệp dll tùy chỉnh, không sử dụng -ListAvailabletùy chọn để xác định xem mô-đun đã được cài đặt hay chưa vì nó sẽ không được liệt kê. Theo tài liệu PowerShell 6 , "ListAvailable không trả về thông tin về các mô-đun không được tìm thấy trong biến môi trường PSModulePath, ngay cả khi các mô-đun đó được tải trong phiên hiện tại".
Dave F

Điều này không xác định xem một mô-đun đã được cài đặt hay chưa (tức là Import-Module) nó chỉ xác định xem mô-đun có sẵn sàng ngay lập tức để được cài đặt hay không mà không chỉ định một vị trí cụ thể chưa có$env:PSModulePath
Slogmeister Extraordinaire

34

Tùy chọn ListAvailable không hoạt động với tôi. Thay vào đó, điều này thực hiện:

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

Hoặc, ngắn gọn hơn:

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

@ oɔɯǝɹ Tôi nghĩ đơn giản là -ListAvailable không có sẵn nhưng tôi vẫn đang thử Import-Module. Với Get-đun của nó tốt
Craig.C

2
Bạn kiểm tra xem mô-đun đã LOADED (tự nó hữu ích - systemcentercentral.com/… ), chứ không phải câu trả lời khác kiểm tra xem mô-đun có tồn tại hay không.
Michael Freidgeim

1
Điều này thực thi nhanh hơn nhiều so với sử dụng ListAvailable.
GaTechThomas

Khá chắc chắn !không hoạt động trong powershell tùy thuộc vào phiên bản?
Kolob Canyon

2
@KolobCanyon !là một bí danh cho -not, nhưng tôi không khuyên bạn nên sử dụng bí danh trong tập lệnh ps1 nói chung. @GaTechThomas nó cũng có một hành vi khác, như được chỉ định bởi @MichaelFreidgeim (nó không trả về giá trị trung thực cho các mô-đun đã cài đặt, nhưng không được nhập).
AndreasHassing

27

Một mô-đun có thể ở các trạng thái sau:

  • nhập khẩu
  • có sẵn trên đĩa (hoặc mạng cục bộ)
  • có sẵn trong thư viện trực tuyến

Nếu bạn chỉ muốn có một thứ dễ sử dụng trong phiên PowerShell để sử dụng, thì đây là một hàm sẽ thực hiện điều đó hoặc thoát ra nếu không thể hoàn thành nó:

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
này là rất tốt "all-in-one" giải pháp (tôi đã chỉ thay đổi Load-đun để trở $ true / $ false thay vì EXIT)
Andrzej Martyna

17

Phiên bản hiện tại của Powershell có một Get-InstalledModulechức năng rất phù hợp với mục đích này (hoặc ít nhất nó đã làm được trong trường hợp của tôi).

Get-InstalledModule

Sự miêu tả

Các Get-InstalledModulelệnh được module PowerShell được cài đặt trên máy tính.

Vấn đề duy nhất với nó là nó ném ra một ngoại lệ nếu mô-đun đang được yêu cầu không tồn tại, vì vậy chúng tôi cần thiết lập ErrorActionthích hợp để ngăn chặn trường hợp đó.

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

    # Install it...
}

13

Chỉ cần xem lại điều này vì đó là điều tôi vừa phải đối mặt và có một số điều không chính xác trong các câu trả lời (mặc dù nó được đề cập trong các bình luận).

Điều đầu tiên mặc dù. Các câu hỏi ban đầu hỏi làm thế nào để biết một mô-đun PowerShell đã được cài đặt hay chưa. Chúng ta cần nói về từ cài đặt! Bạn không cài đặt mô-đun PowerShell (không phải theo cách truyền thống mà bạn cài đặt phần mềm).

Mô-đun PowerShell hoặc có sẵn (tức là chúng nằm trên đường dẫn mô-đun PowerShell) hoặc chúng được nhập (chúng được nhập vào phiên của bạn và bạn có thể gọi các hàm có trong đó). Đây là cách kiểm tra đường dẫn mô-đun của bạn, trong trường hợp bạn muốn biết nơi lưu trữ mô-đun:

$env:psmodulepath

Tôi cho rằng việc sử dụng C: \ Program Files \ WindowsPowerShell \ Modules trở nên phổ biến ; thường xuyên hơn do nó có sẵn cho tất cả người dùng, nhưng nếu bạn muốn khóa các mô-đun của mình trong phiên của riêng bạn, hãy đưa chúng vào hồ sơ của bạn. C: \ Users \% username% \ Documents \ WindowsPowerShell \ Modules;

Được rồi, quay lại hai trạng thái.

Mô-đun có sẵn không (sử dụng sẵn có nghĩa là được cài đặt trong câu hỏi ban đầu)?

Get-Module -Listavailable -Name <modulename>

Điều này cho bạn biết nếu một mô-đun có sẵn để nhập.

Mô-đun có được nhập không? (Tôi đang sử dụng điều này làm câu trả lời cho từ 'tồn tại' trong câu hỏi ban đầu).

Get-module -Name <modulename>

Điều này sẽ trả về một tải rỗng không có gì nếu mô-đun không được nhập hoặc mô tả một dòng của mô-đun nếu có. Như mọi khi trên Stack Overflow, hãy thử các lệnh trên trên các mô-đun của riêng bạn.


1
Bạn có thể cài đặt mô-đun trong PowerShell. PowerShellGet có lệnh Get-InstalledModulekhông trả lại đầu ra giống nhưGet-Module -ListAvailable
Igor

9

Khi tôi sử dụng mô-đun không phải mặc định trong tập lệnh của mình, tôi gọi hàm bên dưới. Bên cạnh tên mô-đun, bạn có thể cung cấp phiên bản tối thiểu.

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

ví dụ sử dụng:

Install-ModuleIfNotInstalled 'CosmosDB' '2.1.3.528'

Vui lòng cho tôi biết nếu nó hữu ích (hoặc không)


4

Bạn có thể sử dụng #Requirescâu lệnh (hỗ trợ các mô-đun từ PowerShell 3.0).

Câu lệnh #Requires ngăn không cho tập lệnh chạy trừ khi đáp ứng các điều kiện tiên quyết về phiên bản PowerShell, mô-đun, snap-in và mô-đun và phiên bản snap-in.

Vì vậy, ở đầu tập lệnh, chỉ cần thêm #Requires -Module <ModuleName>

Nếu các mô-đun bắt buộc không có trong phiên hiện tại, PowerShell sẽ nhập chúng.

Nếu không thể nhập các mô-đun, PowerShell sẽ đưa ra lỗi kết thúc.


3

IMHO, có sự khác biệt giữa việc kiểm tra xem một mô-đun có:

1) đã cài đặt hoặc 2) đã nhập:

Để kiểm tra xem đã cài đặt chưa:

Tùy chọn 1: Sử dụng Get-Modulevới -ListAvailabletham số:

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

Tùy chọn 2: Sử dụng $errorđối tượng:

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

Để kiểm tra xem đã nhập chưa:

Sử dụng Get-Modulevới -Nametham số (bạn có thể bỏ qua vì nó vẫn là mặc định ):

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

Cần phải chỉ ra rằng lệnh ghép ngắn của bạn Import-Modulekhông có lỗi kết thúc, do đó ngoại lệ sẽ không bị bắt, vì vậy bất kể câu lệnh bắt của bạn là gì sẽ không bao giờ trả lại câu lệnh mới mà bạn đã viết.

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

Từ trên:

"Lỗi kết thúc ngừng chạy một câu lệnh. Nếu PowerShell không xử lý lỗi kết thúc theo một cách nào đó, PowerShell cũng ngừng chạy chức năng hoặc tập lệnh bằng cách sử dụng đường dẫn hiện tại. Trong các ngôn ngữ khác, chẳng hạn như C #, lỗi kết thúc được gọi là ngoại lệ . Để biết thêm thông tin về lỗi, hãy xem about_Errors. "

Nó phải được viết là:

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

Trả về:

nope

Và nếu bạn thực sự muốn kỹ lưỡng, bạn nên thêm các lệnh ghép ngắn được đề xuất khác Get-Module -ListAvailable -NameGet-Module -Namethận trọng hơn trước khi chạy các hàm / lệnh ghép ngắn khác. Và nếu nó được cài đặt từ psgallery hoặc nơi khác, bạn cũng có thể chạy Find-Modulelệnh ghép ngắn để xem có phiên bản mới hay không.


2

Bạn có thể dùng Get-InstalledModule

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

Nhiều câu trả lời hay ở đây, nhưng với phương pháp đơn giản mới này, đây có lẽ phải là câu trả lời mới được chấp nhận.
not2qubit

1
  • Kiểm tra đầu tiên nếu mô-đun được tải
  • Sau đó nhập

``

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

Đến từ nền tảng Linux. Tôi muốn sử dụng thứ gì đó tương tự như grep, do đó tôi sử dụng Select-String. Vì vậy, ngay cả khi ai đó không chắc chắn về tên mô-đun hoàn chỉnh. Họ có thể cung cấp các chữ cái đầu và xác định xem mô-đun có tồn tại hay không.

Get-Module -ListAvailable -All | Select-String Module_Name(có thể là một phần của tên mô-đun)


1

Đây là mã để kiểm tra xem mô-đun AZ đã được cài đặt hay chưa:

$checkModule = "AZ"

$Installedmodules = Get-InstalledModule

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

    "$checkModule is installed "

}

else {

    "$checkModule is not installed"

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.