0

I am trying to Write-Host message and save it to a variable in shortest possible way.

Currently my code looks like so:

Write-Host "Branch with name $branch_name already exists!`nNew branch has not been created."
$message = "Branch with name $branch_name already exists!`nNew branch has not been created."

And of course it works. I made a special function to compress this:

function Write-Host-And-Save([string]$message)
{
Write-Host $message
return $message
}

$message = Write-Host-And-Save "Branch with name $branch_name already exists!`nNew branch has not been created."

However it didn't make any output on screen. What is more I think there must be a better solution than new function to do it. And I tried to find one. Unsuccessfully.

Write-Host "Branch with name $branch_name already exists!`nNew branch has not been created." >> $message
Write-Host "Branch with name $branch_name already exists!`nNew branch has not been created." > $message
Write-Host "Branch with name $branch_name already exists!`nNew branch has not been created." -OutVariable $message

Is there any way to short-circuit that script?

Philippe
  • 28,207
  • 6
  • 54
  • 78
  • 3
    You can do this with `Write-Output` : `write-output "hi" -OutVariable message`. Then retrieve with `$message`. On PowerShell 5, you can use `write-host "branch with name" -InformationVariable message`. – AdminOfThings Dec 19 '19 at 12:39
  • Thank you. I guess I should study differences between Write-Output and Write-Host. Also I can see there is no dollar sign before variable name and I put one in my attempts to find a solution. – Mateusz Tryczyński Dec 19 '19 at 12:42
  • `write-host` will work depending on which version of PowerShell you are using. However, in that case, `write-host` is writing to the information stream rather than the success stream. I would not use `write-host` unless you are trying to mess with colored output to the screen: `write-host "branch with name" -InformationVariable message` – AdminOfThings Dec 19 '19 at 12:44

2 Answers2

3

On PowerShell 5+, you can achieve the desired behavior by utilizing Write-Host with the common parameter -InformationVariable. The following example stores the string value in $message.

Write-Host "Branch with name $branch_name already exists" -InformationVariable message

Explanation:

Starting with PowerShell 5, Write-Host became a wrapper for Write-Information. This means Write-Host writes to the information stream. Given that behavior, you can store its output into a variable using the -InformationVariable Common Parameter.


Alternatively, you can achieve similar results with Write-Output using the success stream and the common parameter -OutVariable.

Write-Output "Branch with name $branch_name already exists" -OutVariable message

Typically, I would be in favor of using Write-Output over Write-Host. It has a more synchronous behavior and uses the success stream, which is what you are intending to use here. Write-Host does provide the ability to easily color your console output though.

AdminOfThings
  • 23,946
  • 4
  • 17
  • 27
2

You can use Tee-Object which forwards its input down the pipeline aswell as saving it into a variable (or a file if desired):

"Some message" | Tee-Object -Variable message | Write-Host

You can also start with Write-Host:

Write-Host "Some message" 6>&1 | Tee-Object -Variable message

The 6>&1 redirects the information stream (6) where Write-Host writes to (as of Powershell 5.0), to the standard output stream (1). You may even use *>&1 to capture all streams.

In this case the final output would end up in the regular output stream though, so it doesn't answer your question exactly. It is just an example, how you can use Tee-Object for the general use case of capturing output to a variable while still outputting it to the console (or any cmdlet further down the pipeline).

zett42
  • 25,437
  • 3
  • 35
  • 72