我想在 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)
不。
我们如何只获得已安装的、可运行的命令?
至于这个根查询......
我想在 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)
| 归档时间: |
|
| 查看次数: |
7647 次 |
| 最近记录: |