2

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.

4
  • The variable $test is just a string inside single quotes and doesn't get substituted. Use double quotes instead. Commented Dec 14, 2022 at 11:57
  • Thank you jdweng, but substitution is not what I want. The string in variable $myCheckTest comes from a json file, so substitution will not happen... I switched the first 2 lines in the example to make it more clear. Commented Dec 14, 2022 at 12:01
  • WHAT???? You if statement is always doing '$test -eq 4' $test is always the string "$test". So "$test" never will equal "4". Commented Dec 14, 2022 at 12:07
  • My wish is that '$test -eq 4' will be executed in the if-statement and that within the if-statement the $test will be replaced by 5, not before... Commented Dec 14, 2022 at 12:12

3 Answers 3

1

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"
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you iRon for such clear and complete response, I tested this in my actual script and this works as well. I shall read about both $ExecutionContext.InvokeCommand.ExpandString as about Invoke-Expression to see the differences.
Can we use the test as a parameter to a formatted string? For example: "{0}" -f &{ if (5 -eq 5) { "yes" } else { "No" } }. It doesn't work, but maybe I'm missing something.
@RonJohn, that expression doesn't work by itself and looks quiet cumbersome for something that could be done like: $ExecutionContext.InvokeCommand.ExpandString('$(if (5 -eq 5) { "yes" } else { "No" })') or: $ExecutionContext.InvokeCommand.ExpandString('$(@("No", "Yes")[5 -eq 5])')
I just gave a trivial example. The real formatted string would be much more complicated.
@RonJohn, I see. If I didn't answer your comment, I recommend you to post a formal question with a more specific example.
0

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.

Comments

0

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"
}

2 Comments

Thank you Santiago, nice to see extra options :-) but I have to say that this is a less readable then if (Invoke-Expression $myCheckTest) Still it can be very useful in certain cases....
@Mauricevan'tLoo yup; agreed. The only problem with iex is no way of handling possible arbitrary code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.