I have a PowerShell Script that is importing a module and I am calling this module. However, this module has lots of useful output that I am not capturing and I would like to write it to a file. What is the best way to do this?
Example code:
Write-Host "Loading modules.." -ForegroundColor Cyan
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\cleanupFile.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Get-FullFilePath.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Initialize-DiskPartition.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Initialize-VHDPartition.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\MountVHDandRunBlock.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\New-TemporaryDirectory.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Run-Executable.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Set-DiskPartition.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Set-VHDPartition.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Wim2VhdClass.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\cleanupFile.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\Public\Convert-Wim2VHD.ps1
try
{
Write-Host "========================== Creating VHDX ================================== "
Convert-WIM2VHD -Path ".\os_1.vhdx" -SourcePath ".\os_1.wim" -Size 16GB -force -DiskLayout UEFI
# How to send output from imported module to a "_Convert-WIM2VHD.log"
# Example: powershell -Command "Start-Process 'powershell.exe' -Wait -ArgumentList '-ExecutionPolicy Bypass -Command \"...?
}
catch
{
Write-Host $Error[0]
Write-Host $Error[0].Exception.GetType().FullName
What is the best way to get all the output from Convert-WIM2VHD to _Convert-WIM2VHD.log?
From inside PowerShell:
To capture output only in a file, use a redirection: to capture output from all PowerShell output streams, use
*>
To also capture output in a file, while still outputting it (to the success output stream, which prints to the display by default), use
Tee-Object
; combine with a*>&1
redirection in order to capture all streams:[1]To also capture output from an entire script or session, use
Start-Transcript
andStop-Transcript
:In a
Start-Process
call, the only way to capture any output is in files, namely via-RedirectStandardOutput
and-RedirectStandardError
, but note:There's usually no reason to use
Start-Process
to invoke console applications - see this answer; GitHub docs issue #6239 provides guidance on when use ofStart-Process
is and isn't appropriate.Capturing combined stdout and stderr output isn't directly possible, though when calling the PowerShell CLI, specifically, even PowerShell error output is sent to stdout (see below). For other programs, you'd have to call via a shell (such as PowerShell) in order to merge the streams - see this answer.
From outside PowerShell, when calling the the PowerShell CLI (
powershell.exe
for Windows PowerShell,pwsh
for PowerShell (Core) 7+):Because the PowerShell CLI sends all its output streams to stdout - including the error stream - a simple
>
redirection from a calling shell (e.g.cmd.exe
, Bash) is sufficient; e.g.:2>
), PowerShell's error stream is sent to stderr (but none of the other non-sucesss streams).Note: While this send-everything-to-stdout-by-default behavior happens to be convenient for this use case, it is generally problematic: arguably, all streams other than the success output stream should be sent to stderr - see GitHub issue #7989.
Character-encoding considerations, i.e. what character encoding is used in the output files:
From inside PowerShell:
>
, as an effective alias ofOut-File
, uses the latter's default encoding:Out-File
explicitly, with its-Encoding
parameter (but then you cannot combine it withTee-Object
).Tee-Object
with-FilePath
uses:-Encoding
parameter can be used to change that.Start-Object
with-RedirectStandardOutput
and-RedirectStandardOutput
:From outside PowerShell:
On Windows, the PowerShell CLI (in both editions) uses the console window's output code page (as reported by
chcp
), which defaults to the system's active legacy OEM code page, such as437
on US-English systems.chcp 65001
); since Windows 10 it is also possible to configure a system to use UTF-8 system-wide, in which case both the OEM and the ANSI code page are set to65001
(UTF-8). However, this has far-reaching consequences in that it can change the behavior of existing console applications and PowerShell scripts; see this answer for details as well as a PowerShell-only alternative.Un Unix-like systems, the PowerShell CLI (
pwsh
, the PowerShell (Core) CLI) invariably outputs (BOM-less) UTF-8-encoded text.[1] Note that this by design merges all streams into the success output stream (which is what makes it possible for
Tee-Object
to see all output) and therefore "pollutes" the latter; for display output that doesn't matter, however.