Use Windows PowerShell to get antivirus product information

Windows Security Center has been available in Windows client operating systems since Windows XP SP2. This is a useful feature for monitoring the overall for security status for the system, including antivirus, antimalware and firewall protection. In situations no monitoring software like System Center Operations Manager is in place to monitor the security health on client computers, one option is to use Windows Management Instrumentation. There is a WMI namespace called rootSecurityCenter2 which exposes information from the Windows Security Center, like what antivirus product is installed on the system.

Ive created PowerShell function to query computers for information on what antivirus is installed as well as the current status for antivirus definitions and real-time protection:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
function Get-AntiVirusProduct {
[CmdletBinding()]
param (
[parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)
]
[
Alias('name')]
$computername=$env:computername
)

$AntiVirusProduct = Get-WmiObject -Namespace rootSecurityCenter2 -Class AntiVirusProduct  -ComputerName $computername

#Switch to determine the status of antivirus definitions and real-time protection.
#The values in this switch-statement are retrieved from the following website: http://community.kaseya.com/resources/m/knowexch/1020.aspx

switch ($AntiVirusProduct.productState) {
"262144" {$defstatus = "Up to date" ;$rtstatus = "Disabled"
}
   
"262160" {$defstatus = "Out of date" ;$rtstatus = "Disabled"
}
   
"266240" {$defstatus = "Up to date" ;$rtstatus = "Enabled"
}
   
"266256" {$defstatus = "Out of date" ;$rtstatus = "Enabled"
}
   
"393216" {$defstatus = "Up to date" ;$rtstatus = "Disabled"
}
   
"393232" {$defstatus = "Out of date" ;$rtstatus = "Disabled"
}
   
"393488" {$defstatus = "Out of date" ;$rtstatus = "Disabled"
}
   
"397312" {$defstatus = "Up to date" ;$rtstatus = "Enabled"
}
   
"397328" {$defstatus = "Out of date" ;$rtstatus = "Enabled"
}
   
"397584" {$defstatus = "Out of date" ;$rtstatus = "Enabled"}
default {$defstatus = "Unknown" ;$rtstatus = "Unknown"
}
    }

#Create hash-table for each computer
$ht = @{}
$ht.Computername = 
$computername
$ht
.Name = $AntiVirusProduct.displayName
$ht.ProductExecutable = $AntiVirusProduct.pathToSignedProdu
ctExe

$ht.'Definition Status' = 
$defstatus
$ht
.'Real-time Protection Status' = $rtstatus

#Create a new object for each computer
New-Object -TypeName PSObject -Property $ht

}

 

Sample output:

image

The rootSecurityCenter2 namespace isnt documented on MSDN, so its hard to find information on the properties and methods we find in the different classes in the namespace.

The productstate property of the AntiVirusProduct class is exposed as a integer value, which needs to be converted to a hexadecimal value. Then the different bytes in the value contains information in regards to definition updates and real-time protection. More information on this is available here. I havent found a complete reference to all possible values, the best I could find is available here.

The above function outputs Windows PowerShell objects, so its possible to filter the output i.e. based on the “Definition Status” property.  The computername parameter also supports value from pipeline to make it easy to get the computers to query from i.e. Active Directory without using a foreach construct. A few examples:

001
002
003
004
005
006
#Get antivirus product information for all computers in the specified OU/container
Import-Module ActiveDirectory
Get-ADComputer -SearchBase "CN=Computers,DC=contoso,DC=local" -Filter * | Select-Object -ExpandProperty name | Get-AntiVirusProduct

#Filter using Where-Object to get all computers where the Definition State is not "Up to date"
Get-AntiVirusProduct -computer (Get-Content computers.txt) | Where-Object {$_.'Definition Status' -notlike 'Up to date'}

 

The rootSecurityCenter2 namespace is available on Windows Vista SP1 and above. Windows Security Center is not available on server operatingsystems, meaning that the rootSecurityCenter2 namespace also isnt available. In Windows XP SP2 the namespace is called rootSecurityCenter, but the properties are not the same as in rootSecurityCenter2. It`s possible to get the function work on Windows XP, but you would need to customize it to match the properties available in the rootSecurityCenter namespace.

I would encourage you to add error handling before using this function in a production environment, i.e. adding a test to check if the remote computer is available and allowing RPC-communication. If you would like to explore the other classes in the rootSecurityCenter2 namespace for working with firewall and antispyware products, you can start by exploring the available classes like this: Get-WmiObject -Namespace rootSecurityCenter2 -List

Enable Persistent Mode for Cluster Resource Groups using the PowerShell Failover Clustering module

In Failover Clustering in Windows Server 2008 R2, Persistent Mode is intended to allow resource groups to come online on the node which an admin last moved them to. This setting is enabled by default when a virtual machine is created with Failover Cluster Manager. If you create virtual machine via System Center Virtual Manager this setting is not enabled.

By default, cluster roles have this setting disabled, except for Hyper-V virtual machine cluster roles, which have this enabled by default. This setting is useful when the cluster is shutdown and later started, in order to better distribute the resources across the nodes and allow them to come online faster, as they were likely spread across the nodes before the cluster was offlined. Otherwise, all the resources will attempt to restart on the first nodes which achieve quorum and compete for resources. This only applies to a group if it did not failover after being placed by the administrator. If a group has failed over since the last administrator placement, it is brought online on the node which the administrator last move it to.

Reference and more info regarding the Auto Start, Persistent Mode and Group Wait Delay features is available on the Clustering and High-Availability blog.

Auto Start can be enabled/disabled in bulk by marking all Cluster Resource Groups in Failover Cluster Manager and selecting “Enable auto start”/”Disable auto start”.

For Persistent Mode the only available option in Failover Cluster Manager is to right click each Cluster Resource Group and selecting/de-selecting the checkbox for “Enable persistent mode”:

image

To change this setting for all Cluster Resource Groups in an automated fashion you can use the Failover Cluster module for PowerShell, which I wrote an introduction to here.

Here is an example on how you can do this:

001
002
003
004
005
006
007
Import-Module FailoverClusters
$clustergroups = Get-ClusterGroup -Cluster cluster01.domain.local
foreach ($clustergroup in $clustergroups) {
#To enable persistent mode: x To disable persistent mode: 4294967295
$clustergroup.DefaultOwner=x
}

Although you can change the Auto Start setting in bulk in Failover Cluster Manager you might also want to do this in an automated fashion:

001
002
003
004
005
006
007
Import-Module FailoverClusters
$clustergroups = Get-ClusterGroup -Cluster cluster01.domain.local
foreach ($clustergroup in $clustergroups) {
#To enable Auto Start: 1 To disable Auto Start: 0
$clustergroup.Priority=1
}

You can also change the Group Wait Delay cluster-wide property from the PowerShell Failover Clustering module, how to do this is explained in the above referenced blog-post from the Clustering and High-Availability blog.

For the next version of System Center Virtual Machine Manager I would expect that Persistent Mode is enabled by default, since Microsoft do recommend customers to enable this setting.

Update 08.12.2011: The value of the DefaultOwner property for configuring Persistent Mode is the number of the node you want to be the default owner. In example a value of 1 means the first node in the cluster.