You're really testing for two things here, existence and value. And the existence test is the one causing the warnings under the strict mode operation. So, separate the tests. Remembering that PowerShell sees variables as just another provider (just like a file or registry provider) and that all PowerShell variables exist as files in the root folder of the drive called 'variable:', it becomes obvious that you can use the same mechanism that you would ordinarily use to test for any other file existence. Hence, use 'test-path':
if (!(test-path variable:\var)) {$var = $null} # test for EXISTENCE & create
if ( !$var ) { $var = "new-value"; } # test the VALUE
Note that the current strict mode can be changed in child scopes without affecting the parent scope (eg, in script-blocks). So, you could write a script block that encapsulates removing strict mode and setting the variable without affecting the surrounding program's strictness. It's a bit tricky because of variable scoping. Two possibilities I can think of:
#1 - return the value from the script block
$var = & { Set-StrictMode -off; switch( $var ) { $null { "new-value" } default { $var } }}
or #2 - use scope modifiers
& { Set-StrictMode -off; if (!$var) { set-variable -scope 1 var "new-value" }}
Probably the worst part about these are the error-prone, repetitive use of $var (both with and without the leading $). It seems very error prone. So, instead I'd use a subroutine:
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
This last is probably the way I'd script it.
EDIT: After thinking about your question for a bit longer, I came up with a simpler function that more closely matches your coding style. Try this function:
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"}
Hope that helps.