about_Command_Precedence
主题
about_Command_Precedence
简短说明
描述 Windows PowerShell 如何确定要运行哪个命令。
详细说明
此主题说明 Windows PowerShell 如何确定要运行哪个命令,特别是当会话包含多个同名命令时运行哪个命令。
另外,此主题还说明如何运行在默认情况下不会运行的命令,以及如何在会话中避免命令名冲突。
命令优先级
当会话包含多个同名命令时,Windows PowerShell 按以下规则确定运行哪个命令。
当从模块、管理单元和其他会话向您的会话中添加命令时,这些规则变得非常重要。
-- 如果指定了命令的路径,Windows PowerShell 则运行路径所指定的位置的命令。
例如,以下命令将运行位于 C:\TechDocs 目录下的 FindDocs.ps1 脚本:
C:\TechDocs\FindDocs.ps1
作为一项安全功能,Windows PowerShell 不运行包括 Windows PowerShell 脚本在内的可执行(本机)
命令,除非该命令位于在 Path 环境变量 ($env:path) 中列出的路径中或您指定了脚本文件的路径。
要运行位于当前目录下的脚本,请指定完整路径,或者键入句点 (.) 表示当前目录。
例如,要运行当前目录下的 FindDocs.ps1 文件,请键入:
.\FindDocs.ps1
-- 如果不指定路径,Windows PowerShell 将按以下优先级顺序运行命令:
1. 别名
2. 函数
3. Cmdlet
4. 本机 Windows 命令
因此,如果键入“help”,则 Windows PowerShell 先查找名为“help”的别名,然后查找名为
“Help”的函数,最后查找名为“Help”的 cmdlet。它将运行最先找到的“help”项。
例如,假定有一个名为 Get-Map 的函数,又添加或导入了一个名为 Get-Map 的 cmdlet,则在键入
“Get-Map”时 Windows PowerShell 默认将运行该函数。
-- 如果会话包含名称和类型都相同的项,例如两个同名的 cmdlet,则 Windows PowerShell 运行最近
添加到会话中的项。
例如,假定有一个名为 Get-Date 的 cmdlet,又导入了另一个名为 Get-Date 的 cmdlet,则在键入
“Get-Date”时 Windows PowerShell 默认将运行最近导入的 cmdlet。
隐藏和替换项
由于这些规则的存在,导致某些项可被同名的项替换或隐藏。
-- 如果仍可以通过某种方式(比如通过使用模块名称或管理单元名称限定项名称)访问原始项,则表示该项
被"隐藏"或"遮盖"。
例如,如果导入一个与会话中某 cmdlet 同名的函数,则会隐藏而不是替换该 cmdlet,因为该
cmdlet 是从管理单元或模块导入的。
-- 如果不能再访问原始项,则表示该项被“替换”或“覆盖”。
例如,如果导入一个与会话中某变量同名的变量,则原始变量将被替换,不可再访问。
变量不能通过模块名称进行限定。
此外,如果在命令行键入一个函数,然后导入一个同名的函数,则原始函数将被替换,不可再访问。
运行隐藏命令
可以通过指定项属性以将特定命令与其他可能同名的命令区分开来,从而运行特定的命令。
此方法可用于运行任何命令,但尤其适用于运行隐藏命令。
在编写要分发的脚本时请使用此方法作为一种最佳实践,因为您无法预知在运行脚本的会话中会存在什么命令。
限定名称
对于从 Windows PowerShell 管理单元或模块或者从其他会话导入的命令,可以使用命令的来源模块或管
理单元的名称对命令名进行限定,从而运行这些命令。
可以限定命令,但不能限定变量或别名。
例如,如果来自 Microsoft.PowerShell.Utility 管理单元的 Get-Date cmdlet 被其他同名别名、
函数或 cmdlet 隐藏,则可以使用该 cmdlet 的管理单元限定名称来运行它:
Microsoft.PowerShell.Utility\Get-Date
要运行由 MapFunctions 模块添加的 New-Map 命令,请使用该命令的模块限定名称:
MapFunctions\New-Map
要查找从其导入命令的管理单元或模块,请使用以下 Get-Command 命令格式:
get-command <command-name> | format-list -property Name, PSSnapin, Module
例如,要查找 Get-Date cmdlet 的来源,请键入:
get-command get-date | format-list -property Name, PSSnapin, Module
Name : Get-Date
PSSnapIn : Microsoft.PowerShell.Utility
Module :
调用运算符
也可以使用调用运算符 (&) 运行可通过 Get-ChildItem(alias 是“dir”)、Get-Command 或
Get-Module 命令获取的任何命令。
要运行某命令,请将 Get-Command 放在括号中,并使用调用运算符 (&) 运行该命令。
&(get-command ...)
- 或 -
&(dir ...)
例如,如果名为 Map 的函数被名为 Map 的别名隐藏,可使用以下命令运行该函数。
&(get-command -name map -type function)
- 或 -
&(dir function:\map)
也可以将隐藏命令保存在变量中以便于运行。
例如,以下命令将 Map 函数保存在 $myMap 变量中,然后使用调用运算符运行该命令。
$myMap = (get-command -name map -type function)
&($myMap)
如果命令源自某个模块,则可以使用以下格式运行该命令:
& <PSModuleInfo-object> <command>
例如,要运行 FileCommands 模块中的 Add-File cmdlet,可使用以下命令序列:
$FileCommands = get-module -name FileCommands
& $FileCommands Add-File
替换项
对于不是从模块或管理单元导入的项,比如您在会话中自建的函数、变量和别名,
或者您使用配置文件添加的项,则可能被同名的命令替换。这些项若被替换则不
可访问。
变量和别名总是被替换,即使它们是从模块或管理单元导入的也如此,
这是因为您无法使用调用运算符或限定名称运行它们。
例如,如果在会话中键入 Get-Map 函数,又导入一个名为 Get-Map 的函数,
则原始函数将被替换,您无法在当前会话中检索原始函数。
避免名称冲突
管理命令名冲突的最佳方式是避免出现冲突。在为命令指定名称时,
应使用独特且不太可能重复的名称。例如,可以在您的命令名中的名词中
添加您的姓名或公司名的首字母缩写。
另外,在从 Windows PowerShell 模块或其他会话向您的会话导入命令时,应使用 Import-Module 或
Import-PSSession 的 Prefix 参数为命令名中的名词添加前缀。
例如,在导入 DateFunctions 模块时,使用以下命令可以避免与 Windows PowerShell 附带的 Get-Date
和 Set-Date cmdlet 产生任何冲突。
import-module -name DateFunctions -prefix ZZ
有关详细信息,请参阅 Import-Module 和 Import-PSSession cmdlet 的帮助主题。
另请参阅
about_Path_Syntax
about_Aliases
about_Functions
Alias(提供程序)
Function(提供程序)
Get-Command
Import-Module
Import-PSSession