about_Command_Precedence

簡短描述

描述 PowerShell 如何決定要執行的命令。

詳細描述

命令優先順序描述當會話包含多個具有相同名稱的命令時,PowerShell 如何決定要執行的命令。 會話內的命令可以隱藏或取代為相同名稱的命令。 本文說明如何執行隱藏的命令,以及如何避免命令名稱衝突。

命令優先順序

當 PowerShell 工作階段包含多個具有相同名稱的命令時,PowerShell 會決定要使用下列規則執行的命令。

如果您指定命令的路徑,PowerShell 會在路徑所指定的位置執行命令。

例如,下列命令會在 C:\TechDocs 目錄中執行 FindDocs.ps1 腳本:

C:\TechDocs\FindDocs.ps1

您可以使用完整路徑來執行任何可執行命令。 作為安全性功能,除非命令位於環境變數所列 $env:Path 的路徑中,否則PowerShell不會執行可執行命令,包括PowerShell腳本和原生命令。

若要執行目前目錄中的可執行檔,請指定完整路徑或使用相對路徑 .\ 來代表目前目錄。

例如,若要在目前目錄中執行 FindDocs.ps1 檔案,請輸入:

.\FindDocs.ps1

如果您未指定路徑,PowerShell 會在執行命令時使用下列優先順序。

  1. 別名
  2. 函式
  3. Cmdlet (請參閱 Cmdlet 名稱解析
  4. 外部可執行檔(包括 PowerShell 腳稿檔案)

因此,如果您輸入 help,PowerShell 會先尋找名為 的別名,然後尋找名為 help的函式,最後尋找名為 HelpHelp的 Cmdlet。 它會執行它找到的第一 help 個專案。

例如,如果您的會話包含 Cmdlet 和函式,當您輸入 Get-Map時,兩者皆名為 Get-Map,則 PowerShell 會執行函式。

注意

這隻適用於載入的命令。 如果函式具有build未載入目前會話之模組內名稱Invoke-Build的可執行檔和別名build,PowerShell 會改為執行build可執行檔。 如果找到外部可執行檔,它就不會自動載入模組。 只有在找不到任何外部可執行檔時,才會叫用具有指定名稱的別名、函式或 Cmdlet。

解析具有相同名稱的專案

由於這些規則,專案可以以相同名稱取代或隱藏專案。

如果您仍然可以存取原始專案,例如將專案名稱限定為模組名稱,則專案會 隱藏遮蔽

例如,如果您匯入的函式名稱與會話中的 Cmdlet 相同,則會隱藏 Cmdlet,但不會取代。 您可以指定其模組限定名稱來執行 Cmdlet。

當專案 被取代寫時,您無法再存取原始專案。

例如,如果您匯入與會話中變數同名的變數,則會取代原始變數。 您無法使用模組名稱來限定變數。

如果您在命令行建立函式,然後匯入具有相同名稱的函式,則會取代原始函式。

尋找隱藏的命令

Get-Command Cmdlet 的 All 參數會取得具有指定名稱的所有命令,即使它們已隱藏或取代也一樣。 從 PowerShell 3.0 開始,根據預設, Get-Command 只會取得當您輸入命令名稱時所執行的命令。

在下列範例中,會話包含函 Get-Date 式和 Get-Date Cmdlet。 您可以使用 Get-Command 來判斷先選擇哪一個命令。

Get-Command Get-Date
CommandType     Name                      ModuleName
-----------     ----                      ----------
Function        Get-Date

使用 All 參數來列出可用的Get-Date命令。

Get-Command Get-Date -All
CommandType     Name                 Version    Source
-----------     ----                 -------    ------
Function        Get-Date
Cmdlet          Get-Date             7.0.0.0    Microsoft.PowerShell.Utility
Get-Command where -All
CommandType Name                     Version      Source
----------- ----                     -------      ------
Alias       where -> Where-Object
Application where.exe                10.0.22621.1 C:\Windows\system32\where.exe

您可以藉由包含限定資訊,將命令與可能具有相同名稱的其他命令分開來執行特定命令。 針對 Cmdlet,您可以使用模組限定名稱。 針對可執行檔,您可以包含擴展名。 例如,若要執行的where可執行檔版本。where.exe

使用模組限定名稱

使用 Cmdlet 的模組限定名稱,可讓您執行同名項目隱藏的命令。 例如,您可以藉由將其模組名稱 Microsoft.PowerShell.Utility 或其路徑限定,以執行 Get-Date Cmdlet。 當您使用模組限定名稱時,模組可以根據的值 $PSModuleAutoLoadingPreference自動匯入會話。

注意

您無法使用模組名稱來限定變數或別名。

使用模組限定名稱可確保您正在執行您想要執行的命令。 撰寫您想要散發的腳本時,這是呼叫 Cmdlet 的建議方法。

下列範例說明如何藉由包含其模組名稱來限定命令。

重要

模組限定性會使用反斜杠字元 (\) 來分隔模組名稱與命令名稱,而不論平台為何。

New-Alias -Name "Get-Date" -Value "Get-ChildItem"
Microsoft.PowerShell.Utility\Get-Date
Tuesday, May 16, 2023 1:32:51 PM

若要從MapFunctions模組執行New-Map命令,請使用其模組限定名稱:

MapFunctions\New-Map

若要尋找從中匯入命令的模組,請使用 命令的ModuleName 屬性。

(Get-Command <command-name>).ModuleName

例如,若要尋找 Cmdlet 的來源 Get-Date ,請輸入:

(Get-Command Get-Date).ModuleName
Microsoft.PowerShell.Utility

如果您想要使用模組的路徑來限定命令的名稱,則必須在命令名稱之前使用正斜線 (/) 作為路徑分隔符和反斜杠字元 (\)。 使用下列範例來執行 Get-Date Cmdlet:

//localhost/c$/Progra~1/PowerShell/7-preview/Modules/Microsoft.PowerShell.Utility\Get-Date

路徑可以是相對於目前位置的完整路徑或路徑。 在 Windows 上,您無法使用磁碟驅動器限定路徑。 您必須使用 UNC 路徑,如上一個範例所示,或相對於目前磁碟驅動器的路徑。 下列範例假設您目前的位置位於磁碟驅動器中 C:

/Progra~1/PowerShell/7-preview/Modules/Microsoft.PowerShell.Utility\Get-Date

使用呼叫運算符

您也可以使用呼叫運算符 (&) 將呼叫與 Get-ChildItemGet-Commanddir呼叫結合,或 Get-Module 來執行隱藏的命令。

呼叫運算子會在子範圍中執行字串和腳本區塊。 如需詳細資訊,請參閱 about_Operators

例如,使用下列命令來執行名為 Map 的別名 Map所隱藏的函式。

& (Get-Command -Name Map -CommandType Function)

& (dir Function:\map)

您也可以將隱藏的命令儲存在變數中,以便更輕鬆地執行。

例如,下列命令會將函式儲存 Map 在變數中 $myMap ,然後使用 Call 運算符來執行它。

$myMap = (Get-Command -Name map -CommandType function)
& ($myMap)

已取代的專案

取代的專案是您無法再存取的專案。 您可以從模組匯入相同名稱的專案來取代專案。

例如,如果您在會話中輸入函 Get-Map 式,並匯入名為 Get-Map的函式,則會取代原始函式。 您無法在目前的會話中擷取它。

變數和別名無法隱藏,因為您無法使用呼叫運算符或限定名稱來執行它們。 當您從模組匯入變數和別名時,它們會以相同名稱取代會話中的變數。

Cmdlet 名稱解析

當您不使用 Cmdlet 的限定名稱時,PowerShell 會檢查 Cmdlet 是否在目前的會話中載入。 如果載入多個模組包含相同的 Cmdlet 名稱,PowerShell 會使用依字母順序找到的第一個模組中的 Cmdlet。

如果未載入 Cmdlet,PowerShell 會搜尋已安裝的模組,並自動載入包含 Cmdlet 的第一個模組,並執行該 Cmdlet。 PowerShell 會在環境變數中 $env:PSModulePath 定義的每個路徑中搜尋模組。 路徑會依變數中所列的順序進行搜尋。 在每個路徑中,模組會依字母順序搜尋。 PowerShell 會使用第一個相符專案所找到的 Cmdlet。

避免名稱衝突

管理命令名稱衝突的最佳方式是防止衝突。 當您命名命令時,請使用唯一的名稱。 例如,將縮寫或公司名稱縮寫新增至命令中的名詞。

當您從 PowerShell 模組或另一個工作階段將命令匯入工作階段時,您可以使用 Prefix Import-ModuleImport-PSSession Cmdlet 的參數,將前置詞新增至命令名稱中的名詞。

例如,下列命令可避免匯DateFunctions入模組時,與 PowerShell 隨附的 Get-DateSet-Date Cmdlet 發生任何衝突。

Import-Module -Name DateFunctions -Prefix ZZ

執行外部可執行檔

在 Windows 上。 PowerShell 會將環境變數中列出的 $env:PATHEXT 擴展名視為可執行檔。 不是 Windows 可執行文件的檔案會交給 Windows 進行處理。 Windows 會查閱檔案關聯,並執行延伸模塊的預設 Windows Shell 動詞命令。 若要讓 Windows 支援依擴展名執行,您必須向系統註冊關聯。

您可以使用 CMD 命令殼層的 和 assoc 命令,註冊擴展名ftype的可執行文件引擎。 PowerShell 沒有直接方法來註冊檔案處理程式。 如需詳細資訊,請參閱 ftype 命令的檔

若要讓 PowerShell 在目前的工作階段中看到擴展名為可執行檔,您必須將擴展名新增至 $env:PATHEXT 環境變數。

另請參閱