Prevent the Pinning of IE and Media Player to the Taskbar (And Other Tips)

The Problem:

Every time a new user logs into Windows, Explorer (explorer.exe), Internet Explorer (iexplore.exe) and Windows Media Player (wmplayer.exe) are automatically pinning to the taskbar. You disabled ActiveSetup. You exported/imported registry keys and made your .lnks, and still they were pinned. Not even a copying a profile with the desired setup (and using it as your mandatory one) stopped it.

You may have tried the “Remove pinned programs from the taskbar” GPO only to realize it prevented the pinning of anything at all. Maybe you even found a .vbs script that worked, but which took forever to achieve your goal.

Windows pinning items to the taskbar

So, how do we prevent these guys from pinning themselves, and how do we do it cleanly?

The Resolution

I will address customized taskbar items later in this post (and don’t worry, you won’t need a sysprep with an unattend.xml file and TaskbarLinks). But for now, let’s start with the fix for the auto-pinning.

I have to start by crediting the AppSense Bigot (as I often do on this blog) because he actually (technically) found the solution. He was, however, on a totally different train of thought, so your Google Fu might not have led his way for the answer.

In his post, he speaks to an attempt to pin a specific file to the taskbar (with a .chm extension). He created a shortcut to the file (more specifically, to the hh.exe program which handles .chm files) but found that Windows wouldn’t let him right-click and pin the item to the taskbar. Eventually, he found the following registry value:


This string consists of a semicolon-separated list of .exes. And sure enough, there was hh.exe right there in the middle. It turns out that this value is here to prevent certain programs from being ever being pinned to the taskbar. If you’re wondering what happens when you add iexplore.exe and wmplayer.exe to this REG_SZ value, you’re ahead of me. It turns out, it stops Windows from pinning them automatically. You can also add explorer.exe in the same way, for the record, I am just personally not sure why you would. Everybody likes that one pinned, right?

Admittedly, this will prevent users from manually pinning them later, but since you are going to enforce your own custom set, that shouldn’t be too much of a concern. If it is a concern, then sorry, this post isn’t the one you’re after.

Pinning Custom Items to the Taskbar

I expect that most people will have figured this part out before consulting Google about the above fix. This question is actually addressed all over the internet, and especially well by the infamous Brink. However, for the sake of convenience, and in case you haven’t got your custom pins sorted by this point, here’s how:

Taskbar pins are handled by a combination of a registry key and a set of .lnk files in a particular folder. You really do need both of these — it won’t work if you try to manage one without the other.

Step 1:

Set up a taskbar exactly as you want your users to see it. That is, unpin anything you don’t want there, and pin the things you do. Now, the shortcuts you pinned exist as .lnk files at the following hidden path:

%appdata%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar

You will need to create these files exactly as they appear in that folder for each new user. You can toss them into the default/mandatory user profile at that %appdata% location, or you can import them into AppSense for creation at login. You could even write a login script if you like making things hard on yourself for some reason, but in any case, you’re not quite done yet.

Step 2:

Once you’ve got these icons sorted, you will need to export the following registry key:


It will be filled with some binary values and DWORDs that will likely make no sense to you. Don’t worry: they don’t make sense to anybody else either. The point is that you need to export this key as-is, and subsequently import it for new profiles (again through a customized default/mandatory profile, AppSense, login script, etc.).

This process does not require you to kill and restart Explorer. If you are finding that to be the case, you need to apply the changes sooner. Even via AppSense login actions, I was able to spin up a new desktop with pins configured exactly as desired, and with no delay.

Hopefully this clears up the whole process. Let me know if any of this was confusing, or hey, if it helped.

Imprivata: Being Asked to Enroll Previously Enrolled Badges

First and foremost, I should note that this post will deal specifically with RFIDeas-brand proximity card readers. If you are seeing this problem with any other variety, hopefully I can provide some insight, but I won’t provide a fix. Additionally, this article assumes that you entitle Imprivata users to enroll a single badge at a time, and that you provide them the ability to overwrite their badge enrollment. With all that being said:

The Problem:

You tap your brand new badge on machine A, and enroll your username and password at the prompt. You can tap out and tap in on this device ad infinitum, and the badge works fine every time. You then attempt to roam to Machine B, but when you tap your badge, it asks you to enroll it again. You do so, and can tap out and back in safely once more. However, when you go back to Machine A, you are asked yet again to enroll the same badge you just enrolled twice.

The Reason:

If you were to enroll the badge on Machine A and open your OneSign Administrator Console to your user’s page, you would find a Badge ID currently enrolled to your account. If you then enrolled that same badge on Machine B and checked again, you’d find a totally different ID, and it would probably look like a different format. The problem is not that Imprivata is getting confused about what Badge ID is stored on the card, but rather that the readers themselves are reporting different IDs to the appliance. The order of the bits being sent to the appliance is inconsistent between devices, and this discrepancy results in Imprivata thinking the same badge is actually two (or three, or four) different badges. There is a configuration written to the memory of the proximity card reader itself that determines in what order the bits are read, and therefore, reported.

I have seen customers order a single box of readers with as many as three different configurations pre-programmed within. Users would get asked to re-enroll the same badge every time they touched one of these devices. What’s more, every re-enrollment would break recognition of the badge on the other devices. It’s not that any one of these configurations is right or wrong, it’s just that a consistent configuration does not exist across the board. The fix, therefore, is to write a consistent configuration to each reader. Of course, your immediate question becomes: How do I do that without touching every single reader individually?

The Resolution:

1. Download RFIDeas’ cmdpcprox utility from here. This will allow you to program readers from the command line. Run the installer, which will extract some portable files to a folder.

2. Connect one of your badge readers to a device with the cmdpcprox.exe utility and open a command prompt to the directory in which it resides. Run the following command:

cmdpcprox.exe -writeconfig=”config.hwg”

This command will output the active configuration of the connected reader, and save it to a file named config.hwg.

3. Copy all the contents of the cmdpcprox directory (including the .hwg file from Step 2) to a network share accessible to all users.

4. Create an Imprivata extension object that runs at desktop lock, as well as at session reconnect. You may want to add a pause of a couple of seconds for the latter trigger if you see errors when you test this. The EXO should be “written to a file with an extension of .vbs” and then executed, and it should look something like what you see below. Note that you will need to modify this to suit your environment:

Set objShell = CreateObject(“WScript.Shell”)
userProfilePath = objShell.ExpandEnvironmentStrings(“%UserProfile%”)
hwg = userProfilePath & “\config.hwg
Set objShell = nothing

Set FSO = CreateObject(“Scripting.FileSystemObject”)
FSO.CopyFile “\\network\path\to\config.hwg“, hwg

file = “\\network\path\to\CmdpcProx.exe
args = “-readconfig=” & hwg
CreateObject(“WScript.Shell”).Run file & ” ” & Trim(args), 0, True

FSO.DeleteFile hwg
Set FSO = nothing

5. Lastly, enable the EXO in the computer policy of any Windows-based endpoints or in your virtual desktops if you are using zero clients. You can use the same EXO for both in the case of a mixed environment.

The Explanation:

So, what does this do, and more importantly, why does this work?

The script copies the config.hwg file you exported from one of your readers (in Step 2) to the local computer or virtual desktop, and then instructs the network-hosted utility to write that configuration to the device connected locally. In the case of a Windows-based endpoint, this will take place as the local OneSign agent locks the desktop. A zero client has no full agent of course, but it does pass the USB reader into your virtual desktop, and the configuration can be programmed while it is connected there. The configuration file is deleted after this is accomplished, and that reader will be reliable for everyone using it in the future — not just the user who triggered the script. More importantly, it will enforce a consistent configuration on every single reader, meaning the same badge will be reported as having the same ID regardless of the device that reads it.

Using the VBscript above allows all of this to happen silently with no impact to the end user. You can certainly use simple batch script if you’re not concerned with users seeing a brief command window flash from time to time.

Lastly, just for the record, the cmdpcprox utility does not seem capable of reconciling a network path to the config.hwg file. I add this in case you were wondering why we copy it locally before running the command.

Imprivata: How to Display SSO User in BGinfo on a Kiosk

BGinfo, in case you’re by some chance unfamiliar, is a Microsoft utility for displaying session information on the wallpaper. It is often used on both servers and desktops for the purpose of quickly identifying the current Windows user, the name of the machine, and any other handy information one might want to have at hand. However, in one of Imprivata’s most common use cases, a generic account is used to enter the Windows environment, while a type-2 (kiosk) OneSign agent acts as an authentication gateway for each SSO user who shares that machine.

In this scenario, displaying the currently logged-in Windows user in BGInfo is a bit of a moot point, as it will always be the same for everyone. It doesn’t give any actual indication as to who is presently using the device. The problem is that, by default, there is no environment variable or single point for BGinfo to reference in order to display the current SSO user–that is, the one who just authenticated to Imprivata. Thankfully though, it’s not hard to set this up.

The Extension Object

You’re going to need an extension object, set to run when a session is unlocked. While you have the option to use the setx command to set an environment variable, this is not necessarily the best way to go. In my experience, using this method tends to have some timing issues with respect to the first time BGinfo runs and attempts to reference it, and I have seen this fail in more ways than one. Sometimes it just reliably failed on BGinfo’s first execution of the session, while it worked every subsequent time. In other cases, it failed consistently no matter which attempt you were on.

The more reliable option is to store the SSO User in the registry. The location of the string can be completely arbitrary, but I would strongly encourage using the HKEY Current User hive so you can keep your generic Windows login as far away from admin privileges as possible. The extension object is quite simple — here’s an example:

reg add “HKEY_CURRENT_USER\Software\SSO” /v “SSOUser” /t REG_SZ /d “{var usr}”

This will store a string value called SSOUser (which will contain the username of the person who just authenticated to Imprivata) in the HKCU\Software\SSO key (which will not exist by default, as I just invented it for the sake of this post). You may also want to run BGinfo from this extension object as well. Doing so will ensure the timing of BGinfo’s forthcoming registry reference is consistent–that is, you can be certain that BGinfo will run only after the registry is changed. Which brings me to the next point:

The .bgi File

This part is simple. BGinfo allows you to set any custom fields you’d like using the “Custom” button on the right. Simply hit that button, then “New,” and choose an identifier for your field (Might I recommend SSOUser?)

“Replace identifier with” a registry value (you won’t need to tick the 64bit checkbox unless you made things weirdly hard on yourself in the last step), and enter the path to the value you set earlier–HKEY_CURRENT_USER\Software\SSO\SSOUser in my example. Click “OK” and then “OK” again, and add the field you just created to your configuration, either by clicking the identifier in the box on the right and choosing “Add” or simply by typing its name between < and >, or <SSOUSER> in my example.

Now just save your .bgi file, put it in a place everyone can access it, and use its path as a parameter when you run the BGInfo executable. Let me know if this was helpful!

Windows: KMS Not Auto-Licensing MS Office

So, you set up your KMS server and you activated the license key for your version of Office.  You ran the slmgr.vbs /dlv all command and confirmed that all is configured correctly there. You installed Office on your master image, pointed it at the proper KMS server, re-armed it for activation, and recomposed without ever opening the software. You spun up a fresh virtual desktop, opened Microsoft Word, and found that your version of Office had not been activated. You ran the ospp.vbs /act command and found that KMS did its job, but you thought running that command as part of a startup script seemed like a bad solution to your problem. If all that sounds about right, the good news is that you’re almost there. The fix is simple and, weirdly, hidden in plain sight.

Open up a command prompt on your master image, navigate to the directory containing your Office installer file (setup.exe), and run the following command:

setup.exe /admin

The Office Customization Tool

This thing is insanely powerful and helpful. It is also, for some reason, esoteric. The only way to access it is via the above command — and you actually need the installer file. It’s hardly difficult to access, but I went years without knowing it existed because it can’t be run from anywhere in the Office install directory. I actually stumbled onto it trying to disable the over-the-top Office2013 first-run settings, but realized it could be used to solve this problem as well.

In any case, you will notice in the left panel Licensing and User Interface. Navigate there, and ensure that Use KMS Client Key is selected. That’s it. From here, feel free to make any additional configurations you might want for Office in your virtual environment.

When you’re done, do a File > Save to get a .msp file from the tool. Simply run this file on the master image, take your snapshot, recompose, and watch KMS work as desired.

AutoHotkey: Using RunAs and RunWait

I recently stumbled into a problem while attempting to automate a process that required domain credentials while logged in as a local user. I could use RunWait to run the program, but it would fail unless I was a domain user. When I attempted to use RunAs and RunWait together, I was met with an error that was “possibly related to RunAs.” I mean, who knows for sure what it was related to, am I right? It looked like this:

Don't tell anyone my credentials!

I am not sure whether this is an oversight, a bug, or done by design, but in any case, it wasn’t gonna work out for me. The workaround here is actually quite simple: Create a .bat file that includes the command you want to run (notepad.exe, in the above example) and then a command to exit the command prompt. RunWait the resulting .bat as your user of choice. Furthermore, if you hide the command prompt, it is perfectly seamless.

I ended up supplying the code to create the .bat from within my script, then deleting the resulting file when it was done. The final result looked something like this:

FileAppend, %commands%, Run.bat
RunAs, realUser, realPassword, realDomain
RunWait, Run.bat,,hide
FileDelete, Run.bat

A little bit more trouble than it probably should be, but hopefully this will suit your needs if you run into this problem. Let me know if you have any better ideas.

Imprivata: Seamless Credential Proxy for Published Apps

In certain cases, you may notice that an SSO profile for a Citrix-published app works as desired, but not before a user manually gives focus to the window. I have worked at more than one organization where the extra click was a total deal-breaker, and if you find yourself in need of that seamless experience, you’ll be happy to know the fix is no more complex than a couple of registry settings. One needs to be applied to any and all servers being used to publish the apps (to be sure of a consistent experience), and the other to the receiving clients. Appropriately, we are dealing with “Seamless Flags,” and you can find more information about them in articles CTX112499 and CTX101644 on the Citrix support site.

For quicker reference though, the changes are as follows:

On the server(s):

Key: HKEY_LOCAL_MACHINE/System/CurrentControlSet/Control/Citrix/wfshell/TWI
Value Name: SeamlessFlags
Value Type: REG_DWORD
Value: 0x8400

For x86 machines:

Key: HKEY_LOCAL_MACHINE\Software\Citrix\ICA Client\Engine\Configuration\Advanced\Modules\WFClient
Value Name: TWISeamlessFlag
Value Type: REG_SZ
Value: 1

For x64 machines:

Key: HKEY_LOCAL_MACHINE\Software\ Wow6432Node\Citrix\ICA Client\Engine\Configuration\Advanced\Modules\WFClient
Value Name: TWISeamlessFlag
Value Type: REG_SZ
Value: 1

And that’s it! Let me know if this didn’t work for you.

AutoHotkey: Using Firefox/Chrome Browser Hotkeys While Flash Has Focus

If you know what you’re doing and don’t need my rambling, you can get what you want from here.

If not: I (and countless others) have spoken at length about AutoHotkey and why you should be using it. For the uninitiated, it is an extremely powerful and easy-to-learn scripting language that you can use to fix just about any problem you throw at it. You can use it to automate all your repetitive, boring tasks and even create entirely new workflows. Case in point: this article.

Either by bug or design, there has been a shortcoming in Firefox and Chrome for years now that allows Flash to steal focus from their containers and prevent any browser-specific hotkeys from accomplishing their tasks. That is, trying to hit Ctrl+W to close a YouTube tab after having clicked anywhere in the YouTube window will serve no purpose. Maybe you’re watching something you probably shouldn’t, when you probably shouldn’t, and your boss catches you because your hotkeys weren’t working. Oh the humanity.

The attached scripts are simple workarounds, but effective. AutoHotkey’s keyboard hook supersedes even that of Flash, so it can interpret hotkeys even when Flash has focus. These little programs simply receive the hotkeys, shift focus away from Flash, and send the hotkeys where you wanted them to go in the first place.

You can install AutoHotkey from here. Then it’s simply a matter of saving either the Firefox or Chrome version (or both, I guess) from the GitHub link at the start of this post and double-clicking it. Let me know if you need any more help, if this worked for you, or especially if it didn’t. Happy __tubing.

AutoHotkey: Adding Months to an Arbitrary Date

After the third or fourth time typing date += 1,months in a script and coming up empty, I decided I needed to implement this apparently nonexistent functionality. I did few Google searches for this purpose and was met with a similar lack of success, so I figured I’d share my results here.

This function will take an arbitrary date and add (or subtract) a given number of months from it. If you want to return the date three months from today, throw today’s date and a positive 3 at the function. If you wanted to return what the date was 3 months ago, just make it a negative 3 instead. It’s fully fleshed out in the comments if you are interested.

The script is available at my GitHub. You can grab it here. Be sure to throw it in your Program Files/AutoHotkey/lib folder to make it available for any future scripts.

PS: Thanks go to my friend Joe, without whom I’d have forgotten to deal with leap years. Please let me know if you find any issues with the script, or even better, if you have found/made something more elegant.

Windows: Visible Clock on Multiple Monitors

Prior to Windows 8, the multi-monitor taskbar was not even a native feature in the world of Microsoft. They have finally added it, but for whatever reason, did not make it possible to add a clock on the second monitor. I might find myself in the minority here, but for whatever reason, I instinctively want to glance in the lower-right of my visible screen space to see the time. Barring any tweaks or workarounds put in place beforehand, I will find no clock there, and then have to shift my gaze left to see the time. First world problems? Sure. But solving those is pretty much the point of this blog.

If you’re anything like me, and just want to be able to see a clock on your second monitor, there are a few options available to you, and none of them are native to Windows. Either you’re not using Win8 yet and you don’t even have a taskbar for your second (third, fourth, etc.) monitor, or you are, and that taskbar doesn’t support a clock. There are third-party apps you can grab to solve this, like the wonderful Actual Multiple Monitors, but they are not generally free for personal use. You could switch your primary and secondary monitors in your screen configuration, but that has other implications you might not desire. You could simply train yourself to look for the clock where it appears naturally, but where’s the fun in that?

Another option would be to use a desktop gadget, but there are two possible drawbacks here. Either you set this gadget to be always-on-top, in which case you risk it becoming extremely obtrusive (as with fullscreen video, for instance); or you allow it to sit on the desktop only, in which case it becomes obscured whenever you actually use the secondary monitor. The point of this post is to propose a compromise between these two, that results in a clock visible at the stroke of a key.

How to Make Your Own (Mostly) Always-Visible Clock

See that clock on the second one?

1. The first step is to find the clock you want to use. For this, I recommend Rainmeter–an extremely robust , self-described “desktop customization tool.” It has many more tricks up its sleeve than clocks alone, but that’s beyond the scope of this post. If you decide to use Rainmeter, which I will assume for the remainder of this post, you have an inexhaustible supply of clock skins to choose from. The important thing is that the clock have an opaque background, for reasons which will become clear later on (Get it? Clear? I’ll set myself out.) As of this post, I am using this.

2. Once you have found a place on your desktop to put the clock, the second thing you will need is AutoHotkey. I don’t know how many times I’ve said that sentence in the past year, but at this point, I cannot remember life before it. At the very least, you can download stuff other people make (like what I am about to share), but if you want to give it time, you can solve just about any problem you may have with your operating system or applications. See this Lifehacker post if you need further convincing.

3. Download this script from my GitHub–don’t worry, it is thoroughly commented for your benefit, and you can obviously feel free to modify it to suit you. Essentially, the idea here is to enable a keystroke to send the desktop clock to the top of the window stack for a few seconds only. This will bring it to your immediate attention regardless of what else is happening on that monitor. After a few seconds, the script returns the clock to the desktop, hidden and out of the way, where it won’t disturb you further. You’ll know the time, you’ll have looked exactly where you wanted to look for that time, and you can go back to looking at fullscreen whatever without being disturbed.

Again, keep in mind that Step 3 presumes you are using a RainMeter clock. You will have to modify the script if you’re going to use something else (Let me know if you need help). Good luck, and I hope this works for more people than me.

Imprivata: Using Proximity Cards and Zero Clients

I have touched on the subject of troubleshooting zero clients for Imprivata usage before. However, I have been reminded in recent weeks about something I neglected to cover, and which probably deserves its own post anyway. I am referring to a commonly recurring problem that arises when one attempts to mix Imprivata, zero clients, and proximity cards.

Under certain circumstances, attempting to use proximity cards to “tap out” of an active virtual session on a zero client fails. That is, the card reader beeps, but the session remains open. I have also seen other strange behavior as well, such as a user being able to “tap over” his or her own session–where Imprivata locks the zero client and then logs them back in as themselves. Furthermore, this issue does not seem to be exclusive to View or XenDesktop, and obviously, neither of these scenarios is acceptable. Thankfully, the fix is a simple registry change in your master image.

Simply set the following values (ignore the Wow6432Node part if you’re running 32bit virtual machines):

  • HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SSOProvider\DeviceManager\RedirectionSupport DWORD : 1
  • HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SSOProvider\DeviceManager\RemoteOnly DWORD : 1

And your proximity cards should start behaving as desired. Happy tapping, and Merry Christmas. Unless you’re reading this on a date that’s nowhere near Christmas, or if you’re not into Christmas, in which cases strike that last comment.