Sometimes you might want to script checking health of anti-virus/firewall/&c. However since Windows Vista the method frequently used in scripts is accessing the wmi namespace root/securitycenter2 which is undocumented from publicly available Microsoft. Although the values of what productState mean have been guessed with reasonable accuracy, I prefer to stay away from undocumented items in case of future changes…and if there is a case “we guessed wrong”.
The WMI Method
The documented method since Windows Vista has been the Windows API WscGetSecurityProviderHealth in wscapi.dll which is documented here: http://msdn.microsoft.com/en-us/library/bb432506(v=vs.85).aspx
However calling Windows APIs from scripts can be tricky, so here is a wrapper I built in PowerShell that embeds C# code to call the Windows API and retrieve the data so you can manipulate it in PowerShell.
Note this is just sample code – to be more robust I’d recommend adding error checking/&c. and other improvements. Go knock yourself out.
The way the code works:
- We put our C# code into $wscType
- Add-Type compiles the C# code and makes the members available in $wscType
- $wscType[0]::GetSecurityProviderHealth calls the function to get health
- $wscType[1] is the WSC_SECURITY_PROVIDER enum to specify what security provider to check
- $wscType[2] is the WSC_SECURITY_PROVIDER_HEALTH enum to check against the result of GetSecurityProviderHealth
Note: The WscGetSecurityProviderHealth API is not supported on Windows XP or earlier, or on any Microsoft Server Operating Systems.
Example
The Script
Action Center
Download script here: https://skydrive.live.com/redir?resid=E1A3C870740A073D!298&authkey=!AF2EGVM6l5lQ0dc (1.57 KB ZIP)
Or copy from here:
# by chentiangemalc
# http://chentiangemalc.wordpress.com
# Define our C# functions to extract info from Windows Security Center (WSC) via Windows API so we can call from PowerShell
$wscDefinition = @”
// WSC_SECURITY_PROVIDER as defined in Wscapi.h or http://msdn.microsoft.com/en-us/library/bb432509(v=vs.85).aspx
[Flags]
public enum WSC_SECURITY_PROVIDER : int
{
WSC_SECURITY_PROVIDER_FIREWALL = 1, // The aggregation of all firewalls for this computer.
WSC_SECURITY_PROVIDER_AUTOUPDATE_SETTINGS = 2, // The automatic update settings for this computer.
WSC_SECURITY_PROVIDER_ANTIVIRUS = 4, // The aggregation of all antivirus products for this computer.
WSC_SECURITY_PROVIDER_ANTISPYWARE = 8, // The aggregation of all anti-spyware products for this computer.
WSC_SECURITY_PROVIDER_INTERNET_SETTINGS = 16, // The settings that restrict the access of web sites in each of the Internet zones for this computer.
WSC_SECURITY_PROVIDER_USER_ACCOUNT_CONTROL = 32, // The User Account Control (UAC) settings for this computer.
WSC_SECURITY_PROVIDER_SERVICE = 64, // The running state of the WSC service on this computer.
WSC_SECURITY_PROVIDER_NONE = 0, // None of the items that WSC monitors.
// All of the items that the WSC monitors.
WSC_SECURITY_PROVIDER_ALL = WSC_SECURITY_PROVIDER_FIREWALL | WSC_SECURITY_PROVIDER_AUTOUPDATE_SETTINGS | WSC_SECURITY_PROVIDER_ANTIVIRUS |
WSC_SECURITY_PROVIDER_ANTISPYWARE | WSC_SECURITY_PROVIDER_INTERNET_SETTINGS | WSC_SECURITY_PROVIDER_USER_ACCOUNT_CONTROL |
WSC_SECURITY_PROVIDER_SERVICE | WSC_SECURITY_PROVIDER_NONE
}
[Flags]
public enum WSC_SECURITY_PROVIDER_HEALTH : int
{
WSC_SECURITY_PROVIDER_HEALTH_GOOD, // The status of the security provider category is good and does not need user attention.
WSC_SECURITY_PROVIDER_HEALTH_NOTMONITORED, // The status of the security provider category is not monitored by WSC.
WSC_SECURITY_PROVIDER_HEALTH_POOR, // The status of the security provider category is poor and the computer may be at risk.
WSC_SECURITY_PROVIDER_HEALTH_SNOOZE, // The security provider category is in snooze state. Snooze indicates that WSC is not actively protecting the computer.
WSC_SECURITY_PROVIDER_HEALTH_UNKNOWN
}
// as defined in http://msdn.microsoft.com/en-us/library/bb432506(v=vs.85).aspx
[DllImport("wscapi.dll")]
private static extern int WscGetSecurityProviderHealth(int inValue, ref int outValue);
// code to call our interop function and return the relevant result based on what input value we provide
public static WSC_SECURITY_PROVIDER_HEALTH GetSecurityProviderHealth(WSC_SECURITY_PROVIDER inputValue)
{
int inValue = (int)inputValue;
int outValue = -1;
int result = WscGetSecurityProviderHealth(inValue, ref outValue);
foreach (WSC_SECURITY_PROVIDER_HEALTH wsph in Enum.GetValues(typeof(WSC_SECURITY_PROVIDER_HEALTH)))
if ((int)wsph == outValue) return wsph;
return WSC_SECURITY_PROVIDER_HEALTH.WSC_SECURITY_PROVIDER_HEALTH_UNKNOWN;
}
“@
$wscType=Add-Type -memberDefinition $wscDefinition -name “wscType” -UsingNamespace “System.Reflection”,“System.Diagnostics” -PassThru
“ Firewall: “ + $wscType[0]::GetSecurityProviderHealth($wscType[1]::WSC_SECURITY_PROVIDER_FIREWALL)
“ Auto-Update: “ + $wscType[0]::GetSecurityProviderHealth($wscType[1]::WSC_SECURITY_PROVIDER_AUTOUPDATE_SETTINGS)
“ Anti-Virus: “ + $wscType[0]::GetSecurityProviderHealth($wscType[1]::WSC_SECURITY_PROVIDER_ANTIVIRUS)
“ Anti-Spyware: “ + $wscType[0]::GetSecurityProviderHealth($wscType[1]::WSC_SECURITY_PROVIDER_ANTISPYWARE)
“ Internet Settings: “ + $wscType[0]::GetSecurityProviderHealth($wscType[1]::WSC_SECURITY_PROVIDER_INTERNET_SETTINGS)
“User Account Control: “ + $wscType[0]::GetSecurityProviderHealth($wscType[1]::WSC_SECURITY_PROVIDER_USER_ACCOUNT_CONTROL)
“ WSC Service: “ + $wscType[0]::GetSecurityProviderHealth($wscType[1]::WSC_SECURITY_PROVIDER_SERVICE)
# some examples of checking the “health” status…
if ($wscType[0]::GetSecurityProviderHealth($wscType[1]::WSC_SECURITY_PROVIDER_FIREWALL) -eq $wscType[2]::WSC_SECURITY_PROVIDER_HEALTH_POOR)
{
“Your firewall settings are lame.”
}
if ($wscType[0]::GetSecurityProviderHealth($wscType[1]::WSC_SECURITY_PROVIDER_USER_ACCOUNT_CONTROL) -eq $wscType[2]::WSC_SECURITY_PROVIDER_HEALTH_POOR)
{
“Don’t tell me you switched off UAC. oh dear.”
}
if ($wscType[0]::GetSecurityProviderHealth($wscType[1]::WSC_SECURITY_PROVIDER_ANTIVIRUS) -eq $wscType[2]::WSC_SECURITY_PROVIDER_HEALTH_GOOD)
{
“At least you have anti-virus running and up-to-date.”
}




