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. Функция
  3. Командлет (см . раздел Разрешение имен командлетов)
  4. Внешние исполняемые файлы (включая файлы скриптов PowerShell)

Таким образом, если ввести help, PowerShell сначала ищет псевдоним с именем help, затем функцию с именем Helpи, наконец, командлет с именем Help. Он запускает первый 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 (псевдоним — dir), Get-Command или 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, она заменяет исходную функцию. Вы не можете получить его в текущем сеансе.

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

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

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

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

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

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

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

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

Import-Module -Name DateFunctions -Prefix ZZ

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

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

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

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

См. также раздел