Pre-Flight Checks – Wireless Connectivity

As many of you know, MDT offers a series of ‘pre-flight’ checks you can run at the beginning of a task sequence to verify any number of things – BitLocker state, memory, Windows Scripting Host, etc…  They exist within the Tools\x64\Preflight and Tools\x86\Preflight folders located in the deployment share. Within the UDI Wizard, there are even checks to ensure the machine is plugged into AC power and to ensure the machine is using a wired LAN connection and not wireless. These checks are part of the compiled code and not available to us via a script. This is fine for Lite Touch Installation, but since it requires a touch, it would not work for a Zero Touch deployment.

I have been recently asked to create a wireless check to insert into the task sequence.  I built it with the following requirements…

  1. It must check to see if the currently used network connection was a wireless connection
  2. If it determines the current connection to be wireless, it must return an error, or non-zero code
  3. It must log with the rest of the OSD logs.

Determine the Current Adapter

First we have to determine the currently used adapter.  To do this, I looked in the Win32_NetworkAdapterConfiguration class.  I queried for anything with IPEnabled = TRUE and then verified it had a valid IP address. .   While this seemed to pull all active adapters, the script continued to tell me the machine was connected via LAN, even though it was on wireless.  The problem was related to the Hyper-V adapters I had installed.  The Hyper-V virtual adapters were seen by the computer as a physical adapter and an additional ‘Local Area Connection’.  Thus, the script assumed a physical adapter was in use.

To get around this, I modified the WMI query to look like this:

SELECT * FROM win32_NetworkAdapterconfiguration WHERE IPEnabled = TRUE AND NOT Caption LIKE '%Hyper-V%'

 '// Check for LAN Connection
Set colNetCfg = oWMI.ExecQuery("SELECT * FROM win32_NetworkAdapterconfiguration _
 WHERE IPEnabled = TRUE AND NOT Caption LIKE '%Hyper-V%'")
For Each oNetCfg in colNetCfg
    sAdapterName = Mid(oNetCfg.Caption,12)
    oLogging.CreateEntry "Adapter name:   " & sAdapterName, LogTypeInfo
    '// default value
    IsValidIPAddress = False 
    For Each sIPAddress In oNetCfg.IPAddress
        If InStr(sIPAddress,":") = 0 And Mid(sIPAddress,1,8) _
         <> "169.254" And Mid(sIPAddress,1,3) <> "0.0" Then
            IsValidIPAddress = True
            oLogging.CreateEntry "IsValidIPAddress:   " & IsValidIPAddress, LogTypeInfo
        End If

Find the Wireless Adapter

Now that we have the currently used adapter, we need to know if it is wireless.  The approach I chose to take is to query the registry.  The key we are looking for is HKLM\SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}.   Now we can look through each of the machine’s connections in the sub keys.  As we loop though them, we are looking for a connection with a MediaSubType = 2.  This type is returned for all adapters classified NdisPhysicalMediumWirelessLan in OID_GEN_PHYSICAL_MEDIUM.  More information on this OID can be found here.  Once we find this adapter, we retrieve its name.

 '// Get all Subkeys
oRegProv.Enumkey HKLM, RegKeyPath, arrSubKeys
'// Read each Subkey values
For Each sSubKey In arrSubKeys
   '// Get MediaSubType value if any
   oRegProv.GetDWORDValue HKLM, RegKeyPath & "\" & sSubKey & "\" & "Connection", _
    "MediaSubType", dwValue
   If dwValue = 2 Then
      '// Get Name 
      oRegProv.GetStringValue HKLM, RegKeyPath & "\" & sSubKey & "\" & "Connection" _
       ,"Name", sRegNetworkName
      oLogging.CreateEntry "sRegNetworkName:   " & sRegNetworkName, LogTypeInfo

NOTE:   In some rare cases, a wireless adapter may show a MediaSubType other than 2.  These are usually due to the adapter not supporting the wireless configuration service or the vendor uses a proprietary tool.  Please contact the vendor for assistance.

Getting Results

Now that we have the wireless adapter name from the registry (sRegWlanName) and the name of the currently used adapter (sAdapterName), we compare the two.  If they equal each other, then wireless status is set to TRUE and we return a non-zero code (1).

This takes care of the first two requirements, but to cover the third I am using a .WSF script template.  For more information on the ZTI scripting template, click  here.

 '// Compare both                            
If sRegNetworkName = sNetConnectionID Then    
   GetWirelessName = True
 To VPN or Not To VPN

We now have determined what type of connection the machine is using, but we need to do one more thing before it can be implemented.  We need to make sure that all connections that show as LAN connected are not, in fact, VPN connections. To do this, I am searching the adapter name for anything identified in my array sVPNAdapters.

 '// VPN adapter strings
sVPNAdapters = Array("VPN","JUNIPER")

I am only looking for “VPN” or “Juniper”, but you can easily add to this for different VPN types. 

Now that we have what to look for, we need to compare it to the adapter name previously recorded.  As you can see, if it finds “VPN” or “JUNIPER”, it sets IsVPNAdapter = TRUE and returns a non-zero code.

  '// if adapter is not wireless
 If IsWLANAdapter = False Then
    '// check if adapter is VPN
    For Each sVPN In sVPNAdapters
       If (Instr(UCase(sAdapterName),sVPN) > 0) Then
         IsVPNAdapter = True
       End If
    If IsVPNAdapter = True And oNetCfg.IPConnectionMetric > 0 Then
      iIPConnectStatus = oNetCfg.IPConnectionMetric
      sWLANStatus = "VPN Connected"
      oLogging.CreateEntry "Connection status:   " & sWLANStatus, _

Adding to the Task Sequence

Now that I have a functional script, I am going to add it to the task sequence.  I have named the script z-WirelessCheck.wsf and have placed it in the Scripts folder within my Microsoft Deployment Toolkit package. So to add it to the task sequence, I have simply created a command-line task and used the following syntax – cscript.exe "%deployroot%\scripts\z-WirelessCheck.wsf" /debug:true


NOTE:   Make sure that “Continue on error” is not checked in the Options tab.


I want to give credit to Veeraswamy ”Swamy” Achanta for contributing to this script.

This post was contributed by Brad Tucker, a Senior Consultant with Microsoft Services, East Region, United States

Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the Terms of Use