Skip to main content

Query AV Product and Status

There is a mix of antivirus products I run into and was looking into a good way to report on which was installed/active. Unfortunately looking at a list of processes or installed applications is not accurate enough. The Windows Security Application shows which AV is on and its health. While this is a start, I dislike any answer that requires me to interact with the system in a manner that interrupts the customer unless I have to.

Doing some quick research I did find a few very useful articles that pointed out that this information can be queried with a WMI Instance.

Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct

displayName              : Windows Defender
instanceGuid             : {D68DDC3A-831F-4fae-9E44-DA132C1ACF46}
pathToSignedProductExe   : windowsdefender://
pathToSignedReportingExe : %ProgramFiles%\Windows Defender\MsMpeng.exe
productState             : 397568
timestamp                : Sat, 30 Dec 2023 03:30:13 GMT

If Defender is the only AV it is returned as the only output. Windows Security is able to query if there are current threats, issues with the protection settings, and if there are out of date updates that are missing. Many of the sites I found did say the productState property had the information but none had any official documentation as to what the mean or only had pieces of decoding it. The sources didn't agree on whether this value needed to be converted to a hex or binary value, both of which can be done easily enough.

$AV = Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct
[system.convert]::ToString($AV.productState,16) #Convert to Hexadecimal
[system.convert]::ToString($AV.productState,2) #Conver to Binary

With enough digging this was the most useful resource I found which will return the ProductName, ProductState, SignatureStatus, and Owner.

How To Tell What AntiVirus Software Installed on a Remote Windows Computer - NEXTOFWINDOWS.COM

Which in turn borrowed from Identifying Antivirus Engine State | IderaBlog.

# define bit flags
 
[Flags()] enum ProductState 
{
      Off         = 0x0000
      On          = 0x1000
      Snoozed     = 0x2000
      Expired     = 0x3000
}
 
[Flags()] enum SignatureStatus
{
      UpToDate     = 0x00
      OutOfDate    = 0x10
}
 
[Flags()] enum ProductOwner
{
      NonMs        = 0x000
      Windows      = 0x100
}
 
# define bit masks
 
[Flags()] enum ProductFlags
{
      SignatureStatus = 0x00F0
      ProductOwner    = 0x0F00
      ProductState    = 0xF000
}
 
# get bits
$infos = Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct -ComputerName $computer
ForEach ($info in $infos){
    [UInt32]$state = $info.productState
 
    # decode bit flags by masking the relevant bits, then converting
    [PSCustomObject]@{
          ProductName = $info.DisplayName
          ProductState = [ProductState]($state -band [ProductFlags]::ProductState)
          SignatureStatus = [SignatureStatus]($state -band [ProductFlags]::SignatureStatus)
          Owner = [ProductOwner]($state -band [ProductFlags]::ProductOwner)
    }
}

Of course, if you are only using Microsoft Defender getting the status or configuration it is far simpler and most of what you might be looking of is either in Get-MpComputerStatus or Get-MpPreference.