Accessing Windows Security Centre Status from PowerShell

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:

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:

  1. We put our C# code into $wscType
  2. Add-Type compiles the C# code and makes the members available in $wscType
  3. $wscType[0]::GetSecurityProviderHealth calls the function to get health
  4. $wscType[1] is the WSC_SECURITY_PROVIDER enum to specify what security provider to check
  5. $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.


The Script


Action Center


Download script here:!298&authkey=!AF2EGVM6l5lQ0dc (1.57 KB ZIP)

Or copy from here:

# by chentiangemalc



# 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


        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.







        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.




              // as defined in


        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;






$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.”


About chentiangemalc

specializes in end-user computing technologies. disclaimer 1) use at your own risk. test any solution in your environment. if you do not understand the impact/consequences of what you're doing please stop, and ask advice from somebody who does. 2) views are my own at the time of posting and do not necessarily represent my current view or the view of my employer and family members/relatives. 3) over the years Microsoft/Citrix/VMWare have given me a few free shirts, pens, paper notebooks/etc. despite these gifts i will try to remain unbiased.
This entry was posted in .NET, PowerShell, Scripting and tagged . Bookmark the permalink.

2 Responses to Accessing Windows Security Centre Status from PowerShell

  1. tshark says:

    Hi, cool script. Thanks!
    As you wrote WscGetSecurityProviderHealth is not supported for Window-Server OS. But is there another .dll to import there or a workaround?
    best regards

  2. Your script is great and I’m using it regularly now to monitor hundreds of devices. I have 1 issue that I hope you can help with – it isn’t utilizing the ability to verify that signatures for antivirus products are up to date. I have tried to modify it to include those functions but I’m no programmer and it has me beating my head against the table. Can you help? I’m referring to this:

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s