Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute powershell code which is in variable

Tags:

powershell

suppose I have the following powershell code stored in a file:

## file1.ps1

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

And this code is then stored in a variable:

$code_in_var = cat file1.ps1

How do I execute the code in the variable through piping?

I have tried the following:

PS C:\Mrm> $code_in_var = cat file1.ps1
PS C:\Mrm>
PS C:\Mrm> cat file1.ps1 | powershell -
PS C:\Mrm> 
PS C:\Mrm> cat file1.ps1 | Invoke-expression
Invoke-expression ; At line:1 char:23
+ if ($myvar -ne $null) {
+            ~
Missing closing '}' in statement bllock or type definition
At line:1 char:17

PS C:\Mrm>
PS C:\Mrm> $code_in_var | powershell -   ***(this does not return anything)***
PS C:\Mrm>
PS C:\Mrm>
PS C:\Mrm> $code_in_var | Invoke-expression
**same error**

However, If I run this script directly:

PS C:\Mrm> .\file1.ps1
(i am here) variable is Full

It works as it is expected to.

My question is, how do I run a full powershell code that is stored in a variable, as though it were in a file?

like image 842
KLZY Avatar asked Oct 20 '25 11:10

KLZY


2 Answers

You can store a ScriptBlock in a variable and use the & call operator like this:

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

& $scriptBlock

Output:

(i am here) variable is Full
like image 95
Theo Avatar answered Oct 22 '25 02:10

Theo


A similar thing is fully documented in the MS Docs PowerShell help file.

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-expression?view=powershell-7

You will note that at no point is the formatted multi-line code used. It's all one-liner execution code.

Note that in the call of your code, it's just this.

    @($myvar = "i am here"
    if ($myvar -ne $null) {
        "($myvar) variable is Full"
    } else {
        "($myvar) variable is Empty"
    }) | 
    Out-File -FilePath 'D:\Temp\MyCode.ps1'

    ($Command = Get-Content -Path 'D:\Temp\MyCode.ps1')

    # Results the code just runs with no Invoke-* needed
    <#
    (i am here) variable is Full
    #>

Update as per my comments

You define a var, with whatever string you want, and just type the var name. But you must do it all in the PowerShell process.

Why define PowerShell code outside the PowerShell process, just to send it to the PowerShell process?

# In a PowerShell Script development session

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

$MyCode

# Results
<#
(i am here) variable is Full
#>

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

$myvar
# Results
<#
i am here
#>

# In a PowerShell terminal interactive session. 

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

$myvar
# Results
<#
i am here
#>

$myvar = $null;if ($myvar -ne $null) {"$myvar variable is Full"} else {Write-Warning -Message "$myvar variable is Empty"}

# Results
<#
WARNING:  variable is Empty
#>

You cannot define a var outside of PowerShell then start PowerShell and try to use that var content. It's not in scope. All code, vars, functions, etc., have a scope and the scope must be defined in the PowerShell process

If you are saying you are wanting to run PowerShell code started from another terminal, say cmd.exe, then PowerShell has start parameters, and proper quoting, when needed, is a thing.

# There are several PowerShell startup parameters
<#
The syntax of Powershell.exe Command is:

PowerShell[.exe] 
[-EncodedCommand ]
[-ExecutionPolicy ]
[-InputFormat {Text | XML}]
[-Mta]
[-NoExit]
[-NoLogo]
[-NonInteractive]
[-NoProfile]
[-OutputFormat {Text | XML}]
[-PSConsoleFile ]
[ -Version <Windows PowerShell version> ]
[-Sta]
[-WindowStyle ]<style>
[-File <FilePath> [<Args>]]
[-Command { - | <script-block>  [-args <arg-array> ] | <string>  [<CommandParameters>] } ]
#>
powershell -Command  "Whatever command you want to run"

# Example, from a cmd.exe prompt
powershell -NoProfile -Command Get-Date
# Results
<#
Sunday, 14 June, 2020 04:31:38
#>

powershell -NoProfile -Command '{"Hello World"}'
# Results
<#
Hello World
#>

You cannot do this ...

${yourcode} | powershell

... outside of a PowerShell session. The PowerShell pipeline is only available in a PowerShell session. If you are already in a session, then again, just type and run the code.

Whatever terminal you are in has to be able to send this to PowerShell to run via the normal PowerShell startup. Yet, again, this is just introducing unneeded complexity, vs just running the script of running the code in a PowerShell interactive session directly.

like image 26
postanote Avatar answered Oct 22 '25 03:10

postanote