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

image

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:

  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.

Example

The Script

image

Action Center

image

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

}

Posted in .NET, PowerShell, Scripting | Tagged | Leave a comment

SharpDevelop RT Edition (beta) – Code Windows Forms Directly On Windows RT

Playing with my Microsoft Surface RT I was itching to do some coding on it. So I have started porting SharpDevelop http://www.icsharpcode.net/opensource/sd/download/ so that it will run on Windows RT.

A few notes:

  • This is unsupported by Microsoft method, your device must be “unlocked” to allow running 3rd party Desktop apps
  • I had to go back to SharpDevelop 3.2 as it was last version without WPF based GUI (Windows RT doesn’t support WPF)
  • So far I only tested C# Windows Forms GUI design & compile + C# Console. C# ASP.NET compiles but you’ll need to deploy manually to a web server. VB.NET currently doesn’t work.
  • Debugging does not work, you must run compiled EXE outside debugger currently
  • Ensure target framework is .NET 4.0 and platform is Any CPU (not x86/x64)
  • I removed SVN support, WPF templates
  • I migrated projects to .NET 4.5 framework and changed the build platform from x86 to Any CPU
  • You need to copy from full Windows machine with .NET 4 C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.Targets onto Windows RT. Possibly other files in this folder too. I copied the entire C:\Windows\Microsoft.NET\Framework\v4.0.30319 from my Win8 machine with VS2012 & Windows SDK installed but did not overwrite any existing files in the directory on Windows RT device, if you do you’ll trash your .NET. I chose “skip” for duplicate files. Recommend make backup of dir on Windows RT before modification.
  • You will need to copy from existing Windows development machine with Visual Studio 2012 installed – C:\Program Files\Reference Assemblies on 32-bit machine or C:\Program Files (x86)\Reference Assemblies to your Windows RT devices. You should have structure like this:

  • I also had to take these two DLLs from an existing Windows 8 machine and copy to these locations

xcopy system.xml.linq.dll C:\windows\assembly\GAC_MSIL\System.Xml.Linq\4.0.0.0__b77a5c561934e089\

xcopy system.data.datasetextensions.dll C:\windows\assembly\GAC_MSIL\System.Data.DataSetExtensions\4.0.0.0__b77a5c561934e089\

  • It is possible you may need to copy other DLLs from a Windows 8 machine, the name of missing DLL should be displayed when running EXE

Once above is accomplished you can do the following:

  1. Download and Extract
  2. Run bin\SharpDevelop.exe
  3. Click File | New Solution
  4. Select Windows Application
  5. Give it name Hello World, click Create
  6. Select MainForm.cs tab, then select Design
  7. Click View | Tools
  8. Expand Windows Forms, drag label onto Form
  9. Right click label properties, change text to Hello, Worl

  10. Click Build | Edit Configuration/Platform
  11. In Platform click x86 and Edit

  1. Add anycpu then select it click OK
  2. Select platform Any CPU again. Should look like this:

  1. Hit the red exclamation mark to run program (next to green play button) or hit Ctrl+FN+Search Button

Vs201 project Source code and binary here:

https://skydrive.live.com/redir?resid=E1A3C870740A073D!270&authkey=!AI0vFrK_EVY53hI

original project here: http://www.icsharpcode.net/opensource/sd/download/

Posted in Uncategorized | 14 Comments

Case of The Disconnected Drive That Wouldn’t Go Away

In a remote desktop connection to a Windows 2008 R2 box I had a drive that showed up a Z: and showed up as Disconnected, but right clicking and selecting “Disconnect” I recieved the error:

The network connection does not exist.

The mapped drive was operational, connected to a network share, but I no longer needed it

image

Running ProcMon while attempting to remove the drive I noticed an ACCESS DENIED on an .ini file, in a folder I didn’t even have access to at all.

image

Typically a user’s persistent mapped drives are stored in HKU\Network\<Drive Letter> key within the registry. This drive mapping was persistent across logoff/logon, but kept coming back.

So I thought, what if I add the registry entry in manually, and I set it to a folder I had full control of.

I set the following registry values:

ConnectionType REG_DWROD 0×1

DeferFlags REG_DWORD 0×4

ProviderName REG_SZ Microsoft Windows Network

ProviderType REG_DWORD 0×00020000

RemotePath REG_SZ <file share>

UserName REG_SZ <blank>

image

After adding this entry, I was able to right click drive and Disconnect worked!

Posted in Explorer, ProcMon, Troubleshooting | Tagged | Leave a comment

Case of the MacOS Finder Non-Stop Crashing

95% of the time I run Windows 8 on my MacBook Air, but for music stuff or iOS dev I boot back into MacOS Mountain Lion. So one day I log into MacOS and every 5 seconds Finder crashed, lost the desktop, with the dialog box:

The last time you opened Finder, it unexpectedly quit while reopening windows. Do you want to try to reopen its windows again?

But irresepctive of what I selected (even if I selected nothing) it would re-open about 5 seconds later, then crash again almost immediately afterwards. My desktop icons looked like they had been set to <Blink></Blink>

And I was forced to browse files using Terminal (OK, that is typically my preferred method anyway, so no loss there…)

image

To diagnose I started with MacOS in-built file monitoring utility, and filtered on finder:

sudo fs_usage | grep –i “finder”

You will then need to put in the root password to elevate fs_usage

image

You will get some quick scrolling output, something like this:

image

You can hit Ctrl+C to terminate. Unforuntately the beginning of paths are often chopped off, so you may need to run

find . -name “<folder/filename>” to find what you’re looking for

image

In this case however I looked through the files / processes with “Finder” and one stuck out as being “non-standard” This was process CitrixFMDAgent that was trying to open files used by Finder, which is part of Citrix CloudGateway with ShareFile + Follow-me Data solution.

I found the location of the process using

ps -e | grep -i “citrix”

image

I then removed the application using (this will forcefully delete the application, you will need to re-install from source files)

sudo rm -f -R /Applications/Citrix

Immediately after removing Citrix folder my Finder stopped crashing, logging on/off the problem remained resolved. Of course I no longer had Citrix installed…but as to why Citrix caused this, I’ll save that for another day of debugging…

Posted in Citrix, MacOS | Tagged | 1 Comment

Case of the Chineseification of WinRT apps

So I added two Chinese input methods to my Windows 8 Enterprise x64 (en-GB) system…

image

Please note, I did not add Chinese as a display language. And my desktop UI remains in English…

However WinRT apps…some (but not all) are in Chinese…In email the default folders had switched to Chinese

image

Finance app was in Chinese…

image

Calendar was in Chinese…

image

Internet Explorer remained in English…

image

Store was in English…

image

Settings was in English and English keyboard was selected…

image

Full settings page was in English, and couldn’t find any setting about Chinese

image

I launched ProcMon (http://live.sysinternals.com/ProcMon.exe) and then launched and affected app that wasn’t already running

I found the process ID of one of these WinRT apps using Task Manager, selecting the icon, right clicking and select ‘Go to details’ (Task manager must be in expanded view for this option to be available)

image

Ok here it is, process ID 7164

image

I then set my procmon to filter on PID is 7164

image

Knowing that Chinese is usually referred to with a ZH prefix (for ZHong wen = 中文 = Chinese [language])

Adding filter to log Details contains ZH I found these keys.

image

I noticed the order en-AU, zh-Hans-CN, and then finally en-GB which was the current display language…

It seems like some of these apps are checking for a display language in the order of user profile languages, irrespective of whether they are display language or not. Since most people don’t bother to write in true blue aussie language…none of these apps had en-AU language available. But next on the list was Chinese, so they displayed in Chinese.

This was proven by re-ordering the input languages with the display language set as first:

image

Problem solved!

My Windows 8 apps had mostly reverted back to English…(after they restarted…i.e. killed in task manager, waited to die on their own, or logged off/on)

image

Finance app…

image

Thankfully this had the issue all sorted out

But why…

I suspect these new advanced language settings have something to do with it…

In Clock, Language and Region control panel item select Advanced Settings

image

Here we had selected Use The Language List

image

For people using US English this will not be an issue, as almost all apps have this language already there…but for those of us with alternate versions of English + multiple IMEs will get this issue, unless you override Windows display language here, or Ensure the common English IME (EN-US/EN-GB is set first)

Posted in Language, Sorting It All Out, Windows 8 | Tagged | Leave a comment

Case of the ADODB.Connection Provider Not Found Error

A customer’s old in-house app was bombing out occasionally on Windows 7 with the following error:

ADODB.Connection: Provider cannot be found. It may not be properly installed.

image

The question was – what provider could not be found? We did not have access to the source code to check what line no. 38 referred. From ProcMon it wasn’t immediately obvious what was missing. We could use a debugger and stack traces to work this out…or…

To find the connection string used we simply used API Monitor (http://www.rohitab.com/apimonitor)

(It is also possible some Windows logging that would tell us, but if there was I couldn’t think of it at the time…)

We monitored String Manipulation library of the C runtime

image

and Dialog Boxes

image

By monitoring dialog boxes we can search the log for text in a message box, and then reverse our way through the log to find point before error occurred.

We then selected the running process from a list, right clicked and selected option to monitor process.

We then reproduced problem, and searched for Provider. Immediately I found the database connection string in it’s entirety:

image

I tested the SQL server, user ID and password. All was OK. SQL Server Express 2008 was installed – as was SQL Native Client.

But here’s the problem: The provider being asked for was SQLNCLI. The installed SQL Native Client was SQL Native Client 10.0 (SQL 2008) not SQL Native Client (SQL 2005)

Downloading the standalone SQL Native Client from Microsoft (http://download.microsoft.com/download/2/7/c/27c60d49-6dbe-423e-9a9e-1c873f269484/sqlncli.msi) immediately removed the error and the application continued to work happily along. In odbcad32.exe we also saw SQL Native Client appear as an option…

image

Posted in API Monitor, Application Compatibility, Troubleshooting | Tagged | Leave a comment

Case of the Panasonic TOUGH Book Barcode Settings Failure

These devices are just a pleasure to build automated deployments for. Not. Many people just give up and use the OEM image.

There are a few problems to contend with:

#1 – Drivers & Utilities must be installed in correct order (example: Smart Card driver may prevent others installing…)

#2 – Finding the hidden command line option

PSCDMenu.exe /Auto /Component Essential /Destination “c:\util2″

to auto-install all “essential” 70 drivers/utilities in-order (not to mention the nice 1 GB package it comes in)

#3 – Finding what breaks that automated install of all 70 drivers/utilities (hint: read the log file in c:\util2 and look for any drivers with an exit code other than 0)

#4 – Dealing with the 5 auto-reboots caused by the installation of 70 drivers/utilities in Zero-Touch deployments

Having sorted all the above one final issue remained – at every logon the Panasonic Dashboard utilities launched  a sub-process, “Barcode mode switch utility”, to configure the bar code scanner. This would always fail with the following error message:

Barcode setting failed. Please end the barcode-related application and then retry.

image

Re-installing all bar code software drivers & utilities + the usual reboot failed to do anything to alleviate this message.

Using ProcMon nothing was immediately obvious.

I then launched Panasonic’s Barcode Configuration Utility with API Monitor ( http://www.rohitab.com/apimonitor )

This failed with Barcode Setting Utility failed to access the barcode reader module.

image

API Monitor can monitor MessageBox calls and the relevant parameters – so it was simply a matter of searching for the text in the error message box to find the related event. I also added ISDC_Rs.dll as an “External DLL” to monitor – as this had been labelled “The Barcode Driver” I then looked backwards through the log for errors. What I found was the error message:

Overlapped I/O operation in progress

image

Scrolling further backwards through the log I found what I/O this was referring to – a CreateFile call to COM3

Looking in device manager we could then see the device COM3 along with Intel® Active Management Technology – SOL (COM3)

image

I uninstalled the the device, and chose delete driver option (because I had driver files on hand…)

image

After giving back the driver to this device Intel Active Management was back – on a different COM Port

clip_image002

Suddenly the barcode application was happy – at first logon we now received message Settings were applied successfully.

image

and off we could go on our merry way doing 2D barcode scans…

The problem was SCCM had installed the Intel Active Management Technology driver *before* the Panasonic Toughbook driver package had a chance to do it’s stuff, and taken over the COM port for the barcode scanner. And COM ports don’t like to be shared.

Posted in API Monitor, Debugging, Deployment | Tagged | 6 Comments