Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to output a string to variable and console at the same time

Tags:

powershell

is there an easy way in powershell to output a string to variable and console at the same time?

i want to capture the output of my script to a variable so i can analyze it in the end of the script, save it to a log file and also email to an operator.

my intent is to have a variable $output and add any output strings to it and also output to console immediately something like

$output="Process started"

$output=+"Doing step 1"
"Doing step 1"

$output=+"Doing step 2"
"Doing step 2"

so in the end I can save $output to a log file, email it and parse it.

I played with tee-object that might work for that purpose but unfortunately it would rewrite my $output variable instead of appending a string to it.

UPDATE This is the final solution I decided to go with - thanks to manojlds!

$script:output = ""

filter mylog {
    $script:output+= $_+"`n"
    return $_
}


"doing step {0}" -f 1 | mylog
"doing step {0}" -f 2 | mylog
"doing step {0}" -f 3 | mylog

#in the end of the script
$script:output
like image 771
mishkin Avatar asked Aug 17 '11 02:08

mishkin


2 Answers

There are so many ways to get your end goal:

In your script just have something like this:

"Process started"
<step1>
"Doing step 1"
<step2>
"Doing step 2"
...

Then run the script as

.\test.ps1 | Tee-Object -file log.txt

Note that the output is available to Tee-Object and hence the console as and when it occurs. You don't get the output only after the entire script runs. This is how pipeline works in Powershell. Objects are passed along downstream as and when they occur. Insert a sleep 10 in between as steps and see that the output comes as soon as it is available.

Also, you don't necessarily have to have another script ( the launcher.ps1 ) you are talking about. You can use functions, scriptblock etc. within your script.

Some other ways:

function test {

"Process started"
sleep 5
"Doing step 1"
sleep 5
"Doing step 2"

}

test | %{$output+=$_;$_}
#use output
write-host -fore blue $output

You can create a filter:

$script:output = ""

filter appendOutput {

    $script:output+= $_
    return $_
}

"Process started" | appendOutput
sleep 5
"Doing step 1" | appendOutput
sleep 5
"Doing step 2" | appendOutput
#use output
write-host -fore blue $script:output

There are probably many more ways of doing this.

like image 122
manojlds Avatar answered Oct 21 '22 07:10

manojlds


Here's a nice trick, enclose your variable assignment in parenthesis. You can find more on this in the PowerShell language specification (section 7.1.1 Grouping parentheses) available to download here :

PS > ($var=1)
1
PS >
like image 38
Shay Levy Avatar answered Oct 21 '22 06:10

Shay Levy