I'm working on a powershell script in which several commands output are shown in the window and appended to a file or a variable. It worked correctly until I used the sfc
command. When piped or redirected, the output is "broken":
> sfc /?
Vérificateur de ressources Microsoft (R) Windows (R) version 6.0[...]
> sfc /? | Tee-Object -Variable content
V Ú r i f i c a t e u r d e r e s s o u r c e s M i c r o s o f t ( R ) W i n d o w s ( R ) v e r s i o á 6 . 0[...]
Are there other commands like sfc
that are formatted in the same way, or that will result in a broken output if redirected?
EDIT
Powershell
sample code, using the code from the accepted answer:
# Run a command
function RunCommand([ScriptBlock] $command) {
# Run the command and write the output to the window and to a variable ("SFC" formatting)
$stringcommand = $command.ToString()
if (
$stringcommand -match "^SFC$" -or
$stringcommand -match "^SFC.exe$" -or
$stringcommand -match "^SFC .*$" -or
$stringcommand -match "^SFC.exe .*$"
) {
$oldEncoding = [console]::OutputEncoding
[console]::OutputEncoding = [Text.Encoding]::Unicode
$command = [ScriptBlock]::Create("(" + $stringcommand + ")" + " -join ""`r`n"" -replace ""`r`n`r`n"", ""`r`n""")
& ($command) 2>&1 | Tee-Object -Variable out_content
[console]::OutputEncoding = $oldEncoding
# Run the command and write the output to the window and to a variable (normal formatting)
} else {
& ($command) 2>&1 | Tee-Object -Variable out_content
}
# Manipulate output variable, write it to a file...
# ...
return
}
# Run commands
RunCommand {ping 127.0.0.1}
RunCommand {sfc /?}
[void][System.Console]::ReadKey($true)
exit
CMD
sample code, using more
to format the sfc
output:
@echo off
setlocal enabledelayedexpansion
set "tmpfile=%TEMP%\temp.txt"
set "outputfile=%TEMP%\output.txt"
REM; Run commands
call :RunCommand "ping 127.0.0.1"
call :RunCommand "sfc"
pause
exit /b
REM; Run a command
:RunCommand
REM; Run the command and write the output to the window and to the temp file
set "command=%~1"
(!command! 2>&1) >!tmpfile!
REM; Write the output to the window and to the output file ("SFC" formatting)
set "isSFC=0"
(echo !command!|findstr /I /R /C:"^SFC$" > NUL) && (set "isSFC=1")
(echo !command!|findstr /I /R /C:"^SFC.exe$" > NUL) && (set "isSFC=1")
(echo !command!|findstr /I /R /C:"^SFC .*$" > NUL) && (set "isSFC=1")
(echo !command!|findstr /I /R /C:"^SFC.exe .*$" > NUL) && (set "isSFC=1")
(if !isSFC! equ 1 (
(set \n=^
%=newline=%
)
set "content="
(for /f "usebackq tokens=* delims=" %%a in (`more /p ^<"!tmpfile!"`) do (
set "line=%%a"
set "content=!content!!line!!\n!"
))
echo.!content!
(echo.!content!) >>!outputfile!
REM; Write the output to the window and to the locked output file (normal formatting)
) else (
type "!tmpfile!"
(type "!tmpfile!") >>!outputfile!
))
goto :EOF