Подтвердить что ты не робот

Как проверить, установлен ли модуль PowerShell?

Чтобы проверить, существует ли модуль, я попробовал следующее:

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 в системе?

4b9b3361

Ответ 1

Вы можете использовать опцию ListAvailable в Get-Module:

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

Ответ 2

Параметр ListAvailable не работает для меня. Вместо этого:

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

Или, чтобы быть более кратким:

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

Ответ 3

Просто пересматриваю это как то, с чем я только что столкнулся, и в ответах есть некоторые неправильные вещи (хотя это упоминалось в комментариях).

Хотя первым делом. В первоначальных вопросах спрашивается, как определить, установлен ли модуль PowerShell. Нам нужно поговорить об установленном слове! Вы не устанавливаете модули PowerShell (не так, как обычно, вы устанавливаете программное обеспечение).

Модули PowerShell либо доступны (т.е. Находятся по пути модуля PowerShell), либо импортируются (они импортируются в ваш сеанс, и вы можете вызывать содержащиеся в нем функции). Вот как проверить путь к модулю, если вы хотите знать, где хранить модуль:

$env:psmodulepath

Я бы сказал, что стало обычным делом использовать C:\Program Files\WindowsPowerShell\Modules; чаще всего из-за того, что он доступен для всех пользователей, но если вы хотите заблокировать свои модули для своего собственного сеанса, включите их в свой профиль. C:\Users\%имя пользователя%\Documents\WindowsPowerShell\Modules;

Хорошо, вернемся к двум штатам.

Доступен ли модуль (используя имеется в виду означает установленный в исходном вопросе)?

Get-Module -Listavailable -Name <modulename>

Это говорит вам, если модуль доступен для импорта.

Модуль импортирован? (Я использую это как ответ на слово "существует" в исходном вопросе).

Get-module -Name <modulename>

Это либо возвратит пустую загрузку ничего, если модуль не импортирован, либо однострочное описание модуля, если оно есть. Как и в случае с переполнением стека, попробуйте команды выше на ваших собственных модулях.

Ответ 4

Модуль может находиться в следующих состояниях:

  • импортный
  • доступно на диске (или в локальной сети)
  • доступно в онлайн-галерее

Если вы просто хотите, чтобы в сеансе 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

Ответ 5

Текущая версия 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...
}

Ответ 6

ИМХО, есть разница между проверкой, является ли модуль:

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

Ответ 7

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 также прекращает выполнение функции или сценария с использованием текущего конвейера. В других языках, таких как С#, завершающие ошибки называются исключениями.. Для получения дополнительной информации об ошибках см. 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, чтобы узнать, доступна ли новая версия.

Ответ 8

  • Первый тест, если модуль загружен
  • Затем импортировать

"""

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
}

"""

Ответ 9

Исходя из фона Linux. Я бы предпочел использовать что-то похожее на grep, поэтому я использую Select-String. Так что даже если кто-то не уверен в полном названии модуля. Они могут предоставить инициалы и определить, существует ли модуль или нет.

Get-Module -ListAvailable -All | Select-String Module_Name Get-Module -ListAvailable -All | Select-String Module_Name (может быть частью имени модуля)

Ответ 10

Когда я использую модули не по умолчанию в своих скриптах, я вызываю функцию ниже. Помимо имени модуля вы можете указать минимальную версию.

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

Пожалуйста, дайте мне знать, если это полезно (или нет)

Ответ 11

Вот код, чтобы проверить, установлен модуль AZ или нет:

$checkModule = "AZ"

$Installedmodules = Get-InstalledModule

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

    "$checkModule is installed "

}

else {

    "$checkModule is not installed"

}