Question

Powershell version used: 3.0

Hello everyone,

I'm looking to try and create a new Powershell pipeline and execute a script within it, then get the output it produces into an output variable, but I can't get any output produced from within the object (from the executed script). The whole point of this is so I don't have to manage the $Error object, which I intend to use for error detection. Here's an example below:

$ps = [Powershell]::Create()

$File = ".\Test2.ps1"
$SortedParams = "-Name blah -Key foo"
$RootDirectory = Get-Location
$ExecutionDirectory = "$RootDirectory\Test3"

$ps.AddCommand("Set-Location").AddParameter("Path", "$ExecutionDirectory")
write-host "COMMAND 1: " $ps.Commands.Commands.Item(0).CommandText

$ps.AddScript("$File $SortedParams")
write-host "COMMAND 2: " $ps.Commands.Commands.Item(1).CommandText

$output = $ps.Invoke()

write-host $output

I should mention that I'm trying to use the following 3 methods of producing output within the script executed:

  • Write-Host
  • Write-Output
  • Write-Verbose (used $ps.Streams.Verbose to try to get output, but nothing)

Any suggestions or tips you can give is much appreciated!

Was it helpful?

Solution

Unless you feel there's a specific need to do things the way you're doing them, you might want to look into using PowerShell background jobs instead.

Background jobs allow you to run PowerShell commands in a separate PowerShell instance and then collect the output from those jobs into a variable (if that's what you want to do).

Check out the about_Jobs help topic for more information.

Here's a quick example:

$job = Start-Job -ScriptBlock { "Hello World!" }
$ret = Receive-Job $job -Wait -AutoRemoveJob

# value of $ret will be "Hello World!"

OTHER TIPS

You can call another script with the Invoke-Expression cmdlet and capture its output using the -OutVariable parameter. I recommend using the Out-Null so that data doesn't populate to the console twice, feel free to remove that piped command. Here's an example:

Invoke-Expression -Command "c:\EventLog.ps1" -OutVariable $data | Out-Null

Write-Host $data

This is the code from the sample script I used in the above example:

Param($ComputerName = ".")

Get-EventLog -ComputerName $ComputerName -Log application -EntryType Error | 
    Group-Object -Property source | 
    Sort-Object -Property Count -Descending | 
    Format-Table Count, Name -AutoSize

Check your error stream for errors:

$ps.Streams.Error

This worked for me:

$ps = [Powershell]::Create()
cd 'C:\Users\Andy\Documents'
$File = ".\Test2.ps1"
$SortedParams = "-Name blah -Key foo"
$RootDirectory = Get-Location
$ExecutionDirectory = "$RootDirectory\Test3"
$ps.AddCommand("Set-Location").AddParameter("Path", "$ExecutionDirectory") | Out-Null
$ps.AddScript("$File $SortedParams") | Out-Null
$output = $ps.Invoke()
write-host $output

This shows my setup:

Show file organization:

Command: 

tree.com /F /A $ExecutionDirectory

Output: 

C:\USERS\ANDY\DOCUMENTS\TEST3
    Test2.ps1

Show script contents:

Command:

cat "$ExecutionDirectory\Test2.ps1"

Output: 

param (
    $Name,
    $Key
)
$Name
$Key

I'm using Invoke-Expression and this is the only solution working for me:

test2.ps

Invoke-Expression .\test1.ps1 | Tee-Object -Variable msg | Out-Null
write-host "Return: $msg"</code>

And test1.ps:

$hola="Testing"
$hola

Call:

C:\Test>powershell -ExecutionPolicy unrestricted -file test2.ps1
Return: Testing
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top