Вы действительно проверяете две вещи: существование и ценность. И тест на существование является тем, который вызывает предупреждения при работе в строгом режиме. Итак, отдельные тесты. Помните, что PowerShell рассматривает переменные просто как другого поставщика (как поставщика файлов или реестра) и что все переменные PowerShell существуют как файлы в корневой папке диска называется 'variable:', становится очевидным, что вы можете использовать тот же механизм, который вы обычно используете для проверки любого другого файла существования. Следовательно, используйте 'test-path':
if (!(test-path variable:\var)) {$var = $null} # test for EXISTENCE & create
if ( !$var ) { $var = "new-value"; } # test the VALUE
Обратите внимание, что текущий строгий режим можно изменить в дочерних областях, не затрагивая родительскую область (например, в скриптовых блоках). Таким образом, вы могли бы написать блок сценария, который инкапсулирует удаление строгого режима и установку переменной, не влияя на строгость окружающей программы. Это немного сложно из-за переменной области видимости. Я могу придумать две возможности:
# 1 - вернуть значение из блока скрипта
$var = & { Set-StrictMode -off; switch( $var ) { $null { "new-value" } default { $var } }}
или # 2 - использовать модификаторы области видимости
& { Set-StrictMode -off; if (!$var) { set-variable -scope 1 var "new-value" }}
Вероятно, худшая часть этих ошибок - это подверженное ошибкам повторяющееся использование $ var (как с начальным $, так и без него). Это кажется очень подверженным ошибкам. Итак, вместо этого я бы использовал подпрограмму:
function set-Variable-IfMissingOrNull ($name, $value)
{
$isMissingOrNull = !(test-path ('variable:'+$name)) -or ((get-variable $name -value) -eq $null)
if ($isMissingOrNull) { set-variable -scope 1 $name $value }
}
set-alias ?? set-Variable-IfMissingOrNull
#...
## in use, must not have a leading $ or the shell attempts to read the possibly non-existant $var
set-VarIfMissingOrNull var "new-value"
?? varX 1
Возможно, это последний способ, которым я написал бы сценарий.
РЕДАКТИРОВАТЬ: Подумав немного над вашим вопросом, я придумал более простую функцию, которая более точно соответствует вашему стилю кодирования. Попробуйте эту функцию:
function test-variable
{# return $false if variable:\$name is missing or $null
param( [string]$name )
$isMissingOrNull = (!(test-path ('variable:'+$name)) -or ((get-variable -name $name -value) -eq $null))
return !$isMissingOrNull
}
set-alias ?-var test-variable
if (!(?-var var)) {$var = "default-value"}
Надеюсь, это поможет.