Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 349 Vote(s) - 3.51 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PowerShell - How do I test for a variable value with "Set-StrictMode -version latest"?

#1
I've just started doing some PowerShell scripting, and I'm running into a problem testing variables for a value. I try to run everything with all warnings enabled, especially while I'm learning, in order to catch dumb mistakes. So, I'm using CTPV3 and setting strict mode on with "set-strictmode -version latest". But I'm running into a road block with checking incoming variables for a value. These variables may or may not already be set.

# all FAIL if $var is undefined under "Set-StrictMode -version latest"
if ( !$var ) { $var = "new-value"; }
if ( $var -eq $null ) { $var = "new-value"; }

I can't find a way to test if a variable has a value that doesn't cause warnings when the variable is missing unless I turn off strict mode. And I don't want to turn strict mode on and off all over the place just to test the variables. I'm sure I'd forget to turn it back on somewhere and it looks terribly cluttered. That can't be right. What am I missing?

Reply

#2
Firstly I love Roy's answer, complete and succinct. I just wanted to mention that it seems like you're trying to only set a variable if it's been set already. This seems like a job for read-only variables, or constants.

To make a variable read-only, a constant, use

Set-Variable
From `get-help Set-Variable -full`

-- ReadOnly: Cannot be deleted or changed without the Force parameter.
-- Constant: Cannot be deleted or changed. Constant is valid only when
creating a new variable. You cannot set the Constant option on an
existing variable.

Reply

#3
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, `var` must not have a leading $ or the shell attempts to read the possibly non-existant $var
set-Variable-IfMissingOrNull 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.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through