System File Checker and more with Windows 10

The System File Checker is a very useful tool for repairing/replacing vital Windows system files. Sometimes though, it is unable to do its job, and you have to go through the CBS.log file buried in the Windows directory. Here is the Microsoft KB article on using SFC and sifting through the cbs.log file. The command in the article for doing that

findstr /c:"[SR]" %windir%\Logs\CBS\CBS.log >"%userprofile%\Desktop\sfcdetails.txt"

will certainly do the job. But I decided to use the excuse to make a ramped up PowerShell version that does the same thing, with a few extra features, and using as many PowerShell commands as possible instead of command line or 3rd party (7zip being the exception). It is just something I whipped up in a few hours, so if anyone spots any bugs let me know.

##### Configurable script variables
[string]$cbsLogFilePath = $env:windir + "\Logs\CBS\CBS.log"
[string]$sfcLogFilePath = $env:USERPROFILE + "\Documents\SFC.log"
[long]$maxLogFilesizeBytes = 1048576
##### End of configurable script variables

[System.IO.FileInfo]$sfcLogObj = $null

# Checks to see if output log file exists and creates it if it does not
if(!(Test-Path $sfcLogFilePath)) {
 Write-Host ($sfcLogFilePath + " does not exist. Creating...")
 $sfcLogObj = New-Item $sfcLogFilePath -ItemType File
}
else {
 Write-Host ($sfcLogFilePath + " exists")
 $sfcLogObj = Get-Item $sfcLogFilePath
}

# Archive old SFC log file if current log file exceeds maxLogFilesizeBytes
if($sfcLogObj.Length -ge $maxLogFilesizeBytes) {
 Write-Host ($sfcLogObj.FullName + " is larger than " + $maxLogFilesizeBytes + " bytes. Archiving...")
 7za a -t7z -mx9 -mmt=on -y ($sfcLogObj.FullName + "." + (Get-Date -UFormat "%Y%m%d%H%M%S") + ".7z") $sfcLogObj.FullName
 if($LastExitCode -as [int] -gt 0) { Exit $LastExitCode } # Die with 7za's error number if it is above 0
 $sfcLogObj.Delete()
 $sfcLogObj = New-Item $sfcLogFilePath -ItemType File
}

# Append SFC log info scraped from CBS log file
Write-Host ("Scraping " + $cbsLogFilePath + " for SFC log entries...")
Get-Date -Format F | Out-File -FilePath $sfcLogObj.FullName -Append -Encoding utf8 
Select-String -Path $cbsLogFilePath -SimpleMatch "[SR]" -CaseSensitive | Out-File -FilePath $sfcLogObj.FullName -Append -Encoding utf8

This page by ZigZag3143 on the Microsoft community posts about using SFC as well, but it goes into extra depth of using the Deployment Image Servicing and Management tool (a.k.a. DISM) when SFC fails. And as a bit of an augment, over here on tenforums.com is an article that goes more into depth about using DISM, including using a mounted Windows ISO to grab files for DISM when even it fails under normal operation.

Leave a Reply