为何PowerShell中通过ByPropertyName管道传递Module参数给Get-Command失败?如何解决?
这个问题我之前折腾过好一会儿,明明看Get-Help Get-Command里写着-Module参数支持ByPropertyName的管道输入,怎么实际用起来就报错呢?其实核心问题出在PowerShell的参数集绑定逻辑上。
为啥会失败?
Get-Command有好几个预设的参数集,默认情况下它会优先使用「按命令名查找」的参数集(就是你平时直接敲Get-Command 命令名用的那个)。当你通过管道传递带有Module属性的自定义对象时,因为没有明确指定要使用哪个参数,PowerShell还是会按默认逻辑走——它把整个自定义对象转换成字符串(就是报错里的@{Module=Microsoft.Powershell.Archive}),然后当作命令名去查找,这当然找不到对应的命令,自然就报错了。
虽然-Module参数确实支持ByPropertyName管道绑定,但它属于「按模块查找」的参数集,PowerShell不会自动切换到这个参数集,除非你明确告诉它要这么做。
解决方法有这几种
方法一:明确指定绑定到
-Module参数
直接告诉PowerShell要把管道对象的Module属性值绑定到-Module参数,这样它就会切换到对应的参数集:Get-Content .\modules.txt | Select-Object @{n='Module';e={$_}} | Get-Command -Module { $_.Module }方法二:用
ForEach-Object逐个处理
这种方式逻辑最直白,绕开参数集的坑,直接遍历每个模块名去查命令:Get-Content .\modules.txt | ForEach-Object { Get-Command -Module $_ }方法三:直接用你最开始的写法
其实你一开始用的Get-Command -Module (Get-Content .\modules.txt)就非常好用,直接把模块名的字符串数组传给-Module参数,明确指定了参数集,完全不会有问题,要是没必要用管道的话,这个是最省心的。
备注:内容来源于stack exchange,提问作者Dan Solovay

