Поделиться через


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 или из другого сеанса можно использовать параметр PrefixImport-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.

См. также