简体   繁体   中英

using powershell invoke-expression to run code output

I have been doing a lot of reading on invoke-expression (also known as iex) and I'm having trouble getting it to work for me.

My understanding is, it will run any powershell code you give to it. However, when I run my tests on it, it does not run the code.

Example:

## testcode.ps1

$myvar = "i am here"
if ($myvar -ne $null) {
    "($myvar) variable is Full"
} else {
    "($myvar) variable is Empty"
}

Now, if I cat(gc) this file and I pass it to iex , it outputs a bunch of errors. Same thing happens when I save the code into a variable and then feed the variable to iex . Neither works.

Despite the fact that I've tried numerous examples, I feel there's something minor I'm doing wrong that I'm hoping someone can point out for me.

I'm new to Windows scripting, so please bear with me. These are the results of the tests I performed:

First Test:

PS C:\Users\J> gc C:\Users\J\testcode.ps1 | iex
Invoke-Expression : Cannot bind argument to parameter 'Command' because it is an empty string.
At line:1 char:31
+ cat C:\Users\J\testcode.ps1 | iex    
+                               ~~~    
    + CategoryInfo          : InvalidData: (:PSObject) [Invoke-Expression], ParameterBindingValidationException   
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand
iex : At line:1 char:23
+ if ($myvar -ne $null) {
+                       ~
Missing closing '}' in statement block or type definition.
At line:1 char:31
+ cat C:\Users\J\testcode.ps1 | iex
+                               ~~~
    + CategoryInfo          : ParserError: (:) [Invoke-Expression], ParseException
    + FullyQualifiedErrorId : MissingEndCurlyBrace,Microsoft.PowerShell.Commands.InvokeExpressionCommand

Second Test:

PS C:\Users\J> $scriptBlock = gc C:\Users\J\testcode.ps1
PS C:\Users\J> 
PS C:\Users\J> iex -Command "$scriptBlock"
iex : At line:1 char:23
+  $myvar = "i am here" if ($myvar -ne $null) {     "($myvar) variable  ...
+                       ~~
Unexpected token 'if' in expression or statement.
At line:1 char:1
+ iex -Command "$scriptBlock"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ParserError: (:) [Invoke-Expression], ParseException
    + FullyQualifiedErrorId : UnexpectedToken,Microsoft.PowerShell.Commands.InvokeExpressionCommand

PS C:\Users\J>

I'm aware that I can just run the file containing the code. However, I need help figuring out how iex works and what it is I'm doing wrong.

Please kindly advise.

First things first:

Invoke-Expression should generally be avoided and used only as a last resort , due to its security risks. In short: avoid it, if possible, given that superior alternatives are usually available. If there truly is no alternative, only ever use it on input you either provided yourself or fully trust - see this answer .

For the record: in the case at hand, the superior alternative is to directly invoke the script file:

# Prepend `& `, if the script file path is quoted or references a variable.
C:\Users\J\testcode.ps1

Invoke-Expression ( iex ) accepts multiple strings via the pipeline , and evaluates each individually, as a self-contained script.
Therefore, you must provide the contents of your script as a whole , as a single string , which is what Get-Content 's ( gc 's) -Raw switch does [1] :

Get-Content -Raw C:\Users\J\testcode.ps1 | Invoke-Expression

Alternatively, pass the script-file contents as an argument :

Invoke-Expression (Get-Content -Raw C:\Users\J\testcode.ps1)

Note that passing the string to evaluate as an argument truly only accepts a single string, so the command would fail without -Raw .


[1] By default, the Get-Content cmdlet reads a file line by line , passing each line through the pipeline as it is being read.

$myvar = "I'm Here"

#Using Invoke-Expression - Accepts a STRING as Input

$SBCode = 'if ($Null -ne $myvar) {"($myvar) variable is Full"}' +
          'else {"`$myvar variable is Empty"}'

Clear-Host
"Before Invoke-Expression `$myvar = $myvar"

$Result = Invoke-Expression  $SBCode

"Invoke-Expression Returns: $Result"

#Using Invoke-Command - Accepts Script Block as Input

$SBCode = {
   if ($myvar -ne $null) {
     "($myvar) variable is Full"
   } 
   else {
    "`$myvar variable is Empty"
   }
} #End $SBCode Script Block

"Before Invoke-Command `$myvar = $myvar"

$Result = Invoke-Command -ScriptBlock $SBCode

"Invoke-Command Returns: $Result"

Results:

Before Invoke-Expression $myvar = I'm Here
Invoke-Expression Returns: (I'm Here) variable is Full
Before Invoke-Command $myvar = I'm Here
Invoke-Command Returns: (I'm Here) variable is Full

# After changing $MyVar = $Null

Before Invoke-Expression $myvar = 
Invoke-Expression Returns: $myvar variable is Empty
Before Invoke-Command $myvar = 
Invoke-Command Returns: $myvar variable is Empty

HTH

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM