开发者

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

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
"d开发者_运维知识库oing step {0}" -f 2 | mylog
"doing step {0}" -f 3 | mylog

#in the end of the script
$script:output


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.


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 or view it online here:

PS > ($var=1)
1
PS >


I haven't messed with powershell enough to give a concrete answer, but if I were to do this in C I would exploit side effects.

//Psuedo-C
string con (oldString, newString) {
  print(newString);
  return oldString + newString;
}

Use function like so:

myString = con(myString, "Process started");

It would have the desired effect. (leaving aside correct C syntax and pedantry such as dealing with newlines) I don't know how to translate this to powershell.

What you want to do may be considered messy however. It might be clearer if you just explicitly output and log output and log one after the other in your code. Side effects inevitably come back to bite you. Keep things modular.


I was looking at something similar to this, with the exception I did not need to analyze it afterwards, just collect the output.

Something someone else might look at since it seems you have your answer is using PowerShell transcripts (Start-Transcript and Stop-Transcript).I found from this site that it does have some issues when you hit a server error, but he shows how he handled it.


To expand a bit on @manojlds answer, you can simply use the Tee-Object cmdlet, but rather than specifying a file for it to write to, you can tell it to write directly to a variable, like so:

.\test.ps1 | Tee-Object -Variable output

All of the output from the script/cmdlet/function/etc will be written to the console screen in real-time, as well as stored in the $output variable when the script finishes running. So you could then analyze it or write it to a file using that variable. This avoids you having to read the file contents into a variable after the operation completed.


Script will write data on output screen as well as store the same data in variable

get-process | Tee-Object -Variable test

$test can use further 


("Process started" | out-host) | Set-Variable x ; $x
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜