«Я не всегда тестирую свои сценарии, но когда делаю это, я делаю это в продакшн»
Не лги. Ты делал это раньше. Мы все делали это в определенный момент времени. Однако, запуск PowerShell сценариев в продакшн среде не обязательно является рискованным. Просто помни использовать встроенный параметр PowerShell WhatIf!
Не было бы здорово знать, что бы делала эта команда PowerShell перед тем, как она внесет изменения в вашу среду? Представьте, что вы можете спросить у своей команды: «Что бы вы сделали, если бы запустились?» Вы можете использовать параметр WhatIf
.
Все скомпилированные сценарии PowerShell включают параметр с именем WhatIf
. Этот параметр помогает вам оценить, будет ли команда работать, как вы ожидаете, или запустит ядерный плавильный котел.
Удобный параметр WhatIf
доступен не только для всех встроенных командлетов, но и для ваших сценариев и расширенных функций! Если ваш код будет вносить изменения в вашу среду, у вас есть возможность использовать механизм безопасности в случае неудачи, если вы решите его реализовать.
Необходимые условия
Эта статья будет пошаговым руководством. Если вы хотите следовать за мной в этом путешествии, у вас должно быть несколько вещей.
- A Windows computer capable of running Powershell v5.1. (Windows 10 and above recommended)
- A script editor like Notepad++, the Windows PowerShell ISE or Visual Studio Code.
Обратите внимание, что в этой статье я буду использовать Visual Studio Code 1.38 (август 2019 года) на компьютере с Windows 10.
Параметр WhatIf в PowerShell: Определение
Вкратце, параметр WhatIf
является встроенным переключателем параметра, доступным со всеми расширенными функциями и командлетами (путем добавления ключевого слова PowerShell CmdletBinding
в сценарии и функциях). При использовании этой команды отчет ожидаемого эффекта команды выводится в консоль, но сама команда не выполняется.
Все командлеты и расширенные функции имеют параметр WhatIf. В этой статье мы продемонстрируем использование этого параметра с помощью командлетов Get-Service
, Stop-Service
и New-Item
.
Проверка поддержки параметра WhatIf в PowerShell
Если вы не уверены, поддерживает ли определенная команда WhatIf
, есть два быстрых способа проверки.
Использование команды Get-Command
Вы можете использовать команду Get-Command
для просмотра метаданных команды, используя параметр Syntax
, как показано ниже. Если вы видите ссылку на -WhatIf
, значит поддерживается WhatIf
.

Get-Command <CommandName> -Syntax
Использование автодополнения
Вы также можете проверить поддержку параметра WhatIf
с помощью автодополнения. Просто введите команду, которую хотите проверить, в консоли PowerShell, а затем пробел, тире, ‘Wh’ и клавишу табуляции.
Если появляется WhatIf
, значит эта команда имеет параметр WhatIf
.

PS> <CommandName> -Wh[tab]
Использование параметра PowerShell WhatIf
с командлетами
Существует множество различных способов использования параметра WhatIf
. В этом разделе вы узнаете, как начать использовать параметр WhatIf
немедленно с помощью встроенных cmdlet-ов.
Создание файла
Как и у всех cmdlet-ов, у cmdlet-а New-Item
есть параметр WhatIf
. В этом примере вы будете использовать cmdlet New-Item
для создания файла с именем newfile1.txt в текущем рабочем каталоге.
Если вы выполните нижеприведенную команду, она создаст файл с именем newfile.txt.

PS51> New-Item -ItemType File -Path .\newfile1.txt
Но что, если эта команда создает файл, который может вызвать проблемы, если он создается неудачно? Нет проблем. Вы можете добавить параметр WhatIf
в конец.

New-Item -ItemType File -Path .\newfile1.txt -WhatIf
Остановка службы
Вы также можете использовать параметр WhatIf
с cmdlet-ом Stop-Service
. В этом примере вы получаете список первых пяти служб и останавливаете их с помощью команды Stop-Service
. Но вы этого не делаете.
Вместо этого вы только видите сообщение в выводе консоли PowerShell, которое сообщает вам, какие службы остановил бы cmdlet Stop-Service
.
PS51> (Get-Service)[0..4] | Stop-Service -WhatIf
Изменение глобального поведения WhatIf в Powershell
На данный момент вы должны знать, что использование параметра WhatIf
с cmdlet-ом или расширенной функцией только симулирует операцию. Вы влияете на поведение WhatIf
на уровне команды.
Поведение WhatIf
также можно установить на более высоком уровне, что влияет на все команды путем изменения автоматической переменной $WhatIfPreference
.
Переменная $WhatIfPreference
имеет тип boolean. Она может быть только True
или False
. По умолчанию она установлена в False, что означает, что поддержка WhatIf
отключена для всех команд, если не переопределена на уровне команды. Если установить на True
, все команды, поддерживающие это, будут работать в режиме “WhatIf”, независимо от явного использования параметра WhatIf
.
Вы можете проверить это, изменив значение $WhatIfPreference
на True
с помощью $WhatIfPreference = $true
. Как видно ниже, при использовании команды New-Item
без параметра WhatIf
она будет работать так, как если бы параметр был передан.

PS51> $WhatIfPreference = $true
Если вы изменили значение
$WhatIfPreference
наTrue
, не забудьте вернуть его обратно наFalse
с помощью$WhatIfPreference = $false
.
На этом этапе вы узнали, как использовать поддержку WhatIf с существующими командами. В следующем действии вы узнаете, как добавить поддержку WhatIf в свои собственные скрипты и функции.
Реализация поддержки WhatIf в функциях PowerShell
Перед тем, как приступить к реализации поддержки WhatIf
в своих скриптах, важно знать, что есть правильный и неправильный способы это делать. В следующих разделах вы узнаете, какие это способы.
Неправильный способ: не изобретайте велосипед
Не редкость, когда разработчики скриптов изобретают свой собственный механизм поддержки WhatIf
с помощью конструкций if/then. Ниже приведен пример.
Обратите внимание, что разработчик определил собственный параметр переключения WhatIf
. Затем, используя значение этого параметра, он использовал конструкцию if/then для обработки логики при использовании или отсутствии параметра WhatIf
.
Когда функция выше запускается с использованием параметра WhatIf, как показано ниже, кажется, что она выполнила свою работу. Фактически функция ничего не удалила и вывела сообщение в консоль.

PS51> Remove-LogFile -name log.txt -WhatIf
Если это работает, то в чем проблема с этим методом? Потому что вы игнорируете встроенные возможности расширенной функции. Вам нужно будет встраивать эту функциональность в каждую создаваемую функцию вместо того, чтобы сосредоточиться только на том, что будет делать команда, когда она будет отключена.
Вместо этого не изобретайте велосипед и используйте ключевое слово SupportsShouldProcess
в сочетании с $PSCmdlet.ShouldProcess()
. Это будет рассмотрено далее.
Делаем правильно: Использование SupportsShouldProcess
Все функции, использующие ключевое слово [CmdletBinding()]
, делают их “расширенными”. Это ключевое слово добавляет различные возможности функции, включая поддержку WhatIf
.
Все расширенные функции поддерживают функциональность WhatIf
, но вам нужно воспользоваться этим. Для этого вы должны использовать ключевое слово SupportsShouldProcess
внутри квадратных скобок [CmdletBinding()]
, как показано ниже.
Теперь функция позволяет вызывать метод ShouldProcess()
на переменной функции $PSCmdlet
, чтобы определить, был ли передан параметр WhatIf
функции или нет. Когда используется параметр WhatIf
, ShouldProcess()
возвращает False
. В противном случае он всегда возвращает True
.
WHATIF PARAMETER USED | SHOULDPROCESS() RESULT |
---|---|
True | False |
False | True |
Теперь вы можете видеть ниже, когда Remove-LogFile
выполняется с параметром WhatIf
; он отображает ту же самую функциональность, что и встроенные cmdlet’ы.

PS51> Remove-LogFile -name log.txt -WhatIf
Резюме
В этой статье вы узнали о параметре PowerShell WhatIf. Теперь вы должны понимать, как он работает и какие преимущества он может принести.
Вы также должны знать, что в следующий раз, когда вам понадобится надежная защита для ваших функций PowerShell, не стоит изобретать велосипед. Вместо этого воспользуйтесь существующей поддержкой PowerShell для параметра WhatIf
!