I am trying to scan the CBS log file for a certain string of words and then clean up the registry but I am receiving a null value error. I am having trouble matching on the (ERROR_SXS_ASSEMBLY_MISSING) part that does exist in the log file inside parentheses, but does not contain the '
symbol/mark.
Here is the full code:
#Read CBS log file contents into memory
try {$Contents = [System.IO.File]::ReadLines('C:\Windows\Logs\CBS\CBS.log')} catch {"File is currently in use. Re-run script in 2 minutes.";return}
#Parse log file for missing assemblies
$InterestingLines = $Contents | Select-String -SimpleMatch '(ERROR_SXS_ASSEMBLY_MISSING)'
#Retrieve unique Package names from error messages
$Packages = @()
foreach ($Line in $InterestingLines) {
$Package = [regex]"^([\w\s\.\-\(\)]+)$".Substring(0,$Package.Length - ($Package.split(".")[4]).Length - 1)
if ($Packages -notcontains $Package) { $Packages += $Package }
}
$AllKeys = @('HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackageDetect', 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages')
foreach ($RegRoot in $AllKeys) {
$Keys = Get-ChildItem $RegRoot | where {$_.PSIsContainer}
foreach ($Key in $Keys) {
#write-host "Checking $($Key.name)" -ForegroundColor Blue
foreach ($Package in $Packages) {
foreach ($Property in $Key.Property) {
#write-Host "$Property ? $Package" -ForegroundColor blue
if ($Property -match $Package) {
$ShortTarget = $($Key.Name).Substring(87)
write-host "Found $Package in $ShortTarget... " -ForegroundColor Yellow -NoNewline
$Target = $($Key.Name).TrimStart("HKEY_LOCAL_MACHINE\\")
try {
# Attempt to give Admins full control of key and delete key.
$key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($Target,[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
$acl = $key.GetAccessControl()
$rule = New-Object System.Security.AccessControl.RegistryAccessRule ("BUILTIN\Administrators","FullControl","Allow")
$acl.SetAccessRule($rule)
$key.SetAccessControl($acl)
Remove-ItemProperty -Path "HKLM:\$Target" -Name $Package -Force
Write-Host "delete successful." -ForegroundColor Green
} catch {
Write-Host "delete failed. Delete manually." -ForegroundColor Red
}
}
}
}
}
}
You cannot call a method on a null-valued expression.
At line:4 char:19
+ $Package = $(($Line -split("'") )[1]).Substring(0,$Package.Lengt ...
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
'Package_5287_for_KB4525236~31bf3856ad364e35~amd64~~10.0.1.5.4525236-9034_neutral', rah = '2', manpath = (null), catpath = (null), ed = 0, disp = 0)[gle=0x80073701]
2021-05-09 16:42:50, Info CBS Failed to pin deployment while resolving Update: Package_5287_for_KB4525236~31bf3856ad364e35~amd64~~10.0.1.5.4525236-9034_neutral from file: (null) [HRESULT = 0x80073701 - ERROR_SXS_ASSEMBLY_MISSING]
2021-05-09 16:42:50, Info CBS Failed to bulk stage deployment manifest and pin deployment for package:Package_8014_for_KB5001347~31bf3856ad364e35~amd64~~10.0.1.4 [HRESULT = 0x80073701 - ERROR_SXS_ASSEMBLY_MISSING]
2021-05-09 16:42:50, Info CBS CommitPackagesState: Started persisting state of packages
2021-05-09 16:42:50, Info CBS Not able to add poqexec.log to Windows Error Report. [HRESULT = 0x80070002 - ERROR_FILE_NOT_FOUND]
2021-05-09 16:42:50, Error CSI 00000009 (F) STATUS_SXS_ASSEMBLY_MISSING #33584# from CCSDirectTransaction::OperateEnding at index 0 of 1 operations, disposition 2[gle=0xd015000c]
2021-05-09 16:42:50, Error CSI 0000000a (F) HRESULT_FROM_WIN32(ERROR_SXS_ASSEMBLY_MISSING) #33432# from Windows::ServicingAPI::CCSITransaction::ICSITransaction_PinDeployment(Flags = 0, a = c39e63ddd18df5c405b8f3627f4d40eb, version 10.0.14393.2608, arch amd64, nonSxS, pkt {l:8 b:31bf3856ad364e35}, cb = (null), s = (null), rid = 'Package_5287_for_KB4525236~31bf3856ad364e35~amd64~~10.0.1.5.4525236-9034_neutral', rah = '2', manpath = (null), catpath = (null), ed = 0, disp = 0)[gle=0x80073701]
I'm not 100% sure what exactly are you trying to match / extract from the CBS.log so I will assume what you want to get is the Name of the Package
up until the ~
symbol on those lines where the string ERROR_SXS_ASSEMBLY_MISSING
appears.
So I have captured both examples of the logs you have added to your question into an array which is something similar to what [System.IO.File]::ReadLines('C:\Windows\Logs\CBS\CBS.log')
is doing in your code.
Looks like this:
'Package_5287_for_KB4525236~31bf3856ad364e35~amd64~~10.0.1.5.4525236-9034_neutral', rah = '2', manpath = (null), catpath = (null), ed = 0, disp = 0)[gle=0x80073701]
2021-05-09 16:42:50, Info CBS Failed to pin deployment while resolving Update: Package_5287_for_KB4525236~31bf3856ad364e35~amd64~~10.0.1.5.4525236-9034_neutral from file: (null) [HRESULT = 0x80073701 - ERROR_SXS_ASSEMBLY_MISSING]
2021-05-09 16:42:50, Info CBS Failed to bulk stage deployment manifest and pin deployment for package:Package_8014_for_KB5001347~31bf3856ad364e35~amd64~~10.0.1.4 [HRESULT = 0x80073701 - ERROR_SXS_ASSEMBLY_MISSING]
2021-05-09 16:42:50, Info CBS CommitPackagesState: Started persisting state of packages
2021-05-09 16:42:50, Info CBS Not able to add poqexec.log to Windows Error Report. [HRESULT = 0x80070002 - ERROR_FILE_NOT_FOUND]
2021-05-09 16:42:50, Error CSI 00000009 (F) STATUS_SXS_ASSEMBLY_MISSING #33584# from CCSDirectTransaction::OperateEnding at index 0 of 1 operations, disposition 2[gle=0xd015000c]
2021-05-09 16:42:50, Error CSI 0000000a (F) HRESULT_FROM_WIN32(ERROR_SXS_ASSEMBLY_MISSING) #33432# from Windows::ServicingAPI::CCSITransaction::ICSITransaction_PinDeployment(Flags = 0, a = c39e63ddd18df5c405b8f3627f4d40eb, version 10.0.14393.2608, arch amd64, nonSxS, pkt {l:8 b:31bf3856ad364e35}, cb = (null), s = (null), rid = 'Package_5287_for_KB4525236~31bf3856ad364e35~amd64~~10.0.1.5.4525236-9034_neutral', rah = '2', manpath = (null), catpath = (null), ed = 0, disp = 0)[gle=0x80073701]
If you were to extract for example, the Date & Time
and the Name of the Package
from each line you could use something like this (bear with me, I'm nowhere near a regex
expert):
$regex = [regex]'\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}|Package_\d+_for_KB\d+(?=~)'
$result = foreach($line in $log | Select-String 'ERROR_SXS_ASSEMBLY_MISSING')
{
$isMatch = $regex.Matches($line)
if($isMatch)
{
[PScustomObject]@{
Date = $isMatch[0].Value
Package = $isMatch[1].Value
}
}
}
This would return an object that looks like this:
PS /> $result
Date Package
---- -------
2021-05-09 16:42:50 Package_5287_for_KB4525236
2021-05-09 16:42:50 Package_8014_for_KB5001347
2021-05-09 16:42:50 Package_5287_for_KB4525236
Which then is easy to manipulate. i.e: checking if the package is duplicate:
PS /> $result.Package | Select-Object -Unique
Package_5287_for_KB4525236
Package_8014_for_KB5001347
User contributions licensed under CC BY-SA 3.0