Home > Mobile >  PowerShell if-statement with a condition in a string
PowerShell if-statement with a condition in a string

Time:12-14

I have a condition stored in a string variable and I want to use this in an if-statement.

In this example there is always a match, as the variable is not zero or null, etc. It's not "executing" the variable as condition.

My wish is to "execute" the condition what is stored in the variable.

$myCheckTest = '$test -eq 4'
$test = 5

if ($myCheckTest) {
    write-host "TEST MATCH"
} else {
    write-host "TEST NO MATCH"
}

This works without the quotes like: $myCheckTest = $test -eq 4 but the condition is externally stored in a json file.

I also tried if ( & {$myCheckTest} ) { as I think that this is comparable with JavaScript if ( eval(condition) ) but this is still not giving me the proper answer "TEST NO MATCH" that I expect.

I am aware of powershell IF condition in a Variable but here the condition is not in a string-variable like I have.

CodePudding user response:

You might use the $ExecutionContext.InvokeCommand.ExpandString method to evaluate the string expression:

$test = 5
$myCheckTest = '$test -eq 4'
$ExecutionContext.InvokeCommand.ExpandString("`$($myCheckTest)")
False
$myCheckTest = '$test -eq 5'
$ExecutionContext.InvokeCommand.ExpandString("`$($myCheckTest)")
True

Note that the backtick (`) prevents the first dollar to be substituted so that you actual string expression will be something like: $($test -eq 4)
Or in your function:

if ($ExecutionContext.InvokeCommand.ExpandString("`$($myCheckTest)")) {
    write-host "TEST MATCH"
} else {
    write-host "TEST NO MATCH"
}

A more common way to do thing like this is, is to use a scriptblock:

$myCheckTest = {$test -eq 4}
$test = 5

if (&$myCheckTest) {
    write-host "TEST MATCH"
} else {
    write-host "TEST NO MATCH"
}

CodePudding user response:

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-expression

A collegae pointed me to the Invoke-Expression command:

if (Invoke-Expression $myCheckTest) {
    write-host "TEST MATCH"
} else {
    write-host "TEST NO MATCH"
}

This works within my actual script.

CodePudding user response:

You can use ScriptBlock.InvokeWithContext for this:

$myCheckTest = '$test -eq 4'

# Convert the string to ScriptBlock
$sb  = [scriptblock]::Create($myCheckTest)
# Argument to feed to the ScriptBlock
$arg = [psvariable]::new('test', 5)

if ($sb.InvokeWithContext(@{}, $arg)) {
    write-host "TEST MATCH"
}
else {
    write-host "TEST NO MATCH"
}
  • Related