如何在powershell中列出所有已安装、可运行的cmdlet?

Mar*_*arc 6 powershell

我想在 powershell 中列出所有已安装的、可运行的 cmdlet 和函数,但Get-Command正在列出以某种方式“存在”但未加载且不可运行的 cmdlet。

例如,Get-Command列出New-IseSnippet

PS W:\> get-command "*-*" -CommandType Function,Cmdlet | where name -like "New-IseSnippet" | select name,module,path

Name           Module path
----           ------ ----
New-IseSnippet ISE
Run Code Online (Sandbox Code Playgroud)

所以看起来我们有一个New-IseSnippet命令 - 让我们检查它:

PS W:\> get-command New-IseSnippet
get-command : The term 'New-IseSnippet' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that 
the path is correct and try again.
At line:1 char:1
+ get-command New-IseSnippet
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (New-IseSnippet:String) [Get-Command], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand
Run Code Online (Sandbox Code Playgroud)

不,我们可以运行它吗?:

PS W:\> New-IseSnippet
New-IseSnippet : The 'New-IseSnippet' command was found in the module 'ISE', but the module could not be loaded. For more information, run 'Import-Module ISE'.
At line:1 char:1
+ New-IseSnippet
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (New-IseSnippet:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CouldNotAutoloadMatchingModule

Run Code Online (Sandbox Code Playgroud)

不。

我们如何只获得已安装的、可运行的命令?

pos*_*ote 7

至于这个根查询......

我想在 powershell 中列出所有已安装、可运行的 cmdlet 和函数

...在我的个人图书馆中,这是我很久以前创建/组合的片段的一部分,并根据需要进行更新,正是这种用例。我的代码段中还有更多内容,但是根据您的帖子,这应该可以帮助您找到所需的内容。这是我在 ISE / VSCode 中的代码片段库,我可以根据需要随时使用CTRL+J并在 ISE 中选择它,然后在 VSCode 中输入 Help 并选择它。

# Get parameters, examples, full and Online help for a cmdlet or function

# Get a list of all Modules
Get-Module -ListAvailable | 
Out-GridView -PassThru -Title 'Available modules'

# Get a list of all functions
Get-Command -CommandType Function | 
Out-GridView -PassThru -Title 'Available functions'

# Get a list of all commandlets
Get-Command -CommandType Cmdlet | 
Out-GridView -PassThru -Title 'Available cmdlets'

# Get a list of all functions for the specified name
Get-Command -Name '*ADGroup*' -CommandType Function | 
Out-GridView -PassThru -Title 'Available named functions'

# Get a list of all commandlets for the specified name
Get-Command -Name '*ADGroup**'  -CommandType Cmdlet | 
Out-GridView -PassThru -Title 'Available named cmdlet'

# get function / cmdlet details
Get-Command -Name Get-ADUser -Syntax
(Get-Command -Name Get-ADUser).Parameters.Keys
Get-help -Name Get-ADUser -Full
Get-help -Name Get-ADUser -Online
Get-help -Name Get-ADUser -Examples

# Get parameter that accepts pipeline input
Get-Help Get-ADUser -Parameter * | 
Where-Object {$_.pipelineInput -match 'true'} | 
Select * 

# List of all parameters that a given cmdlet supports along with a short description:
Get-Help dir -para * | 
Format-Table Name, { $_.Description[0].Text } -wrap


# Find all cmdlets / functions with a target parameter
Get-Command -CommandType Function | 
Where-Object { $_.parameters.keys -match 'credential'} | 
Out-GridView -PassThru -Title 'Available functions which has a specific parameter'

Get-Command -CommandType Cmdlet | 
Where-Object { $_.parameters.keys -match 'credential'} | 
Out-GridView -PassThru -Title 'Results for cmdlets which has a specific parameter'

# Get named aliases 
Get-Alias | 
Out-GridView -PassThru -Title 'Available aliases'

# Get cmdlet / function parameter aliases
(Get-Command Get-ADUser).Parameters.Values | 
where aliases | 
select Name, Aliases | 
Out-GridView -PassThru -Title 'Alias results for a given cmdlet or function.'

### Query Powershell Data Types
[AppDomain]::CurrentDomain.GetAssemblies() | 
Foreach-Object { $_.GetExportedTypes() }

# Or 

[psobject].Assembly.GetType(“System.Management.Automation.TypeAccelerators”)::get

# Or

[psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Get.GetEnumerator() `
| Sort-Object -Property Key

<#
 Get any .NET types and their static methods from PowerShell. 
 Enumerate all that are currently loaded into your AppDomain.
#>  
[AppDomain]::CurrentDomain.GetAssemblies() | 
foreach { $_.GetTypes() } | 
foreach { $_.GetMethods() } | 
where { $_.IsStatic } | 
select DeclaringType, Name | 
Out-GridView -PassThru -Title '.NET types and their static methods'
Run Code Online (Sandbox Code Playgroud)

如前所述,有些东西(不一定总是模块/cmdlet)仅是 ISE(当然,这是 ISE 模块中的任何东西或类似的东西),这取决于您在做什么/正在做什么,例如很多形式的东西,但只要当您向代码中添加适当的表单类/类型时,它们也应该在控制台主机中正常运行。

然而,认为标记为 ISE 的任何东西都不会在其他任何地方运行的想法是不正确的。还有很多 ISE 插件。您可以通过 ISE 附加组件菜单访问它们。在控制台主机中永远不应该期望该菜单中的任何内容。例如,这是一个内置工具,可以直接在 ISE 编辑器选项卡中打开基于文本的文件,psEdit。

Get-Help -Name psedit

NAME
    psEdit
    
SYNTAX
    psEdit [-filenames] <Object>  [<CommonParameters>]
    

ALIASES
    None
    

REMARKS
    None
Run Code Online (Sandbox Code Playgroud)

尝试在控制台主机中使用它会失败,因为控制台主机没有这样的编辑器。

您也可以在 ISE 中以编程方式做事,当然这种事情在控制台主机中永远不会起作用。

在此处查看详细信息: ISE 对象模型层次结构

为确保东西在您需要时就在应有的位置,请调整您的 PowerShell 配置文件。例如,这里是我在 ISE 与控制台主机中时要处理的内容的示例。

# Validate if in the ISE or not

If ($Host.Name -match 'ISE')
{
    Import-Module -Name PsISEProjectExplorer
    Import-Module -Name PSharp
    Import-Module -Name ClassExplorer

}

If ($Host.Name -notmatch 'ISE')
{ Import-Module -Name PSReadline }

Import-Module -Name PSScriptAnalyzer
Import-Module -Name Posh-SSH
Import-Module -Name ModuleLibrary -DisableNameChecking
Import-Module -Name Pester
Import-Module -Name PSKoans


If ($Host.Name -match 'ISE')
{
    #Script Browser Begin
    #Version: 1.3.2
    Add-Type -Path 'C:\Program Files (x86)\Microsoft Corporation\Microsoft Script Browser\System.Windows.Interactivity.dll'
    Add-Type -Path 'C:\Program Files (x86)\Microsoft Corporation\Microsoft Script Browser\ScriptBrowser.dll'
    Add-Type -Path 'C:\Program Files (x86)\Microsoft Corporation\Microsoft Script Browser\BestPractices.dll'
    $scriptBrowser = $psISE.CurrentPowerShellTab.VerticalAddOnTools.Add('Script Browser', [ScriptExplorer.Views.MainView], $true)
    $scriptAnalyzer = $psISE.CurrentPowerShellTab.VerticalAddOnTools.Add('Script Analyzer', [BestPractices.Views.BestPracticesView], $true)
    $psISE.CurrentPowerShellTab.VisibleVerticalAddOnTools.SelectedAddOnTool = $scriptBrowser
    #Script Browser End

    Set-StrictMode  -Version Latest 
}
Run Code Online (Sandbox Code Playgroud)

OP 更新

至于……

那么,有没有办法查询在 powershell.exe(或 pwsh.exe)控制台中实际加载和运行的命令?

不是我认为你在想的那种意义上。您似乎对启动时加载了哪些 cmdlet 有所了解。那不是一回事。cmdlet 通过模块加载和路径公开。您期望 PowerShell 仅根据您所在的 PowerShell 版本/环境显示模块/cmdlet/函数。这也不是问题。PowerShell 将可以访问系统上的所有 .Net 以及定义路径中的任何内容。无论您是否加载和使用它们,都是另一回事。

Get-Module                # will show you all currently loaded ones.
Get-Module -ListAvailable # Will show all modules installed on your system.
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 PSv3 及更高版本,那么您的系统环境和 PowerShell 路径始终可用,因为您在路径中调用的任何内容都会在您尝试使用时自动加载。

再次 Get-Command 将列出所有可用的,它们仅在您调用一个时加载,并在调用或会话完成/关闭时消失。

如果您的模块、cmdlet/函数不在预期(环境或 PS 路径)位置,则您必须添加该路径或使用它们的 UNC 路径来运行它们。因此,路径中的任何内容(来自任何 UNC 的点源)始终可用。如果您在 ISE 中,则可以在“命令”选项卡中或使用 Get-Command 在控制台中看到此信息。

您可以即时或使用 PowerShell 配置文件临时添加路径,也可以通过 PowerShell 配置文件或使用 Windows 环境变量对话框永久添加路径。

控制台主机和 ISE 将始终列出预期路径中的任何模块、cmdlet 和函数。它们并不意味着都可用。如前所述,由于显而易见的原因,ISe 特定模块、cmdlet、函数只能在 ISE 中工作。但是,ISE 将运行控制台主机将运行的任何模块 cmdlet ,除了 PSReadline。它会加载它,但它不会在 ISE 控制台中执行任何操作。ISE 控制台实际上是一个输出窗口,与控制台主机不同。好吧,你可以做 consolehost 之类的东西,但这不是一回事。

因此,模块被加载,模块公开其中的 cmdlet/函数。并非所有模块都默认加载,因此上面两个命令的原因,这就是导入模块和调用时自动加载的原因。独立的个人模块/cmdlet/函数/脚本不是 PS 会知道的,除非你告诉它应该从哪里导入/加载/使用它们。

如果您真的对这类事情感到好奇,可以利用 Trace-Command cmdlet ...

跟踪命令

$A = "i*"
Trace-Command ParameterBinding {Get-Alias $Input} -PSHost -InputObject $A

DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Get-Alias]
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Get-Alias]
DEBUG: ParameterBinding Information: 0 :     BIND arg [System.Object[]] to parameter [Name]
DEBUG: ParameterBinding Information: 0 :         Binding collection parameter Name: argument type [Object[]], parameter type [System.String[]], collection type 
Array, element type [System.String], no coerceElementType
DEBUG: ParameterBinding Information: 0 :         Arg is IList with 1 elements
DEBUG: ParameterBinding Information: 0 :         Creating array with element type [System.String] and 1 elements
DEBUG: ParameterBinding Information: 0 :         Argument type System.Object[] is IList
DEBUG: ParameterBinding Information: 0 :         Adding element of type String to array position 0
DEBUG: ParameterBinding Information: 0 :         BIND arg [System.String[]] to param [Name] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Get-Alias]
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing
Run Code Online (Sandbox Code Playgroud)

...使用您的代码查看实际调用的内容,您将看到每次运行代码时都会调用它。

您安装的模块越多,摩尔纹 cmdlet / 功能就可用。如果你真的想一想,他们有数百个模块,因此有数千个暴露的 cmdlet/函数。为什么要在内存中加载所有内容。您的系统只会由于资源耗尽而失败。所以,只加载你真正需要的东西,PowerShell 只会在需要的时候调用它。如果您打算使用控制台主机或使用 ISE / VSCode 并仅在需要时使用控制台主机,请了解 ISE 特定的内容并忽略所有这些内容。这就是我做事的方式。我很少,如果需要去控制台主机做任何事情。ISE 是我的默认设置,VSCode 是我的次要(目前)。有些人对 ISE 大便,我不是其中之一。

OP 更新

至于...

我的用例不是坐在 PC 上的用户,而是运行 powershell.exe (PS5) 或 pwsh.exe (PS6/Core) 主机的 NodeJS 应用程序。我完全明白模块可能“可用”但未加载,这就是我想要查询的:加载了哪些 cmdlet/函数(即现在可以在不加载模块的情况下运行)。我觉得 Get-Command * 会列出 Cmdlet X 但 Get-Command X 会失败,这很奇怪/有问题。我如何查询命令:你是否加载了可运行的?PS:谷歌“powowshell”查看我的项目。

将链接放到您的项目而不是让我搜索它会有所帮助。 8-}并且它只显示在 Google 中而不是其他引擎(如 DuckDuckGo 或 Bing)中的事实有点奇怪,但是很好。

所以,你的意思是这个系列——

http://cawoodm.blogspot.com https://github.com/cawoodm/powowshell

我会看一看。但是,对于您所追求的,不要单独使用 Get-Command。将 Get-Module 与 Get-Command 结合使用以列出那些加载的模块中的 cmdlet/函数,以更接近您所追求的目标。通过这样做,只列出加载的模块和该会话的关联 cmdlet/函数。

# List all loaded session modules and the exposed cmdlets / functions in them
Get-Module -Name '*' | 
ForEach-Object { Get-Command -Module $PSItem }

# Results

 # List all loaded modules and the exposed cmdlets / functions in them
Get-Module -Name '*' | 
ForEach-Object { Get-Command -Module $PSItem }

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
... 
Cmdlet          Export-BinaryMiLog                                 1.0.0.0    CimCmdlets
Cmdlet          Get-CimAssociatedInstance                          1.0.0.0    CimCmdlets
Cmdlet          Get-CimClass                                       1.0.0.0    CimCmdlets
...
Cmdlet          Find-Member                                        1.1.0      ClassExplorer
Cmdlet          Find-Namespace                                     1.1.0      ClassExplorer
Cmdlet          Find-Type                                          1.1.0      ClassExplorer
...
Function        Get-IseSnippet                                     1.0.0.0    ISE
Function        Import-IseSnippet                                  1.0.0.0    ISE
Function        New-IseSnippet                                     1.0.0.0    ISE
Cmdlet          Add-Computer                                       3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Add-Content                                        3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Checkpoint-Computer                                3.1.0.0    Microsoft.PowerShell.Management                                   
...
Run Code Online (Sandbox Code Playgroud)

OP 更新

至于...

您的解决方案将无法列出没有模块关联(在我的系统上为 64)的 cmdlet/函数(例如 ForEach-Object 或 Stop-Job)。另外,您如何确定 Get-Module 仅返回已加载的模块?

PowerShell 从 PowerShell 源和模块获取 cmdlet 和函数。

如果你对你指向的cmdlet /功能查找,你会看到他们来自何处这里

'ForEach-Object','Start-Job' | 
    ForEach{
                Get-Command -CommandType Cmdlet -Name $PSItem | 
                Format-Table -AutoSize
           }

<#
CommandType Name           Version Source                   
----------- ----           ------- ------                   
Cmdlet      ForEach-Object 3.0.0.0 Microsoft.PowerShell.Core



CommandType Name      Version Source                   
----------- ----      ------- ------                   
Cmdlet      Start-Job 3.0.0.0 Microsoft.PowerShell.Core
#>
Run Code Online (Sandbox Code Playgroud)

因此,基本 cmdlet / 函数不是来自导入模块的工作。在 OS/.Net 安装中有设计。

所以,我的解决方案并不是失败的,我从来没有说过使用它会让你 100%。这是一种向您展示哪些模块加载以使用哪些 cmdlet/函数的方式,并且与 Microsoft.PowerShell.Core、.Net 和/或操作系统版本允许的内容几乎没有任何关系(Cmdlets/Functions/Modules 是众所周知,操作系统和 $PSVersion 也是特定的)。

因此,同样,您尝试设计的用例无效。无论来源如何,Cmdlet 和函数都不会加载并可供使用。当您需要通过上述方式调用它们时,它们已安装或公开并可供使用。在您调用它们之前,它们永远不会被加载(位于内存中),GAC 中的任何东西都不会加载。

所以,看着你的项目,我明白你在做什么,但你在为用户着想。正如您作为开发人员必须从 GAC 中引用一个程序集(其中有成千上万的东西,但在您引用它们之前不会加载),您必须知道它在哪里以及您想使用哪个,以及为什么。因此,对于 PowerShell 可以访问的内容,采用相同的思维方式。请注意,我说的是访问权限,而不是您是否可以在 PowerShell 会话中使用它。

所以,如果我们踏入这一步,我们会得到...

Cmdlets / Function come from. The OS (DLLs), [.Net][4], [Core module][3], and those exported from the modules you Import.
Run Code Online (Sandbox Code Playgroud)

因此,再次,您认为必须是,在导入模块或 DLL 时什么是可用的或可用的。导入的模块及其关联的 cmdlet/函数可能无法工作,具体取决于您所在的会话类型。意思是 ISE 与 consolhost。

仅供参考,你必须扩大你对这个的看法......

在 ISE

# Total host available commands cmdlet / Functions regadless where the come from
(Get-Command).Count
8750
# Total host avaialble cmdlets
(Get-Command -CommandType Cmdlet).Count
4772
# Total host available functions
(Get-Command -CommandType Function).Count
3035

# Difference of host available cmdlets / functions not shown that are part of the previous two calls.
(Get-Command).Count - ((Get-Command -CommandType Cmdlet).Count + (Get-Command -CommandType Function).Count)
943

# Further breakdown
(Get-Command -CommandType Alias).Count
1446
(Get-Command -CommandType Application).Count
937
(Get-Command -CommandType Configuration).Count
# The property 'Count' cannot be found on this object. Verify that the property exists.
(Get-Command -CommandType ExternalScript).Count
2
(Get-Command -CommandType Script).Count
# The property 'Count' cannot be found on this object. Verify that the property exists.
(Get-Command -CommandType Filter).Count
2
(Get-Command -CommandType Workflow).Count
# The property 'Count' cannot be found on this object. Verify that the property exists.
(Get-Command -CommandType All).Count
10219


# Get a list of all Modules
(Get-Module -ListAvailable).Count
387

# Get a list of all loaded Modules
(Get-Module).Count
12

# List all loaded session modules and the exposed cmdlets / functions in them
(Get-Module -Name '*' | 
ForEach-Object { Get-Command -Module $PSItem }).Count
505

(Get-Module -ListAvailable | 
ForEach {
    Get-Module -Name $PSItem.Name | 
    ForEach-Object { Get-Command -Module $PSItem }
}).Count
669



# If I Import another 3rdP module I installed from the gallery, things will change of course

Import-Module -Name ShowUI

# Get a list of all Modules
(Get-Module -ListAvailable).Count
387

# Get a list of all loaded Modules
(Get-Module).Count
13

# List all loaded session modules and the exposed cmdlets / functions in them
(Get-Module -Name '*' | 
ForEach-Object { Get-Command -Module $PSItem }).Count
937

(Get-Module -ListAvailable | 
ForEach {
    Get-Module -Name $PSItem.Name | 
    ForEach-Object { Get-Command -Module $PSItem }
}).Count
1101
Run Code Online (Sandbox Code Playgroud)

在控制台主机中 - 注意差异

# Total host available commands cmdlet / Functions regadless where the come from
(Get-Command).Count
9191

# Total host avaialble cmdlets
(Get-Command -CommandType Cmdlet).Count
4772

# Total host available functions
(Get-Command -CommandType Function).Count
3472

# Difference of host available cmdlets / functions not shown that are part of the previous two calls.
(Get-Command).Count - ((Get-Command -CommandType Cmdlet).Count + (Get-Command -CommandType Function).Count)
947


# Further breakdown
(Get-Command -CommandType Alias).Count
1809

(Get-Command -CommandType Application).Count
937

(Get-Command -CommandType Configuration).Count
0
# The property 'Count' cannot be found on this object. Verify that the property exists.
(Get-Command -CommandType ExternalScript).Count
2

(Get-Command -CommandType Script).Count
0
# The property 'Count' cannot be found on this object. Verify that the property exists.
(Get-Command -CommandType Filter).Count
1

(Get-Command -CommandType Workflow).Count
1
# The property 'Count' cannot be found on this object. Verify that the property exists.
(Get-Command -CommandType All).Count
10994




# Get a list of all Modules
(Get-Module -ListAvailable).Count
387

# Get a list of all loaded Modules
(Get-Module).Count
8

# List all loaded session modules and the exposed cmdlets / functions in them
(Get-Module -Name '*' | 
ForEach-Object { Get-Command -Module $PSItem }).Count
467

(Get-Module -ListAvailable | 
ForEach {
    Get-Module -Name $PSItem.Name | 
    ForEach-Object { Get-Command -Module $PSItem }
}).Count
623



# If I Import another 3rdP module I installed from the gallery, things will change of course

Import-Module -Name ShowUI

# Get a list of all Modules
(Get-Module -ListAvailable).Count
387


# Get a list of all loaded Modules
(Get-Module).Count
9


# List all loaded session modules and the exposed cmdlets / functions in them
(Get-Module -Name '*' |
ForEach-Object { Get-Command -Module $PSItem }).Count
899


(Get-Module -ListAvailable |
ForEach {
    Get-Module -Name $PSItem.Name |
    ForEach-Object { Get-Command -Module $PSItem }
}).Count
1055
Run Code Online (Sandbox Code Playgroud)

  • 请参阅我的更新。它很长,所以,请不要采用 TL'DR 方法。;-} (2认同)