Используем функцию PowerShell для проверки существования команды – Hey, Scripting Guy! Blog

Резюме: Microsoft Scripting Guy, Ed Wilson пишет функцию для проверки существования команды.

Находим требуемую команду в Windows PowerShell

Не так давно я использовал командлет Get-ADReplicationConnection. Я хотел определить, доступен ли этот командлет на основании версии модуля ActiveDirectory. Однако, по-видимому команда AD DS не изменяла номер версии модуля.

PS C:\> ipmo activedirectory

PS C:\> (Get-Module activedirectory).version

Major Minor Build Revision

—— —— —— ———

1 0 0 0

Это означает, что для определения того, доступен ли некоторый командлет, мне нужно попробовать его использовать. В случае его наличия, он выполнится, а в случае отсутствия я получу сообщение об ошибке Или же я могу воспользоваться командлетом Get-Command для поиска нужной команды, но все равно, при ее отсутствии будет возвращено сообщение об ошибке.

Так что я решил написать собственную функцию для проверки доступности команды.

Функция Test-CommandExists

Для того, чтобы в случае отсутствия команды не выдавалось сообщение об ошибке, я использую конструкцию Try/Catch/Finally. Проблема состоит в том, что отсутствие команды вызывает непрерывающую ошибку (non-terminating error), а Try/Catch/Finally обрабатывает только прерывающие ошибки (terminating error). Прерывающие ошибки это настолько серьезные ошибки, что Windows PowerShell не может ничего поделать, кроме как прерывать выполнение кода. Непрерывающие ошибки тоже могут быть весьма серьезными, однако при их возникновении Windows PowerShell по умолчанию просто переходит к следующей команде. Чтобы изменить это поведение, мне нужно изменить значение переменной $ErrorActionPreference со значения по умолчанию (“continue”) на значение “stop”. В этом случае возникновение непрерывающей ошибки приведет к тому, что Windows PowerShell все же прервет выполнение, позволяя таким образом блоку Try/Catch/Finally обработать ошибку.

Но изменение привилегированной переменной (preference variable) без спроса – это нехорошо (а также не входит в список рекомендаций по работе с PowerShell), так что я поменяю ее значение только на время работы моей функции. По ее завершении я верну ее к предыдущему значению. Что мне нравится в конструкции Try/Catch/Finally, так это то, что я могу указать отдельный код для каждого блока.

Заметка: Блок Finally обрабатывается в любом случае, так что это отличное место для кода, возвращающего переменную $ErrorActionPreference к прежнему значению. Лично я всегда использую секцию Finally для того, чтобы прибрать за собой.

Итак, одно из действий, которые мне необходимо произвести – это сохранить текущее значение переменной $ErrorActionPreference, а затем назначить ей значение “stop”. Эти две строки кода приведены ниже.

$oldPreference = $ErrorActionPreference

$ErrorActionPreference = ‘stop’

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

Param ($command)

Я использую секцию Try для поиска команды. Для этого я воспользуюсь условием If, в котором я попытаюсь получить команду при помощи командлета Get-Command. Если команда существует, я выведу эту информацию на экран.

try {if(Get-Command $command){«$command exists»}}

Блок Catch я использую для обработки возникновения ошибки. То есть, если командлет Get-Command вернет ошибку, выполнение кода перейдет к блоку Catch, где я укажу сообщение об отсутствии команды.

Catch {«$command does not exist»}

Если возникнет ошибка, код из блока Catch сообщит об отсутствии команды. Далее выполнение кода перейдет к блоку Finally. Если же ошибки не возникнет, блок Catch не будет выполнен. Однако блок Finally все равно отработает, так как он выполняется всегда. В секции Finally я верну переменную $ErrorActionPreference к ее изначальному значению.

Finally {$ErrorActionPreference=$oldPreference}

Полный текст функции приведен ниже.

Function Test-CommandExists

{

Param ($command)

$oldPreference = $ErrorActionPreference

$ErrorActionPreference = ‘stop’

try {if(Get-Command $command){«$command exists»}}

Catch {«$command does not exist»}

Finally {$ErrorActionPreference=$oldPreference}

} #end function test-CommandExists

Когда я запущу эту функцию, выведется следующее.

01

Делаем функцию Test-CommandExists более удобной

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

Function Test-CommandExists

{

Param ($command)

$oldPreference = $ErrorActionPreference

$ErrorActionPreference = ‘stop’

try {if(Get-Command $command){RETURN $true}}

Catch {Write-Host «$command does not exist»; RETURN $false}

Finally {$ErrorActionPreference=$oldPreference}

} #end function test-CommandExists

Мне не обязательно было указывать команду return, но это делает код более читаемым. С блоком Try все просто. А вот над секцией Catch мне пришлось немного подумать. Если бы код в этой секции возвращал только $false, при вызове следующей команды на экране бы ничего не отображалось.

If(Test-CommandExists Get-myService){Get-myService}

Но с другой стороны, если блок возвращает строку, в которой говорится о том, что команда не существует, условием If это приравнивается к $true. Поэтому я решил использовать Write-Host, поскольку он не передает строку в выходной поток, и таким образом вызывающий код ее не увидит. Использование функции приведено на рисунке ниже.

02

Автор:

Ed Wilson, Microsoft Scripting Guy

Оригинал:

http://blogs.technet.com/b/heyscriptingguy/archive/2013/02/19/use-a-powershell-function-to-see-if-a-command-exists.aspx


Страницы в социальных сетях:

Twitter: https://twitter.com/vsseth
Facebook: https://fb.com/inpowershell
VKontakte: https://vk.com/inpowershell


Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s