Today very simple trick to capture whole output from Powershell. Let’s see those files:
1.ps1
1 2 3 4 5 |
echo "1_1 STD OUT" write-host "1_2 HOST OUT" write-error "1_3 STD ERR" .\2.ps1 |
2.ps1
1 2 3 4 5 |
echo "2_1 STD OUT" write-host "2_2 HOST OUT" write-error "2_3 STD ERR" .\3.bat |
3.bat
1 2 3 4 5 |
echo "3_1 STD OUT" echo "3_2 STD ERR" 1>&2 echo "3_2 STD 3" 1>&3 cscript 4.vbs |
4.vbs
1 2 3 4 5 6 7 8 9 10 11 |
Wscript.Echo "4_1 STD OUT" Set fso = CreateObject ("Scripting.FileSystemObject") Set stdout = fso.GetStandardStream (1) Set stderr = fso.GetStandardStream (2) stdout.WriteLine "4_2 STD OUT" stderr.WriteLine "4_3 STD ERR" Set WshShell = CreateObject("WScript.Shell") Set WshShellExec = WshShell.Exec("5.exe") WScript.StdOut.Write WshShellExec.StdOut.ReadAll WScript.StdErr.Write WshShellExec.StdErr.ReadAll |
5.exe
1 2 3 4 5 6 7 8 9 10 |
#include <iostream> #include <cstdlib> int main() { std::cout << "5_1 STD OUT" << "\n"; std::cerr << "5_2 STD ERR" << "\n"; system("6.exe"); } |
6.exe
1 2 3 4 5 6 7 8 |
#include <iostream> #include <cstdlib> int main() { std::cout << "6_1 STD OUT" << "\n"; std::cerr << "6_2 STD ERR" << "\n"; } |
Let’s now run this with powershell:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
PS C:\Afish\Playground> .\1.ps1 1_1 STD OUT 1_2 HOST OUT C:\Afish\Playground\1.ps1 : 1_3 STD ERR At line:1 char:1 + .\1.ps1 + ~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,1.ps1 2_1 STD OUT 2_2 HOST OUT C:\Afish\Playground\2.ps1 : 2_3 STD ERR At C:\Afish\Playground\1.ps1:5 char:1 + .\2.ps1 + ~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,2.ps1 C:\Afish\Playground>echo "3_1 STD OUT" "3_1 STD OUT" C:\Afish\Playground>echo "3_2 STD ERR" 1>&2 "3_2 STD ERR" C:\Afish\Playground>echo "3_2 STD 3" 1>&3 "3_2 STD 3" C:\Afish\Playground>cscript 4.vbs Microsoft (R) Windows Script Host Version 5.812 Copyright (C) Microsoft Corporation. All rights reserved. 4_1 STD OUT 4_2 STD OUT 4_3 STD ERR 5_1 STD OUT 6_1 STD OUT 5_2 STD ERR 6_2 STD ERR |
Okay, we have all STD OUT and STD ERR streams. Let’s now try redirecting this to file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
PS C:\Afish\Playground> .\1.ps1 > out.txt 1_2 HOST OUT C:\Afish\Playground\1.ps1 : 1_3 STD ERR At line:1 char:1 + .\1.ps1 > out.txt + ~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,1.ps1 2_2 HOST OUT C:\Afish\Playground\2.ps1 : 2_3 STD ERR At C:\Afish\Playground\1.ps1:5 char:1 + .\2.ps1 + ~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,2.ps1 "3_2 STD ERR" 4_3 STD ERR 5_2 STD ERR 6_2 STD ERR |
File content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
1_1 STD OUT 2_1 STD OUT C:\Afish\Playground>echo "3_1 STD OUT" "3_1 STD OUT" C:\Afish\Playground>echo "3_2 STD ERR" 1>&2 C:\Afish\Playground>echo "3_2 STD 3" 1>&3 "3_2 STD 3" C:\Afish\Playground>cscript 4.vbs Microsoft (R) Windows Script Host Version 5.812 Copyright (C) Microsoft Corporation. All rights reserved. 4_1 STD OUT 4_2 STD OUT 5_1 STD OUT 6_1 STD OUT |
Okay, so standard output was redirected correctly but standard error and write-host was not. Let’s try this:
1 2 3 |
PS C:\Afish\Playground> .\1.ps1 2>&1 > out.txt 1_2 HOST OUT 2_2 HOST OUT |
File content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
1_1 STD OUT C:\Afish\Playground\1.ps1 : 1_3 STD ERR At line:1 char:1 + .\1.ps1 2>&1 > out.txt + ~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,1.ps1 2_1 STD OUT C:\Afish\Playground\2.ps1 : 2_3 STD ERR At C:\Afish\Playground\1.ps1:5 char:1 + .\2.ps1 + ~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,2.ps1 C:\Afish\Playground>echo "3_1 STD OUT" "3_1 STD OUT" C:\Afish\Playground>echo "3_2 STD ERR" 1>&2 .\3.bat : "3_2 STD ERR" At C:\Afish\Playground\2.ps1:5 char:1 + .\3.bat + ~~~~~~~ + CategoryInfo : NotSpecified: ("3_2 STD ERR" :String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError C:\Afish\Playground>echo "3_2 STD 3" 1>&3 "3_2 STD 3" C:\Afish\Playground>cscript 4.vbs Microsoft (R) Windows Script Host Version 5.812 Copyright (C) Microsoft Corporation. All rights reserved. 4_1 STD OUT 4_3 STD ERR 4_2 STD OUT 5_1 STD OUT 6_1 STD OUT 5_2 STD ERR 6_2 STD ERR |
Okay, we have almost whole output in the file. Only write-host was not redirected. Can we do better?
The trick is to use CMD:
1 |
PS C:\Afish\Playground> cmd /c powershell.exe -file "1.ps1" 4>&1 3>&1 2>&1 > out.txt |
File content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
1_1 STD OUT 1_2 HOST OUT cmd : C:\Afish\Playground\1.ps1 : 1_3 STD ERR At line:1 char:1 + cmd /c powershell.exe -file "1.ps1" 4>&1 3>&1 2>&1 > out.txt + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (C:\Afish\Playground\1.ps1 : 1_3 STD ERR:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,1.ps1 2_1 STD OUT 2_2 HOST OUT C:\Afish\Playground\2.ps1 : 2_3 STD ERR At C:\Afish\Playground\1.ps1:5 char:1 + .\2.ps1 + ~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,2.ps1 C:\Afish\Playground>echo "3_1 STD OUT" "3_1 STD OUT" C:\Afish\Playground>echo "3_2 STD ERR" 1>&2 "3_2 STD ERR" C:\Afish\Playground>echo "3_2 STD 3" 1>&3 "3_2 STD 3" C:\Afish\Playground>cscript 4.vbs Microsoft (R) Windows Script Host Version 5.812 Copyright (C) Microsoft Corporation. All rights reserved. 4_1 STD OUT 4_2 STD OUT 4_3 STD ERR 5_1 STD OUT 6_1 STD OUT 5_2 STD ERR 6_2 STD ERR |
Now we have everything in file. How to see it in the console as well?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
PS C:\Afish\Playground> cmd /c powershell.exe -file "1.ps1" 4>&1 3>&1 2>&1 | Tee-Object -FilePath out.txt 1_1 STD OUT 1_2 HOST OUT cmd : C:\Afish\Playground\1.ps1 : 1_3 STD ERR At line:1 char:1 + cmd /c powershell.exe -file "1.ps1" 4>&1 3>&1 2>&1 | Tee-Object -File ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (C:\Afish\Playground\1.ps1 : 1_3 STD ERR:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,1.ps1 2_1 STD OUT 2_2 HOST OUT C:\Afish\Playground\2.ps1 : 2_3 STD ERR At C:\Afish\Playground\1.ps1:5 char:1 + .\2.ps1 + ~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,2.ps1 C:\Afish\Playground>echo "3_1 STD OUT" "3_1 STD OUT" C:\Afish\Playground>echo "3_2 STD ERR" 1>&2 "3_2 STD ERR" C:\Afish\Playground>echo "3_2 STD 3" 1>&3 "3_2 STD 3" C:\Afish\Playground>cscript 4.vbs Microsoft (R) Windows Script Host Version 5.812 Copyright (C) Microsoft Corporation. All rights reserved. 4_1 STD OUT 4_3 STD ERR 4_2 STD OUT 5_1 STD OUT 6_1 STD OUT 5_2 STD ERR 6_2 STD ERR |
File output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
1_1 STD OUT 1_2 HOST OUT cmd : C:\Afish\Playground\1.ps1 : 1_3 STD ERR At line:1 char:1 + cmd /c powershell.exe -file "1.ps1" 4>&1 3>&1 2>&1 | Tee-Object -File ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (C:\Afish\Playground\1.ps1 : 1_3 STD ERR:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,1.ps1 2_1 STD OUT 2_2 HOST OUT C:\Afish\Playground\2.ps1 : 2_3 STD ERR At C:\Afish\Playground\1.ps1:5 char:1 + .\2.ps1 + ~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,2.ps1 C:\Afish\Playground>echo "3_1 STD OUT" "3_1 STD OUT" C:\Afish\Playground>echo "3_2 STD ERR" 1>&2 "3_2 STD ERR" C:\Afish\Playground>echo "3_2 STD 3" 1>&3 "3_2 STD 3" C:\Afish\Playground>cscript 4.vbs Microsoft (R) Windows Script Host Version 5.812 Copyright (C) Microsoft Corporation. All rights reserved. 4_1 STD OUT 4_3 STD ERR 4_2 STD OUT 5_1 STD OUT 6_1 STD OUT 5_2 STD ERR 6_2 STD ERR |
Now it works correctly.