about_Command_Precedence

Краткое описание

Описывает, как PowerShell определяет, какая команда будет выполняться.

Подробное описание

Приоритет команды описывает, как PowerShell определяет, какая команда выполняется, если сеанс содержит несколько команд с одинаковым именем. Команды в сеансе могут быть скрытыми или заменены командами с тем же именем. В этой статье показано, как выполнять скрытые команды и как избежать конфликтов имен команд.

Приоритет команд

Если сеанс PowerShell включает несколько команд с одинаковым именем, PowerShell определяет, какая команда выполняется с помощью следующих правил.

Если указать путь к команде, PowerShell выполняет команду в расположении, указанном в пути.

Например, следующая команда запускает скрипт FindDocs.ps1 в каталоге C:\TechDocs :

C:\TechDocs\FindDocs.ps1

Вы можете выполнить любую исполняемую команду с помощью полного пути. В качестве функции безопасности PowerShell не выполняет исполняемые команды, включая скрипты PowerShell и собственные команды, если команда не находится в пути, указанном в переменной $env:Path среды.

Чтобы запустить исполняемый файл, который находится в текущем каталоге, укажите полный путь или используйте относительный путь .\ для представления текущего каталога.

Например, чтобы запустить FindDocs.ps1 файл в текущем каталоге, введите:

.\FindDocs.ps1

Если путь не указан, PowerShell использует следующий порядок приоритета при выполнении команд.

  1. Псевдоним
  2. Function
  3. Командлет (см . разрешение имен командлетов)
  4. Внешние исполняемые файлы (включая файлы скриптов PowerShell)

Поэтому, если вы вводитеhelp, PowerShell сначала ищет псевдоним с именем, а затем функцию с именем и, наконец, командлет с именемHelphelpHelp. Он запускает первый help элемент, который он находит.

Например, если сеанс содержит командлет и функцию с именем Get-Map, при вводе Get-MapPowerShell запускает функцию.

Примечание.

Это относится только к загруженным командам. Если есть исполняемый build файл и псевдоним build функции с именем Invoke-Build внутри модуля, который не загружен в текущий сеанс, PowerShell запускает исполняемый build файл. Он не загружает модули автозагрузки, если он находит внешний исполняемый файл. Это только в том случае, если внешний исполняемый файл не найден, что вызывается псевдоним, функция или командлет с заданным именем.

Разрешение элементов с одинаковыми именами

В результате этих правил элементы могут быть заменены или скрыты элементами с тем же именем.

Элементы скрыты или тени, если вы по-прежнему можете получить доступ к исходному элементу, например путем указания имени элемента с именем модуля.

Например, если вы импортируете функцию с тем же именем, что и командлет в сеансе, командлет скрыт, но не заменен. Вы можете запустить командлет, указав его имя, указанное в модуле.

При замене или перезаписи элементов вы больше не сможете получить доступ к исходному элементу.

Например, при импорте переменной, которая имеет то же имя, что и переменная в сеансе, заменяется исходная переменная. Невозможно указать переменную с именем модуля.

Если вы создаете функцию в командной строке, а затем импортируете функцию с тем же именем, то будет заменена исходная функция.

Поиск скрытых команд

Параметр All командлета Get-Command получает все команды с указанным именем, даже если они скрыты или заменены. Начиная с PowerShell 3.0, Get-Command по умолчанию получает только команды, выполняемые при вводе имени команды.

В следующих примерах сеанс включает Get-Date функцию и командлет Get-Date . Чтобы определить, какая команда выбрана сначала, можно использовать 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

Вы можете выполнять определенные команды, включив квалифицированную информацию, которая отличает команду от других команд, которые могут иметь то же имя. Для командлетов можно использовать полное имя модуля. Для исполняемых файлов можно включить расширение файла. Например, чтобы запустить исполняемую версию where использования where.exe.

Использование имен с указанием модуля

С помощью имени модуля командлета можно выполнять команды, скрытые элементом с тем же именем. Например, можно запустить Get-Date командлет, присвоив ему имя модуля Microsoft.PowerShell.Utility или путь к нему. При использовании имен модулей модуль можно автоматически импортировать в сеанс в зависимости от значения $PSModuleAutoLoadingPreference.

Примечание.

Имена модулей нельзя использовать для квалификации переменных или псевдонимов.

Использование имен с указанием модуля гарантирует выполнение команды, которую вы планируете выполнить. Это рекомендуемый метод вызова командлетов при написании скриптов, которые вы планируете распространять.

В следующем примере показано, как квалифицировать команду, включив ее имя модуля.

Внимание

Квалификация модуля использует символ обратной косой черты (\) для разделения имени модуля от имени команды независимо от платформы.

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

Чтобы выполнить New-Map команду из MapFunctions модуля, используйте его имя, заданное модулем:

MapFunctions\New-Map

Чтобы найти модуль, из которого была импортирована команда, используйте свойство ModuleName команд.

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

Например, чтобы найти источник командлета Get-Date , введите:

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

Если вы хотите указать имя команды, используя путь к модулю, перед именем команды необходимо использовать косую черту (/) в качестве разделителя пути и символ обратной косой черты (\). Используйте следующий пример для запуска командлета Get-Date :

//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-ChildItem (псевдонимом ) dirGet-Command или Get-Module.

Оператор вызова выполняет строки и блоки скриптов в дочернем область. Дополнительные сведения см. в about_Operators.

Например, используйте следующую команду, чтобы запустить функцию с именемMap, скрытой псевдонимом.Map

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

or

& (dir Function:\map)

Вы также можете сохранить скрытую команду в переменной, чтобы упростить выполнение.

Например, следующая команда сохраняет Map функцию в переменной $myMap , а затем использует Call оператор для его запуска.

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

Замененные элементы

Замененный элемент — это элемент, к которому вы больше не можете получить доступ. Вы можете заменить элементы, импортируя элементы с тем же именем из модуля.

Например, если вы вводите Get-Map функцию в сеансе и импортируете вызываемую Get-Mapфункцию, она заменяет исходную функцию. Его нельзя получить в текущем сеансе.

Переменные и псевдонимы не могут быть скрыты, так как для их выполнения нельзя использовать оператор вызова или полное имя. При импорте переменных и псевдонимов из модуля они заменяют переменные в сеансе одинаковым именем.

Разрешение имен командлета

Если вы не используете полное имя командлета, PowerShell проверка, чтобы узнать, загружен ли командлет в текущем сеансе. Если есть несколько модулей, загруженных с одинаковым именем командлета, PowerShell использует командлет из первого модуля, найденного в алфавитном порядке.

Если командлет не загружен, PowerShell выполняет поиск установленных модулей и автоматически загружает первый модуль, содержащий командлет и запускает этот командлет. PowerShell ищет модули в каждом пути, определенном в переменной $env:PSModulePath среды. Пути выполняются в том порядке, в который они перечислены в переменной. В каждом пути модули выполняются в алфавитном порядке. PowerShell использует командлет из первого найденного совпадения.

Предотвращение конфликтов имен

Лучший способ управления конфликтами имен команд — предотвратить их. При имени команд используйте уникальное имя. Например, добавьте инициалы или название компании в существительные в командах.

При импорте команд в сеанс из модуля PowerShell или из другого сеанса можно использовать Prefix параметр командлета Import-Module или Import-PSSession , чтобы добавить префикс в существительные в именах команд.

Например, следующая команда позволяет избежать конфликтов с командлетами, которые входят в Get-DateSet-Date PowerShell при импорте DateFunctions модуля.

Import-Module -Name DateFunctions -Prefix ZZ

Выполнение внешних исполняемых файлов

В Windows. PowerShell обрабатывает расширения файлов, перечисленные в переменной $env:PATHEXT среды, как исполняемые файлы. Файлы, которые не являются исполняемыми файлами Windows, передаются в Windows для обработки. Windows ищет сопоставление файлов и выполняет команду оболочки Windows по умолчанию для расширения. Чтобы Windows поддерживало выполнение по расширению файла, необходимо зарегистрировать связь в системе.

Вы можете зарегистрировать исполняемый модуль для расширения файла с помощью ftype командной оболочки CMD и assoc команд. PowerShell не имеет прямого метода регистрации обработчика файлов. Дополнительные сведения см. в документации по команде ftype .

Чтобы PowerShell видел расширение файла как исполняемый файл в текущем сеансе, необходимо добавить расширение в $env:PATHEXT переменную среды.

См. также