Quantcast
Channel: HTG
Viewing all articles
Browse latest Browse all 178

Identifying wired or wireless connection types using AppSense DesktopNow Environment Manager

$
0
0
Recently I came across an Environment Manager configuration where different printers were required depending on whether a user was connected to the wired or wireless networks in an office. At first, the only way to tell seemed to be querying the client IP address(es) and matching them against wired or wireless subnets, but this didn't sit too well with me. Normally, when I solve an issue, I prefer it to be modular, so that it can be reused without having to reinvent the wheel, so I set to thinking about how to solve it in a slightly different way.

Client IP addresses

First a quick note about client IP addresses. This is a little bit tangential, but I thought it would be useful to share the information I found out during the course of dealing with this issue. As some computers (usually laptops) have both wired and wireless adapters, I wondered if AppSense Environment Manager would be smart enough to query both addresses, or would it simply take the first one assigned?

Luckily, it looks like EM is clever enough to deal with multiple IP addresses. After a little bit of testing involving assigning additional IP addresses (and a bit of help from Richard Thompson, as I originally couldn't find a network cable), we saw that if you made Actions specifically dependent on exact IP addresses, they were all processed successfully.

Finding another way

But, as mentioned earlier, this method (of checking IP subnets directly) would render the method completely self-contained for the particular customer, and make it a pretty dreary exercise for whoever copped the job of setting up all the subnet Conditions! So I thought it might be interesting to try and find another way to achieve this.

Querying network connection status

In Windows 8 and 8.1 you get the wonderful native Get-NetAdapter cmdlet, which I will endeavour to move to as time goes by (see screenshot below). However, as most enterprises are primarily concentrated on Windows 7/2008 R2 at present, I had to try and find an alternative method that I could call from PowerShell (because, if you hadn't noticed by now, PowerShell is the answer to everything!)


Prior to the dawn of PowerShell, Windows admins grew to love the netsh command. This is what I am going to use to achieve this, despite the fact that going by Microsoft's attitude, the command could be killed at any moment


When we can actually use these cmdlets directly from older PowerShell platforms it will definitely be the way to go (yes, I know there are ways to use these commands prior to Windows 8, but I'm trying to keep things simple here). Until then, we are going to make do by calling netsh from PowerShell directly.

Identifying the network connection

Digging around in netsh output - specifically, the command netsh interface ipv4 show interfaces - shows us a few interesting things...

The wired connection tends to be shown as "Local Area Connection" on all (or most) platforms. Occasionally it additionally shows as "Ethernet" (not sure whether this is a Windows 8.x thing or not)

The wireless connection shows as "Wireless Network Connection" on Windows 7/2008 R2 and earlier, and as "Wifi" on Windows 8/2012 and later.

We're very aware that a laptop can also be connected to multiple networks, so for this particular issue we're going to make a decision to implement a variable called "primary connection type".

If the user is connected to wired and wireless networks, the primary connection type will be identified as "wired".

If the user is connected to wired or wireless networks, the primary connection type will be set to whichever is connected (or not set at all, in the event the user isn't connected to any networks).

You could also leverage other Conditions (like checks to see if you are connected to the corporate network - see here or here for some more info on these) to further enhance this, but in the interests of simplicity we will stick to what we have already defined.

More simplistic PowerShell

Yes, as I keep saying my PowerShell skills are rubbish (born from necessity rather than training), but they seem to work, so if you can tidy up my code please feel free!

Needless to say this routine is best put together in a Reusable Node, as you may need to re-evaluate the connection status as a user disconnects networks, locks and unlocks their machine, runs certain executables (VPNs etc.) and logs off or on.

The first Action will be a Custom Action to query the status of the wired connection

$data = netsh interface ipv4 show interfaces | Select-String"Local area connection"
$split = $data -split '[ ]+'
$split1 = $split[4]
[Environment]::SetEnvironmentVariable("ConnectionTypeWired",$split1, "Machine")

As we've done previously, we've used the .Net Framework SetEnvironmentVariable method to make this persistent in the session - note that this time we've used a Machine variable, rather than a User one. Don't forget that you may need to run each of the Custom Actions as SYSTEM rather than the user to ensure that they can correctly set the machine environment variable - this seems to be rather hit-and-miss as to whether it is actually a requirement during my testing. As they say, your mileage may vary.

We will then add a couple of Conditions OR'ed together to check whether the OS is Windows 8 or Server 2012, because the script will have to be slightly different to check for the wireless connection in these later OSes



And then do the same for Windows 7/2008 (or any combination of OS Condition queries to define what is necessary for your environment)



For Windows 8 or 2012, the script in the Custom Action nested underneath it will look like this...

$data = netsh interface ipv4 show interfaces | Select-String"Wifi"
$split = $data -split '[ ]+'
$split1 = $split[4]
[Environment]::SetEnvironmentVariable("ConnectionTypeWireless",$split1, "Machine")

and for earlier versions, it should look like this...

$data = netsh interface ipv4 show interfaces | Select-String"Wireless"
$split = $data -split '[ ]+'
$split1 = $split[4]
[Environment]::SetEnvironmentVariable("ConnectionTypeWireless",$split1, "Machine")

This should leave your entire node structure for this Reusable Node looking like so


So now we have a Reusable Node that assesses which network connections are there (based on the OS), and sets a system environment variable showing the status of the Wired and Wireless connections it finds. The variable will actually contain the precise info on the connection state, so you will have a variable for either (or both) of these connections containing one of the following states:-

Disconnected
Connecting
Connected
Disconnecting
Hardware not present
Hardware disabled
Hardware malfunction
Media disconnected
Authenticating
Authentication succeeded
Authentication failed
Invalid address
Credentials required

This information could allow you to do some more work on identifying network adapter states and manipulating them, but I will leave that to you if you require it. We will simply concentrate on whether or not the variable shows as "connected". The savvy among you may also note that as I am using a space as a delimiter in my scripts, you will have to tidy up the -split function if you want to utilize this more detailed information. Yes, I did tell you my PowerShell was cheap and cheerful!

There is also another caveat to these quick-and-dirty scripts - if the machine you're testing (and I'm assuming 99.9% of the use case for this will be for laptops) has multiple physical NICs or wireless adapters, you are going to have to do some more advanced parsing of the netsh output, otherwise the variable will be defined by the status of the last matching adapter in the list.

Identifying the primary connection

So now we simply need to put together another Reusable Node that takes the info from the two environment variables we have set and decides what to set for our final environment variable, the one for PrimaryConnectionType.

This is a good case for an If Else group with an extra Else If (how's that for confusing?) Rather than run through each Action, it's easier to see how they sit together with a single screenshot showing the entire group Action


Now we will have (or not have) another environment variable declaring whether we have a PrimaryConnectionType or not. So it's now dead easy to set up some Reusable Conditions telling us whether the user is using wired, wireless, or neither.

To tell whether the user's primary connection is wired...





if it is wireless...




or if it isn't in a connected state for either.


Summary

This is a fairly simple example of what you can do with this. As I mentioned before, if your endpoints (or servers even, you may have users that roam between hosted and physical sessions) have multiple physical NICs or wireless adapters, then you will need to put a bit of work in on expanding the detection slightly.

If you do use something like this, then you'll also have to re-evaluate the network connection status from time to time. There are various triggers mentioned earlier that you can consider for this, but as always, testing is key to a successful implementation.

One final note. The AppSense grapevine is awash with rumours regarding new features coming in the next version of Environment Manager, EM 8 FR 5. If one of these turns out to be a Condition checking for network connection types, I will be somewhat unamused :-) 

I've also included the configuration I created during this article for download, should you wish to save some copy and pasting time! 

Viewing all articles
Browse latest Browse all 178

Trending Articles