Write-Host => Export to a file Write-Host => Export to a file powershell powershell

Write-Host => Export to a file


Write-Host redirects the output only to the console.

You can use Write-Output and redirect to a file (> export.txt or pipe to Out-File export.txt)

In the extreme case when you absolutely need to redirect all output from a script, take a look to this cmdlet:

Start-TranscriptGet-Help Start-Transcript -full


In PowerShell script > export.txt is syntactic sugar for script | Out-File -path export.txt.

Write-Host sends the objects to the host, and it does not return any objects. This means no objects are piped to the Out-File cmdlet and nothing is written to the export.txt file. A workaround (in case you don't want to change your script) is to open a cmd console and redirect the PowerShell output using cmd console redirection.

C:\> powershell .\script.ps1 > .\export.txt


The usefulness of different approaches is largely going to be based on your use case, of course, but...

The "right" way to do this, I believe, if you have control of the scripts (and this is what I usually do, though admittedly I was looking for a shortcut today), is to "overload" Write-Host, so to speak, and then send everything you would've sent to Write-Host to this new function.

Just to stay with valid PowerShell verbs, I call mine Write-Feedback.

function Write-Feedback(){    param    (        [Parameter(Position=0,ValueFromPipeline=$true)]        [string]$msg,        [string]$BackgroundColor = "Yellow",        [string]$ForegroundColor = "Black"    )    process {        $msg | ForEach-Object {            Write-Host `                -BackgroundColor $BackgroundColor `                -ForegroundColor $ForegroundColor `                $_;        }    }}

So now you have a function that operates essentially identically to Write-Host, but you can easily control where the output goes. If you need to write to a file, you can edit Write-Feedback so that all of its calls now do whatever you need.

You could simply change the line to Write-Output, depending on if you're doing anything else down the pipeline...

...Write-Output $_;

You could send the output to the same file that you're piping the rest of the command to, but within the Write-Feedback function, even keeping the Write-Host too:

function Write-Feedback(){    param    (        [Parameter(Position=0,ValueFromPipeline=$true)]        [string]$msg,        [string]$BackgroundColor = "Yellow",        [string]$ForegroundColor = "Black"    )    process {        $msg | ForEach-Object {            Write-Host `                -BackgroundColor $BackgroundColor `                -ForegroundColor $ForegroundColor `                $_;            $_ | Out-File "./export.txt" -Append; # <<< or add a param to location        }    }}

Or if you have a few outliers where you don't want the Write-Feedback content to be piped to a file, you could add a new optional parameter that asks what to do with each specific Write-Feedback call that you switch off of -- and send to file, to Write-Host, to Write-Output, etc -- changing the default to what you usually want, and explicitly switching off of the new parameter where it's explicitly set.

Etc., etc. It's just soooo much easier to route all of your calls into a centralized clearinghouse for output in PowerShell. Then when you do change your mind, it's not a huge search and replace -- and replace back -- task.

I think the only pain here would be if you didn't want to send things down the pipeline, so Write-Output is out, but did want to ensure the file Write-Feedback wrote to was the same as what you've specified in the > export.txt from your example without editing Write-Feedback each time. I'm not sure if there's an easy way to do that.

But since you'd then already be one step removed from your "pipe step", that's probably not a legitimate use case.

Anyhow, the bottom line is to overload Write-Host and do whatever you want by editing in one place.