Solving The Antimalware Status Challenge
In this issue:
Let's re-visit the scripting challenge I gave you at the end of last month. I challenged you to create a PowerShell tool that would provide information from the AntimalwareHealthStatus WMI class found in the root\Microsoft\SecurityClient namespace. Naturally, I wanted your code to query a remote computer and at a minimum show this information:
- The computer name
- The enabled status
- The product status
- The spyware signature version
- the antivirus signature version
- the time of the last quick scan
- the time of the last full scan
For bonus points, I asked you to decode the ProductStatus and scanning sources from integers (technically a byte) to descriptions, i.e. System.
I hope you at least started tackling this problem. There are some good scripting techniques that I know you can apply to other projects.
A Starting Point
I told you where to start so it makes sense to see what you have to work with:
PS C:\> Get-CimInstance -Namespace root\Microsoft\SecurityClient -ClassName AntimalwareHealthStatus
PackedXml : <instance classname="AntimalwareHealthStatu
s"><property name="AntispywareEnabled" type="boolean"><value>TRUE</value></property><p name="AntispywareSignatureAge" roperty="" type="uint32"><value>0</value><prope ...="" rty="">
SchemaVersion : 1.0.0.1
Enabled : True
Name : Antimalware
Version : 4.18.26090.7
AntispywareEnabled : True
AntispywareSignatureAge : 0
AntispywareSignatureUpdateDateTime : 2026-09-25T09:30:43.000Z
AntispywareSignatureVersion : 1.459.398.0
AntivirusEnabled : True
AntivirusSignatureAge : 0
AntivirusSignatureUpdateDateTime : 2026-09-25T09:30:42.000Z
AntivirusSignatureVersion : 1.459.398.0
BehaviorMonitorEnabled : True
EngineVersion : 1.1.26090.9
IoavProtectionEnabled : True
LastFullScanAge : 4294967295
LastFullScanDateTimeEnd :
LastFullScanDateTimeStart :
LastFullScanSource : 0
LastQuickScanAge : 6
LastQuickScanDateTimeEnd : 2026-09-19T00:54:57.769Z
LastQuickScanDateTimeStart : 2026-09-19T00:51:35.070Z
LastQuickScanSource : 2
NisEnabled : True
NisEngineVersion : 1.1.26090.9
NisSignatureVersion : 1.459.398.0
OnAccessProtectionEnabled : True
ProductStatus : 524288
RealTimeScanDirection : 0
RtpEnabled : True
PSComputerName :
This looks rather straightforward. Although, you might want to look at the class definition. Instead of using Get-CimClass, let's use Get-CimClassProperty from the PSScriptTools module.
PS C:\> Get-CimClassProperty -Namespace root\Microsoft\SecurityClient -ClassName AntimalwareHealthStatus
Class: root/Microsoft/SecurityClient:AntimalwareHealthStatus
Property ValueType Flags
-------- --------- -----
AntispywareEnabled Boolean ReadOnly
AntispywareSignatureAge UInt32 ReadOnly
AntispywareSignatureUpdateDateTime String ReadOnly
AntispywareSignatureVersion String ReadOnly
AntivirusEnabled Boolean ReadOnly
AntivirusSignatureAge UInt32 ReadOnly
AntivirusSignatureUpdateDateTime String ReadOnly
AntivirusSignatureVersion String ReadOnly
BehaviorMonitorEnabled Boolean ReadOnly
Enabled Boolean ReadOnly
EngineVersion String ReadOnly
IoavProtectionEnabled Boolean ReadOnly
LastFullScanAge UInt32 ReadOnly
LastFullScanDateTimeEnd String ReadOnly
LastFullScanDateTimeStart String ReadOnly
LastFullScanSource UInt8 ReadOnly
LastQuickScanAge UInt32 ReadOnly
LastQuickScanDateTimeEnd String ReadOnly
LastQuickScanDateTimeStart String ReadOnly
LastQuickScanSource UInt8 ReadOnly
Name String ReadOnly
NisEnabled Boolean ReadOnly
NisEngineVersion String ReadOnly
NisSignatureVersion String ReadOnly
OnAccessProtectionEnabled Boolean ReadOnly
PackedXml String ReadOnly
ProductStatus UInt32 ReadOnly
RealTimeScanDirection UInt8 ReadOnly
RtpEnabled Boolean ReadOnly
SchemaVersion String ReadOnly
Version String ReadOnly
This is useful because this tells us that the datetime properties are technically strings so we'll need to convert them.
I know I'll only need a subset of these properties:
PS C:\> Get-CimInstance -Namespace root\Microsoft\SecurityClient -ClassName AntimalwareHealthStatus | Select-Object ProductStatus,*end,*source,*version,*enabled | Tee-Object -variable t
ProductStatus : 524288
LastFullScanDateTimeEnd :
LastQuickScanDateTimeEnd : 2026-09-19T00:54:57.769Z
LastFullScanSource : 0
LastQuickScanSource : 2
SchemaVersion : 1.0.0.1
Version : 4.18.26090.7
AntispywareSignatureVersion : 1.459.398.0
AntivirusSignatureVersion : 1.459.398.0
EngineVersion : 1.1.26090.9
NisEngineVersion : 1.1.26090.9
NisSignatureVersion : 1.459.398.0
Enabled : True
AntispywareEnabled : True
AntivirusEnabled : True
BehaviorMonitorEnabled : True
IoavProtectionEnabled : True
NisEnabled : True
OnAccessProtectionEnabled : True
RtpEnabled : True
This is more than I will eventually need, but it gives me something to work with. For example, I can figure out how I'm going to handle datetime values.
PS C:\> $t.LastQuickScanDateTimeEnd
2026-09-19T00:54:57.769Z
PS C:\> $t.LastQuickScanDateTimeEnd -as [datetime]
Friday, September 18, 2026 8:54:57 PM
That's pretty easy.