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