Dell Hardware Patches Analyses/Relevance

I get the same thing you got

file -i /var/opt/BESClient/Inventory.xml
/var/opt/BESClient/Inventory.xml: text/xml; charset=utf-16le

Oops, actually I'm not on RHEL8, with my sequence of hops I'm actually on an Ubuntu system.

Same error though, so I'm going to keep going.

Ok, looks like the XML library we're using on Ubuntu and probably RHEL does not support the contains() function in XPath expressions. The joys of cross-platform queries I suppose.

I've used xmllint and iconv to test out different file encodings and validate the XML, and it all looks correct.

I think you'll need to use the Relevance-based filtering method instead of the XPath filter to get around this.

Simpler demonstration below shows the error trying to use the contains() function:

Q: (node value of attribute "display" of it) of xpaths ("/SVMInventory/Device/Application") of xml document of file "/tmp/hw.xml"
A: BIOS
A: DSU
A: Power Supply
A: Power Supply
A: Firmware for  - Disk 0 of PERC H755 Front Controller 0
A: Firmware for  - Disk 1 of PERC H755 Front Controller 0
A: Firmware for  - Disk 2 of PERC H755 Front Controller 0
A: Firmware for  - Disk 3 of PERC H755 Front Controller 0
A: PERC H755 Front Controller 0 Firmware
A: Backplane Expander FW
A: Dell Connectivity Client
A: Integrated Dell Remote Access Controller
A: Intel(R) Ethernet 25G 2P E810-XXV OCP - 30:3E:A7:26:1B:74
A: Intel(R) Ethernet 25G 2P E810-XXV Adapter - B4:83:51:1F:D5:CE
A: Lifecycle Controller

Q: (node value of attribute "display" of it) of xpaths ("/SVMInventory/Device/Application[@display='Power Supply']") of xml document of file "/tmp/hw.xml"
A: Power Supply
A: Power Supply
T: 762

Q: (node value of attribute "display" of it) of xpaths ("/SVMInventory/Device/Application[contains(@display,'Power Supply')]") of xml document of file "/tmp/hw.xml"
E: The expression could not be evaluated: 19XmlDomDocumentError
T: 637

I was suprised to find this issue, usually our XML parsing is pretty excellent on Linux. Feel free to open a bug report on that.

In the meantime I think you can change to the Relevance-based filtering:

Q: (node value of attribute "display" of it) whose (it as string contains "Intel" or it as string contains "QLogic") of xpaths ("/SVMInventory/Device/Application") of xml document of file "/tmp/hw.xml"
A: Intel(R) Ethernet 25G 2P E810-XXV OCP - 30:3E:A7:26:1B:74
A: Intel(R) Ethernet 25G 2P E810-XXV Adapter - B4:83:51:1F:D5:CE
T: 770

Okay that works for the model but then how would you do it for the version. You can't do it as string. I tried this but it is saying operator "attribute" is not defined.

if (windows of operating system) then if (exists file "C:\Program Files (x86)\BigFix Enterprise\BES Client\Inventory.xml") then if (exists (node value of attribute "display" of it) of xpaths ("/SVMInventory/Device/Application[contains(@display, 'Intel') or contains(@display, 'QLogic')]") of xml document of file "C:\Program Files (x86)\BigFix Enterprise\BES Client\Inventory.xml") then ((node value of attribute "display" of it) of xpaths ("/SVMInventory/Device/Application[contains(@display, 'Intel') or contains(@display, 'QLogic')]") of xml document of file "C:\Program Files (x86)\BigFix Enterprise\BES Client\Inventory.xml") else "N/A" else "No file" else if (linux of operating system) then if (exists file "/var/opt/BESClient/Inventory.xml") then if (exists (node value of attribute "version" of it) whose (node value of attribute "display" of it as string contains "Intel" or node value of attribute "display" of it as string contains "QLogic") of xpaths ("/SVMInventory/Device/Application") of xml document of file "/var/opt/BESClient/Inventory.xml") then ((node value of attribute "version" of it) whose (node value of attribute "display" of it as string contains "Intel" or node value of attribute "display" of it as string contains "QLogic") of xpaths ("/SVMInventory/Device/Application") of xml document of file "/var/opt/BESClient/Inventory.xml") else "N/A" else "No file" else "Unsupported OS"

I maybe getting confused here - what do you want to show?
On the Windows portion of your query I think you're pulling 'display' but on the Linux side you're pulling 'version'.

We can retrieve either, or both, but if you can clarify what you want the final output to look like I can help...I will take my best guess in a few minutes

Here are a few variations on different ways to get the Display and Version, of nodes where the Display matches one of your strings.

All of these queries should work on both Windows and Linux; and display the 'No File' message on other operating systems - so you don't need to include if windows then () else () clause.

Option 1: Plurals, with empty results for "no file".

If we make everything plural, then machines where the file does not exist just return an empty result. This is the simplest, but cannot distinguish between 'a machine where the inventory has not run' versus 'a machine that has an inventory, but no Intel or QLogic devices'.

Q: (node value of attribute "display" of it, node value of attribute "version" of it) of xpaths ("/SVMInventory/Device/Application") whose (node value of attribute "display" of it as string contains "Intel" or node value of attribute "display" of it as string contains "Qlogic") of xml documents of files "Inventory.xml" of storage folder of client
A: Intel(R) Ethernet 25G 2P E810-XXV OCP - 30:3E:A7:26:1B:74, 24.0.5
A: Intel(R) Ethernet 25G 2P E810-XXV Adapter - B4:83:51:1F:D5:CE, 24.0.5

Option 2: with 'error' message.

When we use an If/Then/Else, the Then and Else must both return the same types - i.e. "two strings" on both. The exception is we can replace one of these with an error response type, which is valid to have different types versus the other option:

Q: if exist file "Inventory.xml" of storage folder of client then ((node value of attribute "display" of it, node value of attribute "version" of it) of xpaths ("/SVMInventory/Device/Application") whose (node value of attribute "display" of it as string contains "Intel" or node value of attribute "display" of it as string contains "Qlogic") of xml documents of files "Inventory.xml" of storage folder of client) else error "No File"
A: Intel(R) Ethernet 25G 2P E810-XXV OCP - 30:3E:A7:26:1B:74, 24.0.5
A: Intel(R) Ethernet 25G 2P E810-XXV Adapter - B4:83:51:1F:D5:CE, 24.0.5

Option 3: Coercing the (display, version) into a single string, so it can match the case of 'else'.

Q: if exist file "Inventory.xml" of storage folder of client then ((it as string) of (node value of attribute "display" of it, node value of attribute "version" of it) of xpaths ("/SVMInventory/Device/Application") whose (node value of attribute "display" of it as string contains "Intel" or node value of attribute "display" of it as string contains "Qlogic") of xml documents of files "Inventory.xml" of storage folder of client) else "No File"
A: Intel(R) Ethernet 25G 2P E810-XXV OCP - 30:3E:A7:26:1B:74, 24.0.5
A: Intel(R) Ethernet 25G 2P E810-XXV Adapter - B4:83:51:1F:D5:CE, 24.0.5

That works, thank you!

1 Like

Happy to help!

I am now looking to do a version check on the firmware basically if the version does not equal 52.30.0-6753 for the PERC make the relevance true if it does equal that then the relevance should be false. I thought I had it with the below but that is showing true no matter if it is that version or not.

((exists ((node value of attribute "version" of child nodes whose (node name of it = "Application") of it < "52.30.0-6753") of xpaths ("/SVMInventory/Device[@vendorID='1000']") of xml document of file "/var/opt/BESClient/Inventory.xml")))

I don't have the hardware to check this, but the problem is likely with your 'exists' and boolean comparsion.

The problem is, that True 'exists' and False also 'exists'.

q: exists True
A: True

q: exists False
A: True

q: ("2" < "1")
A: False

q: exists ("2" < "1")
A: True


q: exists ("1" < "2")
A: True

What I think is happening in your comparison is that where you are checking for the version -

(node value of attribute "version" of child nodes whose (node name of it = "Application") of it < "52.30.0-6753") 

...this part either returns True or False; but both of those answers 'exist', so the existence check always returns True. Incidentally I'd expect to get an error about a singular expression, if the XML document does not exist, but that's an aside.

I think you could change the check so that the logic is exists (node values whose (version check) of attributes.... In that case, the (node values whose(version check) will either return a the node value that matches the condition, or will return an empty value. The empty value triggers the False for exists check.

Again I don't have the test file but try

exists node values whose ( it as string as version < version "52.30.0-6753") of attributes "version" of child nodes whose (node name of it = "Application") of xpaths ("/SVMInventory/Device[@vendorID='1000']") of xml documents of files "/var/opt/BESClient/Inventory.xml"

That works thank you!

1 Like

Just a thought in case this situation may arise, if the build number increments but the major.minor.revision remain the same, using a version comparison may give a false negative.

Q: version "52.30.0-6753" < version "52.30.0-9998"
A: False
T: 0.027 ms
I: singular boolean

Q: version "52.30.0-6753"
A: 52.30.0
T: 0.028 ms
I: singular version

Wow, good point I was running on autopilot there.

There really isn't a good way to compare that; if we use the 'version' type, the '-6753' gets truncated.
But if we do a string comparsion, "2" evalutes as greater than "10" because it is a character-by-character comparison.

Maybe 1 approach is to replace the “-” with a “.” then cast as version could work on the nix style.

Q: version (concatenation "." of substrings separated by "-" of "52.30.0-6753")
A: 52.30.0.6753
T: 0.186 ms
I: singular version

Q: version (concatenation "." of substrings separated by "-" of "52.30.0-6753") < version (concatenation "." of substrings separated by "-" of "52.30.0-9998")
A: True
T: 0.095 ms
I: singular boolean

1 Like