Build your own Thin-ish client with Windows 10 LTSB

After some positive user feedback from the launch of our new Server 2016-powered RDS setup I started wondering if it could have a wider use that just the remote access concept we initially wanted to address. One thought in mind was making use of old \ low-spec devices that would be a bit too clunky for running a modern OS but where the physical hardware itself was in good condition.

Chrome-OS esque distributions such as CloudReady sound nice but come at cost so I set up a little side-project to see if there’s anything that could be done with what we have on our licensing agreement or anything in the open-source space.

Looking around there do seem to be various thin-client “converter” products but again they all seem to be commercial e.g. https://www.igel.com/desktop-converter-udc/

The only other option I found was ThinStation which may also be worth a look when I have more time as it seems a bit more involved to get set up and I wanted to stick to the Microsoft RDP client for now for maximum compatibility.

Windows options

Going back some time I remember Microsoft released cut-down versions of Windows for RDS-type scenarios; going back to the XP days it was called Windows Fundamentals for Legacy PCs and morphed into Windows 7 Thin PC in its next incarnation. Effectively all I want the OS to do is boot up, log in quickly then pass the credentials to a pre-configured RDP file using the standard mstsc.exe application.

However building any solutions on a Windows 7 base going forward seems to be a false economy so I decided to have a look around to see what was available on the Windows 10 codebase – the results were interesting…

IoT is name of the day

Going forward it seems Microsoft have changed the branding for this kind of cut-down devices to Windows IoT. In fact there’s a free edition which sounds ideal but it only runs on certain devices and isn’t really geared for UI use:

Ref: https://www.theregister.co.uk/2015/05/21/first_look_windows_10_iot_core_on_raspberry_pi_2/
Ref: http://blogs.perficient.com/microsoft/2016/01/windows-10-iot-editions-explained/

Reading a bit further it appears Microsoft license an edition called Windows 10 IoT Enterprise for new thin client devices. Now it gets interesting… it seems that the OS itself is Windows 10 Enterprise LTSB but with some special OEM licensing. It just so happens the edu customers get Enterprise LTSB on EES licensing so it’s time to take a closer look!

What this does mean is that Windows 10 Enterprise LTSB gets features from the old Windows Embedded products such as Unified Write Filter, perfect for a locked down device that shouldn’t need to experience configuration changes to the base OS.

Ref: https://msdn.microsoft.com/en-us/windows/hardware/commercialize/customize/enterprise/unified-write-filter

All these features are available in Enterprise LTSB simply by going into Add \ Remove Windows Features window, look for the Device Lockdown section and add whichever ones meet your needs (more on this later).

Image & GPOs

After downloading the latest ISO the LTSB 2016 WIM was imported into MDT. I made a quick task sequence to get it up and running and deployed the OS to a Hyper-V VM.

Boot and logon speeds are very quick given the lack of any Modern Apps which usually need to be provisioned at each new login. The performance gain explains why quite a few people within education have used LTSB for their desktop builds against MS’ wishes; however they’ll miss out on new features such as the much-needed OneDrive Files on Demand that will only be provided to the Current Branch release.

In theory setting up a Mandatory Profile could speed up login even further but haven’t got round to trying that yet.

RDS domain SSO

Upon logging in with domain credentials the next aim is to seamlessly drop users into the RDS farm without any further prompts. After doing a bit of research this can be achieved by setting a couple of GPOs:

  • allow credential delegation
  • trust SHA1 signature of signed RDP file

The need to allow delegation of credentials is fairly commonly mentioned but a lot of the articles are old and don’t mention where this needs to be set in a 2016 farm. In fact you only need to allow the delegation on the FQDN of the Connection Broker based on the results of my testing so far.

Computer Configuration > Administrative Templates > System > Credentials Delegation

To avoid any unwanted prompts about trusting the signature of a signed RDP file populate the GPO mentioned above and copy \ paste the signature from the RDP file that is provided by RDWeb for whatever RDS Collection you want to connect to.

User Configuration > Administrative Templates > Windows Components > Remote Desktop Services > Remote Desktop Connection Client > Specify SHA1 thumbprints of certificates representing trusted .rdp Publishers

Custom shell

Now with the credentials side sorted out the final piece of the puzzle was to cleanly launch the session and (here’s the tricky bit) made a seamless logout once the RDS connection is closed. Now there’s a few ways to achieve the first part:

  • use the IoT Embedded Shell Launcher feature \ enable Kiosk Mode via System Image Manager
  • use the Custom User Interface User GPO

Ref: https://social.technet.microsoft.com/Forums/en-US/b4552957-45c2-4cc4-a13d-6397f06ee62e/windows-10-kiosk-build-embedded-shell-launcher-vs-custom-user-interface?forum=win10itprosetup

Ref: https://docs.microsoft.com/en-us/windows/configuration/set-up-a-kiosk-for-windows-10-for-desktop-editions

One thing to bear in mind with Shell Launcher is what happens when the shell i.e. mstsc.exe closes, you only have the choice of

  • Restart the shell.
  • Restart the device.
  • Shut down the device.
  • Do nothing

For the sake of speed logging off would be better so I decided to go with the Custom User Interface GPO – seeing as the Windows 10 device would be domain-joined anyway it also seemed a quicker more efficient way to configure multiple clients too.

Seeing as the Custom User Interface is a User GPO it goes without saying that Loopback Policy Processing needs to be enabled for the OU where the client resides. That also comes in handy for a few additional personalisation settings later on too.

The User GPO settings are summarised in the screenshot below, you can add more lock-down policies as you see fit:

Auto log-out on disconnect

Seeing as I wanted to automate the process as much as possible and all the devices would be domain managed anyway the GPO method seems to be the quickest way to achieve what I want. Also avoids needing to do an Add \ Remove Features step for each endpoint device.

Another important point is that the Shell Launcher method only provides options to relaunch the program, shut down or restart the machine. For speed I was aiming to log off the “client” when the RDS session is done so definitely going down the GPO route as a result.

In the GPO settings I initially tried the standard string you’d expect to launch a Remote Desktop session i.e. mstsc.exe C:\Default.rdp but noticed some strange behaviour:

  • Windows logs in
  • RDP file launched
  • connection starts
  • before the green bar completes i.e. handshake still in progress
  • host session logs out

This seemed like a behaviour I’ve seen with some other programs in the past where they appear to terminate mid-way through actions actually occurring. To check I tried manually with the “start” command with the same result. It appears mstsc.exe doesn’t play nicely so we need another way…

Plan b) was to monitor the mstsc.exe process then log out from the client once RDS disconnected and therefore the process was no longer running. After looking around and trying a few scripts out I settled on one I found here:

Ref: https://www.experts-exchange.com/questions/24218998/Check-if-a-process-is-running-in-vbs.html

Just add the logout command as the action to run when the desired process terminates and we have the desired behaviour. It takes a second or two to react to the process closing but there doesn’t seem to be a way to speed that up as far as I can see.

Final steps

Now just some finishing touches required to give the solution a bit of polish 🙂

  • set logon and desktop wallpaper
  • disable Task Manager and related lockdown setings

When the machine boots users see this login screen, easily customised via GPO…

After login connection to RDS is pretty much immediate and no further credential \ security prompts appear…

UWF

The final piece of the puzzle is tidying up after the client has been in use for a while. That’s where the Unified Write Filter from earlier comes in handy:

Enable-WindowsOptionalFeature -Online -FeatureName Client-UnifiedWriteFilter

Then enable the filter;

uwfmgr.exe filter enable

Ref: https://docs.microsoft.com/en-us/windows-hardware/customize/enterprise/unified-write-filter
Ref: https://developer.microsoft.com/en-us/windows/iot/docs/uwf
Ref: https://deploymentresearch.com/Research/Post/632/Using-the-Unified-Write-Filter-UWF-feature-in-Windows-10

And there you have it, a locked down RDS client that will run on older hardware (Windows 10 works on pretty much anything from the last 10 years) which can be managed through your standard AD infrastructure, all using stuff you already have access to via your Campus agreement… enjoy!