I am stuck on this Powershell script giving me a null value error when trying to scan the CBS log file and registry for errors

0

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]
powershell
logging
null
registry
asked on Stack Overflow May 9, 2021 by Joe W • edited May 10, 2021 by Joe W

1 Answer

0

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
answered on Stack Overflow May 10, 2021 by Santiago Squarzon

User contributions licensed under CC BY-SA 3.0