How can I determine whether an Antivirus product is installed?

We have a large installation with over 15,000 machines. They are supposed to have a version of Trend Micro installed; however, we don't know that for sure.

These are all Windows boxes which includes XP with various SP levels, Vista both RTM and SP1, and several 2000 and 2003 servers.

How can I determine:

  1. Whether ANY AV product is installed?
  2. What version of the product is installed?
  3. What version of the pattern file is on the box?

Ideas?

Thanks,


Since you're talking of 15,000 hosts, querying each of them from the network is going to be highly inefficient.

The Right Thing To Do™ then is to have a watchdog running on each host to make sure the appropriate software is installed and running. This watchdog might be a piece of software running as a service, a scheduled script or even hardware-based if you use something like Intel vPro.

To verify if an AV software is installed, you could use the following PowerShell command --

$avSoftware = get-wmiobject -class "Win32_Product" -namespace "root\cimv2" `
              -computername "." -filter "Name like '%antivirus%'"

Note that at the end you have a filter argument that you can customize to make sure you're looking at the right product.

After playing a bit with the like operator, you should be able to nail the antivirus description and minor variations here and there. Note that my example above (anything containing the word "antivirus") is pretty simplistic. You should instead look for specific patterns matching your approved antivirus software (e.g. "Trend Micro Antivirus%")

Anyway, the command above will return a collection of installed products that match your filter statement. From here you can test whether $avSoftware.Count is greater than zero, in which case you have antivirus software installed. The example below lists all the installed antivirus software --

if ($avSoftware.Count -gt 0) {
    foreach ($av in $avSoftware) {
        write-host $p.Name
    }
} else {
    write-host "No AV software found"
}

Instead of just printing a message saying that no AV has been found, you should obviously do something more useful, e.g.

  • Notify an admin
  • Install an AV from the network

You also said you'd like to get the version of the installed AV. To do that, you can use the Version property of the Win32_Process. Let's modify the above code like this to also print the version numbers for the installed software --

$avSoftware = get-wmiobject -class "Win32_Product" -namespace "root\cimv2" `
              -computername "." -filter "Name like '%antivirus%'"

foreach ($av in $avSoftware) {
    write-host $av.Name, $av.Version
}

As for the version of the installed virus definition files, you'd have to rely on each specific AV WMI interface. You'll have to consult the vendor's documentation for that.

One more thing to remember. It's probably not enough to know that the host has AV installed if the AV isn't running. After checking which AV is installed, you should make sure its process is running. To do that, you'll have to know what the appropriate process for each of your AV software is and look for them like this --

$processes = get-wmiobject -class "Win32_Process" -namespace "root\cimv2" `
             -computername "." -filter "Name = 'TeaTimer.exe'"

if ($processes.Count -gt 0) {
    foreach ($p in $processes) {
        write-host $p.Name
} else {
    # AV not running. Launch it here or notify someone 
}

The above example looks for the Spybot process (not exactly AV, but you get the picture), which is called "TeaTimer.exe". Modify it to look for your process instead.

Now, all of that said, if you're dealing with thousands of hosts like that, you should probably invest in some management tool (e.g. LANdesk, Microsoft System Center or Level Platforms.) These tools would make your life a whole lot easier.


In current versions of Windows (xp sp3+, vista, win 7) you can query the same WMI provider that Windows Security Center uses to know if an antivirus product installed and up-to-date.

Here's an example:

Set objSWbemServices = GetObject("winmgmts:\\.\root\SecurityCenter")
Set colFirewall = objSWbemServices.ExecQuery("Select * From antivirusProduct",,48)
For Each objAntiVirusProduct In colFirewall
  WScript.Echo "companyName: " & objAntiVirusProduct.companyName
  WScript.Echo "displayName: " & objAntiVirusProduct.displayName
  WScript.Echo "instanceGuid: " & objAntiVirusProduct.instanceGuid
  WScript.Echo "onAccessScanningEnabled: " & objAntiVirusProduct.onAccessScanningEnabled
  WScript.Echo "productUptoDate: " & objAntiVirusProduct.productUptoDate
  WScript.Echo "versionNumber: " & objAntiVirusProduct.versionNumber
Next

That said, not all antivirus products will register a WMI provider, but I suspect most of the popular ones will. Also, it's not clear if this is officially supported by Microsoft, so it might go away in future versions.

You might try it in combination with the other WMI suggestions here, falling back to scanning the installed products if the this doesn't work.


Since you mention Trend Micro, and we use Trend, here's what we do. A scheduled task does a full scan of the system and puts the results in a text file. Actually, it's a log file with the date as the name of the file... like 20090517.log in the C:\TRENDMICRO folder. Because this just has the results of the scan in it, it's a small file.

In our case with roughly 100 computers, it's easy enough for a powershell script on the server to walk through all the computers, and concatenate those files, and only look for the ones that didn't have the string "Virus found count(0)" in them. Obviously if that file and phrase isn't there, something is wrong: AV didn't run recently, Virus found, AV not installed, etc. You probably need something a little more fancy to scale it up.

But aren't there enterprise versions of AV that do it all for you instead of my poor man's version?


+1 for Knox regarding the enterprise version. I agree. Trend's enterprise desktop solution has a server piece that keeps track of clients and which scan engines and patterns they currently have. It also lets you deploy. I would use this to work toward your goal. Deploy a reinstall of OfficeScan using this. I wouldn't even bother with the effort of deploying scripts to figure out where you're at at this point in the game. Best to just start over. Work with Trend on the licensing if you don't already have the enterprise tools (which would really surprise me). If you don't then someone needs to account for poor purchasing decisions.