1

When running the sfc /scannow command from a powershell script, how do you trim the output to only keep all the data after "Verification 100% complete."?

Simple code example:

 $Result = Invoke-Command { sfc /scannow } | Out-String

A truncated version of this output is:

Verification 97% complete. 
Verification 98% complete.
Verification 98% complete.
Verification 99% complete.
Verification 99% complete.
Verification 100% complete.

Windows Resource Protection found corrupt files and successfully repaired them.

For online repairs, details are included in the CBS log file located at

windir\Logs\CBS\CBS.log. For example C:\Windows\Logs\CBS\CBS.log. For offline

repairs, details are included in the log file provided by the /OFFLOGFILE flag.

I also wouldn't mind removing the extraneous line breaks so the final output when returning $Result would simply be:

Windows Resource Protection found corrupt files and successfully repaired them. For online repairs, details are included in the CBS log file located at windir\Logs\CBS\CBS.log. For example C:\Windows\Logs\CBS\CBS.log. For offline repairs, details are included in the log file provided by the /OFFLOGFILE flag.

I have a 1024 character limit for the output, and right now I'm just truncating it with the following:

if ($Result.length -gt 1024) {
        $Result = $Result.Substring($Result.Length-1024)
    }

But I'd like to get rid of all the "status" type messaging from the output and just retain the final result of the scan.

Thank you!

zett42
  • 25,437
  • 3
  • 35
  • 72
sk8erord
  • 11
  • 3
  • What did you try to filter? Did you read the manual https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/out-string?view=powershell-7.2 ? (It includes an example that might help) – An-dir Oct 11 '22 at 17:46
  • ```$result = (sfc /scannow) -replace "`0" | where-object {$_ -and $_ -notmatch 'Verification'}``` think this helps – Toni Oct 11 '22 at 17:57
  • Thanks, this code worked perfectly. Can you help me understand what the `0 represents? My google skills apparently suck on this and I can't find an answer. – sk8erord Oct 11 '22 at 19:29
  • @sk8erord `0 represents null characters. A full list is here: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_special_characters – Cpt.Whale Oct 11 '22 at 20:22

1 Answers1

0

First and foremost this is an encoding issue. The sfc command outputs UTF-16, but PowerShell doesn't know that (because it's a native command), so you typically get embedded null characters between the actual characters (try sfc /? | Out-String | Format-Hex to see what I mean).

Removing the embedded null characters would only partially fix the symptoms. On non-english systems the encoding of non-ASCII characters will still be wrong.

To fix the cause, you have to tell PowerShell the output encoding used by the command (see this answer for background, albeit it focuses on UTF-8):

# Save the current encoding settings and temporarily switch to UTF-16 (aka UnicodeEncoding).
$oldOutputEncoding = $OutputEncoding; $oldConsoleEncoding = [Console]::OutputEncoding
$OutputEncoding = [console]::OutputEncoding = New-Object System.Text.UnicodeEncoding

# No need for Invoke-Command. Just call it directly.
$result = sfc /scannow | Out-String

# Restore the previous settings.
$OutputEncoding = $oldOutputEncoding; [Console]::OutputEncoding = $oldConsoleEncoding

# Encoding fixed, but duplicate newlines remain. Replace them by single newlines:
$result = $result -replace '\r?\n\r?\n', [Environment]::NewLine

#Finally strip off everything up to and including the `100%` line:
$result = ($result -replace '(?s)^.*100\s*%.*?\r?\n').Trim()

See this RegEx101 demo for an explanation of the RegEx used by the last -replace command. Note that (?s) enables single-line mode so dot . matches newlines.

zett42
  • 25,437
  • 3
  • 35
  • 72