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*>&1redirection in order to capture all streams:[1]To also capture output from an entire script or session, use
Start-TranscriptandStop-Transcript:In a
Start-Processcall, the only way to capture any output is in files, namely via-RedirectStandardOutputand-RedirectStandardError, but note:There's usually no reason to use
Start-Processto invoke console applications - see this answer; GitHub docs issue #6239 provides guidance on when use ofStart-Processis 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.exefor Windows PowerShell,pwshfor 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-Fileexplicitly, with its-Encodingparameter (but then you cannot combine it withTee-Object).Tee-Objectwith-FilePathuses:-Encodingparameter can be used to change that.Start-Objectwith-RedirectStandardOutputand-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 as437on 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-Objectto see all output) and therefore "pollutes" the latter; for display output that doesn't matter, however.