Antivirus detection

Has anyone created a scan that finds what virus software is installed on pcs.

You can find this info through WMI.

selects "* from AntiVirusProduct" of (if exists (wmi "root\SecurityCenter2") then (wmi "root\SecurityCenter2") else (wmi "root\SecurityCenter"))

Hey @jgstew… Looping back around to this. When I run the above on a WS2012 R2 server with McAfee VSE 8.8 installed, it gives me “Singular expression refers to nonexistent object”. Any ideas why this A/V would not be pulled from WMI?



Holy necro-thread, batman! But with Spectre/Meltdown patches needing AV, no surprise that this is a necessary topic.

Singular expression errors usually occur when you try to enumerate something that does not exist. In this case, check if the root\SecurityCenter or root\SecurityCenter2 namespaces actually exist, and if they do, that the AntiVirusProduct class exists.

Here’s a couple queries to get you started if you want to use Relevance; alternatively, you can use something like WMIExplorer to manually check the namespaces and classes.

Q: exists wmis ("root\SecurityCenter";"root\SecurityCenter2")

Q: exists selects "* from AntiVirusProduct" of wmis ("root\SecurityCenter";"root\SecurityCenter2")

Q: selects "* from AntiVirusProduct" of wmis ("root\SecurityCenter";"root\SecurityCenter2")

Note that with WMI you can easily run into Windows errors, especially if trying to query classes or namespaces that do not exist. Plenty of topics about that on here, though.

1 Like

Lol, “necro-thread”! Thanks for the info, @mwolff…

So; I understand how querying WMI works, was more looking for background info on why not all AVs - or namespaces/classes - would be present/created for all AV products.
Querying this would be really useful if it worked for all products, but it does not appear to:

Q: exists wmis ("root\SecurityCenter";"root\SecurityCenter2")
A: False
T: 2.227 ms

Q: exists selects "* from AntiVirusProduct" of wmis ("root\SecurityCenter";"root\SecurityCenter2")
A: False
T: 2.285 ms

Q: selects "* from AntiVirusProduct" of wmis ("root\SecurityCenter";"root\SecurityCenter2")
T: 3.358 ms

Any idea why these don’t get written to WMI? This relevance would be really useful if it pulled any AV, but apparently we would need to extend this relevance to look at other AV attributes in order to have one RP to pull an overview of what AV is installed on any given machine… Thoughts?


I just ran this relevance on 40% of our Windows endpoints using BigFix Query Tester, and got a mix of the following (we are predominantly on one product, but I also manage various colos and acquired companies, hence the variation):
Avast Antivirus
McAfee VirusScan Enterprise
Microsoft Forefront Endpoint Protection
System Center Endpoint Protection
The expression could not be evaluated: Windows Error 0x800401f0: CoInitialize has not been called.
Windows Defender

Given that I can pull MVSE results from WMI on what looks like Server 2012, Server 2012R2, and Server 2016, I don’t think this is an IBM or BigFix issue. I don’t even think this is a Microsoft issue, in-so-far as the functionality seems to work OK in my case.

This could simply be a WMI issue on that particular system. Have you tried running the relevance on other endpoints that are similarly configured? I would also check the WMI namespaces manually with WMIExplorer, at this point, since the namespace should exist and everything you’re getting indicates that the namespaces simply aren’t there.

1 Like

Yeah, it works a lot of the time, just not all of the time. McAfee especially seems to be hit or miss. I’ll analyse further and see if I can pinpoint the issue. Thanks.


Definitely let us know what you find. Some WMI failures are expected, especially with specific namespaces (I see this too often with SCCM/SMS and SQL namespaces), but they should be few and far between.

I often see namespace issues that I believe result from the BES client using 32-bit WMI queries. Some namespaces, especially custom namespaces, don’t get populated into 32-bit areas. As yet, there is no equivalent “x64 wmi” or “native wmi” set of inspectors as there are for the filestem or registry inspectors.
Keep that in mind when troubleshooting, it’s worth trying the wmic.exe clients from both the system32 and the syswow64 directories.

1 Like

You could have a task that calls this using the wow redirection false and outputs the results to see if it is in WMI but not being picked up by the WMI inspector.

Seems like this is something that might require a platform enhancement to add a new WMI x64 inspector or to make the existing one work with both.

This is how I would do this now. The relevance I wrote long ago in this post is not how I would do it anymore, though in this case the issue is greater than just the relevance it seems.

Ran into this while working on antivirus detection fixlet. I tried wmic.exe from both System32\wbem and SysWow64\wbem folders and it just says invalid namepace for both SecurityCenter and SecurityCenter2.

I created a property with
unique values of string values of selects "displayname from AntiVirusProduct" of ((wmis "root\SecurityCenter2");(wmis "root\SecurityCenter"))

and the only systems coming up with a value are all Win7 and Win10. Lot of Win2k12 servers have McAfee installed on our environment and they show up as <error>

1 Like

Nevermind. These namespaces are only available for desktop operating systems. Came across this after i posted.

I played around with your property a little bit and found in my environment that it reported Windows Defender on many Windows computers, as well as the installed AV. Given that I don’t particularly care about Windows Defender showing up as long as there’s another AV, I’m using this:

(if number of elements of it >= 2 then elements whose (it != "Windows Defender") of it else elements of it) of (set of string values of selects "displayname from AntiVirusProduct" of ((wmis "root\SecurityCenter2");(wmis "root\SecurityCenter")))

@JasonWalker & @jgstew, I am looking at implementing a similar piece of relevance and it also returns multiple entries. Too me it looks like the entry with the newest timestamp is the active Antivirus. Is there a way through relevance to return just the newest entry? Also, “item 2” of the tuple returns with parentheses around it. First off why is that, when the others do not and is there a way to return the value without it?

(item 0 of it, item 2 of it, "Is Antivirus: " & bit 18 of item 1 of it as string, "On Access Scanning: " & bit 12 of item 1 of it as string, "Auto-Update: " & bit 17 of item 1 of it as string, "Out of date: " & bit 3 of item 1 of it as string) of (string value of property “displayName” of it, string value of property “productState” of it as integer as bit set, string value of property “timestamp” of it ) of select objects “* from AntiVirusProduct” of ((wmis “root\SecurityCenter2”);(wmis “root\SecurityCenter”))

Any string with commas in it will display wrapped in parentheses in the Fixlet Debugger, to distinguish that it is “one item” and not “multiple tuple items”. Just a display thing, if you were writing to a file in an action or something like that it wouldn’t have the parentheses.

You can filter to just the latest timestamp but you’d have to run the query twice - once to find the latest timestamp, and again to filter to the one result matching the latest timestamp.
I know we have the logic for that here somewhere - will try to find it.
I think the context that’s been posted before has been around finding the latest version among multiple registry entries, like the latest of several installed Java versions.

Thank you I will look at this.