Parsing Scheduled Task XML

Ok, possibly a bit of both UTF-16 encoding, as well as xpath namespace issues.

I saved your file with notepad++ on my test machine. Being notepad++, it saved the file in UTF-8 encoding, which does not match the XML data type defined and won’t load directly as an XML document. (FWIW, I also have an XML plugin that warned me the data was invalidly-encoded when I tried to save it)

q: lines of file "c:\temp\setupdiagresults.xml"
A: <?xml version="1.0" encoding="utf-16"?>
A: <SetupDiag xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://docs.microsoft.com/en-us/windows/deployment/upgrade/setupdiag">
A:   <Version>1.6.0.0</Version>
A:   <ProfileName>FindRollbackFailure</ProfileName>
A:   <ProfileGuid>3A43C9B5-05B3-4F7C-A955-88F991BB5A48</ProfileGuid>
A:   <FailureData>Error: SetupDiag reports rollback failure found.Last Phase = Pre First BootLast Operation = Setup the recovery partitionError = 0xC1900101-0x30004</FailureData>
A:   <FailureData>LogEntry: </FailureData>
A:   <FailureData>Refer to "https://docs.microsoft.com/en-us/windows/desktop/Debug/system-error-codes" for error information.</FailureData>
A:   <FailureDetails>RollbackErrorCode = 0xC1900101, ExtendedCode = 0x30004, LastOperation = Setup the recovery partition, LastPhase = Pre First Boot</FailureDetails>
A:   <SetupPhaseInfo>
A:     <PhaseName>Pre First Boot</PhaseName>
A:     <PhaseStartTime>9/28/2021 12:16:06 AM</PhaseStartTime>
A:     <PhaseEndTime>1/1/0001 12:00:00 AM</PhaseEndTime>
A:     <PhaseTimeDelta>0:00:00:00.0000000</PhaseTimeDelta>
A:     <CompletedSuccessfully>false</CompletedSuccessfully>
A:   </SetupPhaseInfo>
A:   <SetupOperationInfo>
A:     <OperationName>Setup the recovery partition</OperationName>
A:     <OperationStartTime>9/28/2021 12:16:06 AM</OperationStartTime>
A:     <OperationEndTime>1/1/0001 12:00:00 AM</OperationEndTime>
A:     <OperationTimeDelta>0:00:00:00.0000000</OperationTimeDelta>
A:     <CompletedSuccessfully>false</CompletedSuccessfully>
A:   </SetupOperationInfo>
A: </SetupDiag>
T: 12.973 ms
I: plural file line

The Fixlet Debugger won’t load the file as an XML document:

q: xml document of file "c:\temp\setupdiagresults.xml"
E: The expression could not be evaluated: XMLDomDocumentError: Switch from current encoding to specified encoding not supported.

However, I can read the file with the ‘lines of file’ inspector, concatenate them back together with the CR/LF end-of-line delimiter characters, and read the resulting string as an XML document:

q: xml document of concatenation "%0d%0a" of lines of file "c:\temp\setupdiagresults.xml"
E: This expression evaluates to an unrepresentable object of type "xml dom document"
T: 10.821 ms
I: singular xml dom document

As an XML document, I can get the node names of the the top-level of the document:

q: node names of child nodes of xpaths ("/") of xml document of concatenation "%0d%0a" of lines of file "c:\temp\setupdiagresults.xml"
A: xml
A: SetupDiag
T: 8.417 ms
I: plural string

But an xpath query for /SetupDiag fails…

q: node names of child nodes of xpaths ("/SetupDiag") of xml document of concatenation "%0d%0a" of lines of file "c:\temp\setupdiagresults.xml"
T: 5.904 ms
I: plural string

The trick there is with the namespace definitions at the top of the file. ‘SetupDiag’ isn’t just a node, it’s a node within a namespace xmlns=“https://docs.microsoft.com/en-us/windows/deployment/upgrade/setupdiag

<SetupDiag xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://docs.microsoft.com/en-us/windows/deployment/upgrade/setupdiag">

To query this with an ‘xpath’ definition, we can supply a mapping where we assign a “friendly name” for each namespace. In this case, I’ll assign the friendly name of “a” to map to the “https://docs.microsoft.com…” namespace. Then we have to reference nodes within that namespace as “a:NodeName”

q: node names of child nodes of xpaths ("xmlns:a='https://docs.microsoft.com/en-us/windows/deployment/upgrade/setupdiag'","/a:SetupDiag") of xml document of concatenation "%0d%0a" of lines of file "c:\temp\setupdiagresults.xml"
A: Version
A: ProfileName
A: ProfileGuid
A: FailureData
A: FailureData
A: FailureData
A: FailureDetails
A: SetupPhaseInfo
A: SetupOperationInfo
T: 6.293 ms
I: plural string

Here’s an example of querying for all of the “FailureDetails” and “FailureData” nodes, using the namespace-aware xpath query:

q: (node name of it, node values of child nodes of it) of xpaths ("xmlns:a='https://docs.microsoft.com/en-us/windows/deployment/upgrade/setupdiag'", ("/a:SetupDiag/a:FailureDetails";"/a:SetupDiag/a:FailureData")) of xml document of concatenation "%0d%0a" of lines of file "c:\temp\setupdiagresults.xml"
A: FailureDetails, ( RollbackErrorCode = 0xC1900101, ExtendedCode = 0x30004, LastOperation = Setup the recovery partition, LastPhase = Pre First Boot )
A: FailureData, Error: SetupDiag reports rollback failure found.Last Phase = Pre First BootLast Operation = Setup the recovery partitionError = 0xC1900101-0x30004
A: FailureData, LogEntry: 
A: FailureData, Refer to "https://docs.microsoft.com/en-us/windows/desktop/Debug/system-error-codes" for error information.
T: 3.465 ms
I: plural ( string, string )

@brolly33’s post at Xpath and node value woes describes how one could handle multiple namespaces within the same XML document

q: node values of xpath ("xmlns:a='http://schemas.microsoft.com/win/2004/08/events/event' xmlns:b='Event_NS'","/a:Event/a:UserData/b:EventXML/b:Param1/text()") of xml document of file "event.xml" of parent folder of client
A: ak166-cdss

For whatever it’s worth, this isn’t just a BigFix oddity, it’s an XPath thing; I have to do similar namespace definitions when I’m parsing XML with Python.

2 Likes