powershell - 如何在 Powershell 中列出所有已安装、可运行的 cmdlet?
问题描述
我想在 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
所以看起来我们有一个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
不,我们可以运行它吗?:
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
没有。
我们如何只获得已安装的、可运行的命令?
解决方案
至于这个根查询......
我想在 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'
如前所述,有些东西(不一定总是模块/cmdlet)只是 ISE(当然是 ISE 模块等中的任何东西)取决于你在做什么/做什么,例如很多形式的东西,但只要当您将适当的表单类/类型添加到代码中时,它们也应该在控制台主机中运行良好。
然而,认为标记为 ISE 的任何东西都可以在其他任何地方运行是不正确的。还有很多 ISE 插件。您可以通过 ISE 附加组件菜单访问它们。该菜单中的任何内容都不应该出现在控制台主机中。例如,这是一个内置工具,可直接在 ISE 编辑器选项卡中打开基于文本的文件,psEdit。
Get-Help -Name psedit
NAME
psEdit
SYNTAX
psEdit [-filenames] <Object> [<CommonParameters>]
ALIASES
None
REMARKS
None
尝试在控制台主机中使用它会失败,因为控制台主机没有这样的编辑器。
您也可以在 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
}
OP 更新
至于……</p>
那么,有没有办法查询在 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.
如果您使用的是 PSv3 或更高版本,那么您的系统环境和 PowerShell 路径始终可用,因为您在路径中调用的任何内容都会在您尝试使用它时自动加载。
再次 Get-Command 将列出所有可用的,它们仅在您调用一个时加载,并且在调用或会话完成/关闭时消失。
如果您的模块、cmdlet / 函数不在预期的(环境或 PS 路径)位置,则必须添加该路径或使用它们的 UNC 路径来运行它们。因此,路径中的任何内容(源自任何 UNC 的点源)始终可用。如果您在 ISE 中,您可以在“命令”选项卡中查看此内容,或者使用 Get-Command 在控制台中查看。
您可以通过 PowerShell 配置文件或使用 Windows 环境变量对话框即时或使用 PowerShell 配置文件临时添加路径,或永久添加路径。
控制台主机和 ISE 将始终列出预期路径中的任何模块、cmdlet 功能。它们并不意味着它们都是可用的。如前所述,出于显而易见的原因,特定于 ISe 的模块、cmdlet、函数只能在 ISE 中运行。然而,ISE 将运行控制台主机将运行的任何模块 cmdlet 功能,PSReadline 除外。好吧,它会加载它,但它不会在 ISE 控制台中执行任何操作。ISE 控制台实际上是一个输出窗口,与控制台主机不同。好吧,你可以在里面做控制台主机之类的东西,但这不是一回事。
因此,加载了模块,模块公开了其中的 cmdlet / 函数。并非所有模块都默认加载,因此上述两个命令的原因,这就是 Import-Module 和 auto load on call 存在的原因。独立的个人模块/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
...使用您的代码查看实际调用的内容,您将看到每次运行代码时都会调用它。
您安装的模块越多,云纹 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
...
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
#>
因此,基本 cmdlet / 功能不是来自 Import-Module 的工作。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.
因此,您再次认为,在导入模块或 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
在控制台主机中 - 注意差异
# 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
推荐阅读
- sql - SQL 查询不检查 After 和 Clause
- html - 为什么 flexbox 没有按预期对齐项目
- swift - 仅在模拟器/iPhone 中加载选项卡视图和按钮文本,但应用程序在预览中工作
- django - 测试 Django 是否发送电子邮件进行密码重置
- android - @null 在自定义视图中
- elasticsearch - 从特定文档开始的弹性搜索分页
- azure-data-explorer - 改进 Kusto Query - 邮箱审核日志搜索
- python - 尝试运行对象检测时出错
- reactjs - react-redux 当前道具值
- node.js - 如何通过 sequelize 的foreing key value 巧妙地查询?