要检查模块是否存在,我尝试了以下方法:
try {
Import-Module SomeModule
Write-Host "Module exists"
}
catch {
Write-Host "Module does not exist"
}
Run Code Online (Sandbox Code Playgroud)
输出是:
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
Run Code Online (Sandbox Code Playgroud)
我确实得到了一个错误,但没有抛出任何异常,所以我们Module exists最终看到,虽然SomeModule不存在.
是否有一种好方法(最好不会产生错误)来检测系统上是否安装了PowerShell模块?
Kle*_*ler 96
您可以使用以下ListAvailable选项Get-Module:
if (Get-Module -ListAvailable -Name SomeModule) {
Write-Host "Module exists"
}
else {
Write-Host "Module does not exist"
}
Run Code Online (Sandbox Code Playgroud)
kar*_*zza 25
ListAvailable选项对我不起作用.相反,这样做:
if (-not (Get-Module -Name "<moduleNameHere>")) {
# module is not loaded
}
Run Code Online (Sandbox Code Playgroud)
或者,更简洁:
if (!(Get-Module "<moduleNameHere>")) {
# module is not loaded
}
Run Code Online (Sandbox Code Playgroud)
Rod*_*Rod 13
模块可以处于以下状态:
如果您只是想在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
Run Code Online (Sandbox Code Playgroud)
TJ *_*ama 13
当我在脚本中使用非默认模块时,我调用下面的函数。除了模块名称,您还可以提供最低版本。
# 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 -lt $_.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
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
Install-ModuleIfNotInstalled 'CosmosDB' '2.1.3.528'
Run Code Online (Sandbox Code Playgroud)
请让我知道它是否有用(或没有)
mel*_*ous 12
您可以使用 Get-InstalledModule
If (-not(Get-InstalledModule SomeModule -ErrorAction silentlycontinue)) {
Write-Host "Module does not exist"
}
Else {
Write-Host "Module exists"
}
Run Code Online (Sandbox Code Playgroud)
Nig*_*888 11
当前版本的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...
}
Run Code Online (Sandbox Code Playgroud)
byt*_*kie 10
只是重新审视这个,因为它是我刚刚遇到的东西,答案中有一些不正确的东西(尽管在评论中提到过).
但第一件事.原始问题询问如何判断是否安装了PowerShell模块.我们需要谈谈安装这个词!您不安装PowerShell模块(不是以传统的方式安装软件).
PowerShell模块可用(即它们位于PowerShell模块路径上),或者它们已导入(它们将导入到您的会话中,您可以调用包含的函数).这是检查模块路径的方法,以防您想知道模块的存储位置:
$env:psmodulepath
Run Code Online (Sandbox Code Playgroud)
我认为使用C:\ Program Files\WindowsPowerShell\Modules正变得越来越普遍; 更常见的原因是它可供所有用户使用,但如果您想将模块锁定到自己的会话中,请将它们包含在您的个人资料中.C:\ Users \用户%的用户名%\文件\ WindowsPowerShell \模块;
好吧,回到两个州.
该模块是否可用(使用可用于表示安装在原始问题中)?
Get-Module -Listavailable -Name <modulename>
Run Code Online (Sandbox Code Playgroud)
这会告诉您模块是否可用于导入.
模块是否已导入?(我用它作为原始问题中"存在"一词的答案).
Get-module -Name <modulename>
Run Code Online (Sandbox Code Playgroud)
如果未导入模块,这将返回空载空载,如果是,则返回模块的单行描述.与Stack Overflow一样,请在您自己的模块上尝试上述命令.
小智 7
try {
Import-Module SomeModule
Write-Host "Module exists"
}
catch {
Write-Host "Module does not exist"
}
Run Code Online (Sandbox Code Playgroud)
应该指出的是,您的 cmdletImport-Module没有终止错误,因此不会捕获异常,因此无论您的 catch 语句如何,都永远不会返回您编写的新语句。
从上面:
“终止错误会阻止语句运行。如果 PowerShell 不以某种方式处理终止错误,PowerShell 也会停止使用当前管道运行函数或脚本。在其他语言(例如 C#)中,终止错误称为异常.有关错误的更多信息,请参阅about_Errors。”
应该写成:
Try {
Import-Module SomeModule -Force -Erroraction stop
Write-Host "yep"
}
Catch {
Write-Host "nope"
}
Run Code Online (Sandbox Code Playgroud)
返回:
nope
Run Code Online (Sandbox Code Playgroud)
如果您确实想彻底了解,您应该添加其他建议的 cmdlet Get-Module -ListAvailable -Name,并Get-Module -Name在运行其他函数/cmdlet 之前格外小心。如果它是从 ps gallery 或其他地方安装的,您还可以运行 cmdletFind-Module来查看是否有可用的新版本。
您可以使用该#Requires语句(支持来自 PowerShell 3.0 的模块)。
#Requires 语句阻止脚本运行,除非满足 PowerShell 版本、模块、管理单元以及模块和管理单元版本先决条件。
所以在脚本的顶部,只需添加 #Requires -Module <ModuleName>
如果所需的模块不在当前会话中,PowerShell 会导入它们。
如果无法导入模块,PowerShell 会引发终止错误。
恕我直言,检查模块是否是有区别的:
1) 安装,或 2) 导入:
检查是否已安装:
选项 1:与参数Get-Module一起使用-ListAvailable:
If(Get-Module -ListAvailable -Name "<ModuleName>"){'Module is installed'}
Else{'Module is NOT installed'}
Run Code Online (Sandbox Code Playgroud)
选项 2:使用$error对象:
$error.clear()
Import-Module "<ModuleName>" -ErrorAction SilentlyContinue
If($error){Write-Host 'Module is NOT installed'}
Else{Write-Host 'Module is installed'}
Run Code Online (Sandbox Code Playgroud)
检查是否导入:
使用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)."
}
Run Code Online (Sandbox Code Playgroud)
因为这个问题出现在很多答案中,所以我将其作为单独的答案发布,而不是发表几条评论。请将此视为公共服务公告。
Get-InstalledModule如果您确实想知道某个模块在安装中是否可用,那么基于使用的答案是极其危险的PowerShell。仅当模块是从 PowerShellGet 安装时Get-InstalledModule才会报告该模块的存在。
来自 PowerShell 的证据:
PS C:\Users\chris> Get-InstalledModule | Select-Object -Property Name, Version
Name Version
---- -------
Choco 1.0.0
NTFSSecurity 4.2.6
PS C:\Users\chris> Get-Module | Select-Object -Property Name, Version
Name Version
---- -------
chocolateyProfile 0.0
CimCmdlets 7.0.0.0
Microsoft.PowerShell.Management 7.0.0.0
Microsoft.PowerShell.Security 7.0.0.0
Microsoft.PowerShell.Utility 7.0.0.0
Microsoft.WSMan.Management 7.0.0.0
PackageManagement 1.4.7
PowerShellGet 2.2.5
PSReadLine 2.1.0
Run Code Online (Sandbox Code Playgroud)
没有任何参数Get-InstalledModule可以用来告诉它“显示您现在没有显示的其他模块”。它无法显示任何其他内容。正如您在上面看到的,当我将九个模块导入会话时,它只显示安装了两个模块。
由于这是一个答案,我将在这里添加指导:
-ListAvailable参数实际上并未列出所有可用模块。但实际上,我们大多数人可能不太关心,因为如果ListAvailable不返回模块,那么我们就无法使用它,除非我们已经知道如何使用非标准/手动方法加载它,在这种情况下我们不太可能从一开始就寻找它。Get-Module -ListAvailable. 这是OP可以使用的一个简单示例:$module = "SomeModule"
if (Get-Module -ListAvailable | Where-Object {$_.Name -eq $module}) {
Write-Output "Module is installed."
Import-Module $module
}
else {
Write-Output "Module is not installed."
}
Run Code Online (Sandbox Code Playgroud)
但是,我并没有重复其他人在上述答案中提供的答案,我的主要观点是:请不要离开此页面,认为这Get-InstalledModule是确定模块是否已安装(可通过名称在本地导入)的可靠方法您的 PowerShell 安装)。它不是。它将为您提供由PowerShellGet安装的模块的名称,但不会为您提供任何其他本地安装的模块的名称。
| 归档时间: |
|
| 查看次数: |
86004 次 |
| 最近记录: |