如何在PowerShell同会话使用不同别名并调用原Get-WmiObject命令?
在PowerShell中调用被覆盖的原始命令及类似Linux的别名禁用方法
问题说明
在Linux环境中我们可以用.\ls绕过别名直接调用原始命令,那PowerShell里有没有类似操作?比如下面这段代码,自定义了和原生cmdlet同名的Get-WmiObject函数,还创建了别名指向这个函数:
function Get-WmiObject { # 这里怎么调用原始的Get-WmiObject命令? Get-WmiObject "win32_bios" | select Manufacturer } New-Alias -Name "Get-WmiObject" -Value Get-WmiObject -Force
执行Get-WmiObject时会触发错误:
Get-WmiObject : The term 'Get-WmiObject' 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-WmiObject + ~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (Get-WmiObject:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException
原因是函数内部调用Get-WmiObject时,PowerShell会优先解析为当前自定义函数,导致递归调用最终出错。
解决方法
1. 在自定义函数中调用原始cmdlet的两种方式
方式一:使用cmdlet的完全限定名称(FQN)
PowerShell的每个内置cmdlet都属于特定模块,用模块名\cmdlet名的格式可以直接定位到原始命令,完全不受自定义函数或别名的影响。Get-WmiObject属于Microsoft.PowerShell.Management模块,修改后的代码如下:
function Get-WmiObject { # 直接用完全限定名称调用原始cmdlet Microsoft.PowerShell.Management\Get-WmiObject "win32_bios" | select Manufacturer } New-Alias -Name "Get-WmiObject" -Value Get-WmiObject -Force
方式二:提前保存原始命令的引用
在定义自定义函数之前,先把原始cmdlet的引用存到变量里,后续在函数中通过这个变量调用原始命令:
# 提前获取原始cmdlet的引用,指定CommandType确保拿到的是原生命令而非自定义函数 $originalGetWmi = Get-Command Get-WmiObject -CommandType Cmdlet function Get-WmiObject { # 通过调用变量中的原始命令引用执行操作 & $originalGetWmi "win32_bios" | select Manufacturer } New-Alias -Name "Get-WmiObject" -Value Get-WmiObject -Force
2. PowerShell中类似Linux的别名/命令覆盖绕过方法
- 针对内置cmdlet:优先使用完全限定名称(FQN),或者用
Get-Command指定-CommandType Cmdlet获取原始命令后执行,比如:# 直接调用原始Get-WmiObject & (Get-Command Get-WmiObject -CommandType Cmdlet) "win32_bios" - 针对外部可执行文件:类似Linux的
.\ls,PowerShell中可以用.\\前缀调用当前目录的可执行文件(避免和系统命令/别名冲突),比如当前目录有个ls.exe,可以用.\\ls执行它而不是系统的ls别名。
内容的提问来源于stack exchange,提问作者Ichigo Kurosaki
相关产品推荐
相关产品推荐

