Server 2016 RDS via Azure AD Application Proxy end-to-end guide

remote_desktop_blueOne of our priorities for this year was to improve our remote access offering to staff to enable more flexible working whilst outside of college. Office 365 helps greatly and has already improved functionality in many ways but there’s still some legacy applications and classic file shares that need to be provided remotely too. If at all possible we prefer the files not to leave the network so some form of virtual desktop looked the way to go.

After discounting VMware and Citrix offerings on cost grounds the improvements to Microsoft’s RDS offering in Server 2016 seemed to come at a perfect time.

Even more so now we’ve implemented Azure AD Application Proxy (more on that shortly!) We’ve also recently decommissioned some services that freed up a bit of physical hardware resource to “play” with so away we went!

Server installation

The physical hardware for now is running on some reclaimed Dell PowerEdge R610 servers; 64GB RAM, dual CPU and 6 x 15k disks in RAID10. Should be plenty to get us up and running with the RDS roles eventually split across two hosts. For now we’re running on just the one but even that’s plenty to get up and running with.

We installed Server 2016 Core running the Hyper-V role, which was simple enough. The Core role looks to be a tad more polished in Server 2016, although not new the sconfig tool got the main settings entered with fairly minimal fuss.

r610
yes it will go back in the rack once we’re done with it!

Getting the OS to update correctly wasn’t so simple due to Microsoft doing something silly to the update mechanism in the initial release of Windows 10 1607 and its equivalent Server 2016 release. Update status was stuck on “Downloading” showing no signs of progressing. In the end manually installing the latest Cumulative update release from the Microsoft Update Catalog did the trick e.g.

wusa.exe windows10.0-kb3213986-x64_a1f5adacc28b56d7728c92e318d6596d9072aec4.msu /quiet /norestart

Server roles

With Hyper-V up and running the next stage was to install our guests. We went with 3 VMs set up as follows:

  • Connection Broker \ RD Licensing
  • RD Web Access \ RD Gateway
  • RD Session Host

The original plan was to try and embrace the Server Core concept and only install the GUI where absolutely necessary. With that in mind we made the first two servers with Core and only the Session Host with a GUI. More on that soon… (!)

add-roles-wizard
RDS deployment wizard Role Services

Running the deployment through Server Manager on my desktop was easy going, Microsoft have done good work with this and the deployment doesn’t seem too far removed from the 2012 R2 guides I’ve been looking at online. We added each server to the roles as per above, got to the final screen and hit the magic Deploy button then…

"Unable to install RD Web Access role service on server"

Role service... Failed
Deployment... Cancelled

Well that didn’t go to plan! We had a look online, trying to find reasons for the failures and went through some initial troubleshooting to make sure all recent updates were installed and each server’s patches matched exactly, also enabled Powershell remoting…

Enable-PSRemoting -force

…still no joy until we found this little nugget of information…

Ref: https://social.technet.microsoft.com/Forums/Sharepoint/en-US/b5c2bae3-0e3b-4d22-b64d-a51d27f0b0e4/deploying-rds-2012-r2-unable-to-install-rd-web-access-role-service-on-server?forum=winserverTS

So it appears the RD Gateway \ RD Web Access role isn’t supported on Server Core. Of course we wouldn’t want the web-facing part of the deployment running on a server with reduced attack surface would we Microsoft… not impressed!

Ref: https://technet.microsoft.com/en-us/library/jj574158(v=ws.11).aspx

To confirm the hypothesis running Get-WindowsFeature on Server 2016 Core gives this…

server-core-available-rds-roles
Server Core

and on Server 2016 with GUI gives this…

server-gui-available-rds-roles
Server with GUI

Published names & certificate fun and games

After begrudgingly re-installing one of the VMs with a GUI (seemed quicker than trying to convert the Core install) we managed to get past the final Deploy page with 3 success bars 🙂

The first key setting we were asked for was the external FQDN for the RD Gateway, which was added to our ISP-hosted DNS records. We use a wildcard certificate to cover our external facing SSL needs, nothing out the ordinary there and went on to apply it to each of the four roles specified by the RDS Deployment wizard. A Session Collection was created for a test group and pointed at the new Session Host. All looking promising.

The RD Gateway FQDN naming in itself wasn’t a problem but led us to an interesting part of the setup relating to SSL certificates and domains. Once we had the RDS services accessible from outside the network (see below) I fired up my 4G tethering to give it a test.

The connection worked but threw up a certificate warning and it was obvious to see why. Our wildcard certificate is for *.domain.ac.uk but the Connection Broker’s published FQDN is servername.subdomain.domain.ac.uk and therefore isn’t covered.

Fortunately a Powershell script called Set-RDPublishedName exists to change this published name and works a treat! Grab it from https://gallery.technet.microsoft.com/Change-published-FQDN-for-2a029b80

You’ll also need to ensure that you can access the new published name internally, depending on what form your internal domain is vs. your external you may need to do a bit of DNS trickery with zones to get the records you need. More on that can be found at:

Ref: https://msfreaks.wordpress.com/2013/12/09/windows-2012-r2-remote-desktop-services-part-1
Ref: https://msfreaks.wordpress.com/2013/12/23/windows-2012-r2-remote-desktop-services-part-2

set-rdpublishedname
Set-RDPublishedName script in action

External access via Azure AD Application Proxy

We published the RD Gateway and RD Web Access via our new shiny Azure AD Application Proxy for a few reasons…

  • simplicity, no firewall rules or DMZ required
  • security, leverages Azure to provide the secure tunnel
  • SSO, use Kerberos Delegation to sign into RD Web Access as part of the user’s Office 365 login

I followed the excellent guides from Arjan Vroege’s blog for this, in particular the section regarding how to edit the RD Web Access webpage files… nice work Arjan!

Publish your RDS Environment with Azure and AD Proxy – Part 1 – http://www.vroege.biz/?p=2462
Publish your RDS Environment with Azure and AD Proxy – Part 2 – http://www.vroege.biz/?p=2563
Publish your RDS Environment with Azure and AD Proxy – Part 3 – http://www.vroege.biz/?p=2647

As per my previous post on Azure AD Application Proxy & Kerberos delegation use the command below to add the SPN record (replace the FQDN and server name as appropriate)

setspn -s HTTP/servername.subdomain.domain.ac.uk servername

When done the end result is a seamless login to RD Web Access via the Azure AD login page. In our case the link will eventually end up as a button on our Office 365-based Staff Intranet, therefore not requiring any further logins to get to the RDWeb app selection screen.

I particularly wanted to avoid the RDWeb login screen, which I’m amazed in 2017 still requires DIY hacks to avoid the requirement to login with the DOMAIN\username format. Thought Microsoft would’ve improved that in the Server 2016 release but evidently not.

One more gotcha

So having done all the hard work above preparing the login all that was left was to click the Remote Desktop icon and enjoy, right? Wrong.

After running the Set-RDPublishedName script the certificate warning went away and I could see the change to the new wildcard-friendly name, however the connection attempt now failed with the error “Remote Desktop can’t connect to the remote computer *connectionbrokername* for one of these reasons”

remote-desktop-cant-connect
connection failure after changing Published Name

Neither explanation made any sense as the connection was working perfectly fine until changing the Published Name. Indeed changing it back to the original FQDN of the Connection Broker restored service so it had to be something to do with that. After being stumped initially I came back after food (always helps!) then after a bit more research found this very helpful post:

Ref: https://social.technet.microsoft.com/Forums/windowsserver/en-US/4fa952bc-6842-437f-8394-281823b0e7ad/change-published-fqdn-for-2012-r2-rds?forum=winserverTS

It turns out the new FQDN we added when changing the Published Name needs to be added to RDG_RDAllConnectionBrokers Local Computer Group.

This group is used to approve connections in the Resource Authorization Policies (RD-RAP) section of RD Gateway Manager. By default only the server’s domain FQDN is present in the list (as you’d expect) so it appears unless you add the new Published Name in there the connection attempt gets denied.

To add your external published name follow these steps:

  • Server Manager > Tools > Remote Desktop Services > Remote Desktop Gateway Manager
  • expand your RD Gateway server > Policies > Resource Authorization Policies
  • Click Manage Local Computer Groups on the right hand pane
  • Select RDG_RDConnectionBrokers > Properties
  • Click the Network Resources tab
  • type the FQDN of the Published Name you supplied to the Powershell script earlier then click Add
  • OK all the way out then try your connection again

manage-locally-stored-computer-groups
RD Gateway Manager

The example below replaces the real server names with dummy entries but should illustrate the concept. The same scenario applies if your servers exist in a .local Active Directory domain (which will be the top entry) and your external domain is something different (again remember to sort out internal DNS zone entries to suit)

add-external-name-to-rdcbcomputers-group
Manage RDG_RDCBComputers group

Finishing touches

Once all the above is done you should then get a connection, there is one seemingly unavoidable credential prompt due to Microsoft persisting with using an ActiveX control to start the RDP session but perhaps one day they’ll update it (we live in hope). It seems you can use the UPN style format here which is handy as it keeps things consistent. In a way it’s a bit of a security measure so not the end of the world.

Now the connection itself is sorted out all that’s left is to tweak the Session Host to our requirements. This guide gives some nice pointers on locking down the server via GPO:

Ref: http://www.it.ltsoy.com/windows/lock-down-remote-desktop-services-server-2012

We also push out a custom Start Menu using the newer Windows 10 1607 GPO settings along with the Export-StartLayout command. Finally install any programs required, remember to change the mode of the server first:

Ref: https://technet.microsoft.com/en-us/library/ff432698.aspx

change user /install

Then once done

change user /execute

Now enjoy 🙂

rds-screenshot
Connection to Server 2016 RDS Session Based desktop via RD Web Access \ RD Gateway

Azure Active Directory Application Proxy installation and troubleshooting

11225654646_7fc9621cc9_bRecently we decided to migrate away from our legacy reverse-proxy product to something that would integrate better with our AD \ Office 365 systems. I’ve wanted to try out Azure AD Application Proxy for a while since seeing it in beta last year so this seemed a good time to get to grips with it. This post outlines a few gotchas to watch out for and some useful background reading.

Let’s start off with the initial Microsoft documentation available here

https://docs.microsoft.com/en-us/azure/active-directory/active-directory-application-proxy-get-started

Education freebies

Although Microsoft’s recent price hikes haven’t come at a good time for us in education we do get a lot of extras thrown into our Microsoft licensing agreement. One of the lesser-known ones is Azure AD Basic, which is the minimum requirement to use Azure AD Application Proxy – see comparison chart at https://www.microsoft.com/en-cy/cloud-platform/azure-active-directory-features for more info

To get your free licenses you’ll need to get in contact with your EES reseller and they’ll get them added to your tenant in a similar way to Office 365.

Applying the Azure AD Basic license is nice and simple, go to your Azure Management portal at https://manage.windowsazure.com, select your Azure AD directory then assign suitable groups to the license. What’s handy is that if you’re using Azure AD Connect to sync from your on-prem directory any new users will get automatically licensed as they come on board.

Installation

Next step in the documentation list is here:

https://docs.microsoft.com/en-us/azure/active-directory/active-directory-application-proxy-enable

I used two dedicated Server 2012 R2 VMs for our install, the connector will be installed on each so we have failover should it be required at some point. Enabling the Application Proxy in Azure is nothing more than one click in the portal

Now in theory the installation should be straightforward, nothing more than downloading the installer from the link, sign in with admin credentials and job done. However if everything went that smoothly this blog wouldn’t exist (!)

Troubleshooting 403 Forbidden errors

At the end of the installation the wizard helpfully offers to run a troubleshooter to check all is well but in fact all was far from well…

Checking Event Viewer threw up the following errors:

  • Event ID 32012
    The Connector update using the update service failed: ‘The remote server returned an error: (403) Forbidden.’. Check your firewall settings.
  • Event ID 12020
    The Connector was unable to connect to the service due to networking issues. The Connector tried to access the following URL: ‘https://***GUID***.bootstrap.msappproxy.net:8080/’

Outbound firewall settings were already configured to allow all the ports that were asked for in the documentation, proxy was disabled in Connection Settings and the firewall didn’t register any outbound traffic being blocked so what’s going on here? The mystery deepens…

Although the wizard only offers to run the troubleshooter once you can run it again manually by launching it from:

C:\Program Files\Microsoft AAD App Proxy Connector\ConnectorTroubleshooterLauncher.exe

Troubleshooting the troubleshooter

Although there’s a fair bit of documentation in the troubleshooting section on Microsoft’s pages none of it referred to this particular error. Google didn’t have much to go on either but did throw up some useful and detailed slides from the Ignite conference that are well worth a read:

Ref: https://channel9.msdn.com/Events/Ignite/2015/BRK3864
Ref: https://techcommunity.microsoft.com/t5/Microsoft-Ignite-Content/BRK3139-Throw-away-your-DMZ-Azure-Active-Directory-Application/td-p/10675

The second link references another useful document aimed purely at troubleshooting:

Ref: http://aka.ms/proxytshootpaper

Whilst searching I stumbled across an email contact for the Microsoft Azure AD Application Proxy team

aadapfeedback@microsoft.com 

so I dropped them a message with the errors I was encountering. The team replied almost instantly and initially suggested ensuring that the following updates were applied on the server:

https://support.microsoft.com/en-us/kb/2973337
https://support.microsoft.com/en-us/kb/2975719

Proxy proxy proxy!

However still no joy even with everything present as it should be. The next recommendation was to check if I was using a proxy server for outbound connections. We do have one but it’s not used for server VLANs and is the first thing I disable on a new VM build.

However I did get intrigued to check the traffic going out via TCPView… lo and behold there was the proxy server trying to take the outbound connections and failing miserably. It seems that despite everything in the operating system suggesting traffic should be going out directly the Connector was still trying to use the proxy route instead.

Ref: https://blogs.technet.microsoft.com/applicationproxyblog/2016/03/07/working-with-existing-on-prem-proxy-servers-configuration-considerations-for-your-connectors/

The solution is in this document under the section “Bypassing outbound proxies”, which basically involves adding these lines to the .config files for both Connector and Updater services

<system.net>

<defaultProxy enabled="false"></defaultProxy>

</system.net>

Checking Event Viewer and the Azure Portal afterwards showed success, my Connectors were now up and running with nice green icons, much better 🙂

Note: even though this fix resolves the issue the current version of the Troubleshooter doesn’t seem to follow the settings in the .config files and will still report connection failures. The Azure AD Application Proxy team are aware of this and are aiming to have a new version out soon.

Additional considerations

There’s a few other points to bear in mind when you’re completing the configuration of the application proxy. None of them are major issues but good to have everything ready before you start…

Certificates

Once the Connectors are up and running the rest of the process went smoothly, although note you will need a wildcard certificate if you want to publish your applications via a “vanity” URL i.e. your own domain rather than “msappproxy.net”

Using the vanity domain and some DNS CNAME records means that if you use Office 365 SharePoint for your Intranet your internal applications can work from the same URL both inside and outside.

Setting SPNs for Kerberos SSO

Even better, those internal apps can SSO based on the Office 365 initial sign-on for a suitably slick user experience! This does require a bit more configuration with Kerberos delegation but it’s not too bad.

When setting the SPN records I remembered the gotcha from when I worked on Dynamics CRM to type the command in manually… bizarre as it is the same still applies!

Using the -S switch worked well for me:

setspn -s HTTP/yourserver yourserver

Ref: https://blogs.msdn.microsoft.com/saurabh_singh/2009/01/08/new-features-in-setspn-exe-on-windows-server-2008/

Nested groups

Finally, bear in mind if you’re using groups created natively in Azure AD you can’t nest memberships when creating application assignments, which is a shame. As a workaround create any nested ones in your local AD instead and sync them up via Azure AD Connect or just create flat groups in Azure AD if you prefer to work solely up there.

Ref: https://docs.microsoft.com/en-us/azure/active-directory/active-directory-accessmanagement-manage-groups

Application links

You can either publish your application links via your Intranet or users can browse them via the portal (I’ve linked to the new makeover version as it looks much better than the previous one in my opinion)

https://account.activedirectory.windowsazure.com/r#/applications

image credit Rainer Stropek 

Tip of the day – Windows Update fixes for 7 and 8.1

20013670043_113a55f0bf_z

Back in the good old days (aka a few years ago) Windows Update tended to be something that just… worked. You’d take a fresh Windows install, pop it through the update process and after a bit of chugging you’d get a fully patched OS.

Recently Microsoft seem to have made a bit of a mess of things and I’ve spent far too much time forcing recalcitrant machines to do what should be a simple task.

Hopefully once the cumulative updates start rolling everything into the monthly patch cycle this post may become irrelevant. Until then here’s the quick way to persuading a Windows 7 / 8.1 machine through the Update process…

High CPU hotfix

Install this one first if you’re faced with a particularly out-of-date installation otherwise you’ll be stuck for days “searching for updates” while your CPU goes crazy (100% utilisation) for very little return…

Windows 7 https://support.microsoft.com/en-gb/kb/3102810
Windows 8 https://support.microsoft.com/en-gb/kb/3102812

Windows Update Agent

Next install this to update your updating software in order to download new updates (!)

https://support.microsoft.com/en-gb/kb/949104

Reset Windows Update Agent script

Sometimes Windows Update still won’t work in spite of the patches above so run this script from TechNet to reset the Windows Update subsystem in case something has gone awry

https://gallery.technet.microsoft.com/scriptcenter/Reset-Windows-Update-Agent-d824badc

Round trip limit exceeded

Despite all of the above Windows Update can still fail because of a hard-coded limit in how it talks to WSUS (this only applies to managed Windows desktops rather than home users). In which case you need to take advice from this song…


“you can get it if you really want but you must try, try and try, try and try… you’ll succeed at last”

Basically just keep clicking the retry button until WSUS gets through enough trips to serve you all the updates Windows needs.

Ref: http://trentent.blogspot.co.uk/2016/03/wsus-clients-fail-with-warning-exceeded.html
Ref: https://blogs.technet.microsoft.com/sus/2008/09/18/wsus-clients-fail-with-warning-syncserverupdatesinternal-failed-0x80244010/

You may also be able to speed things up by cleaning up your WSUS server, which can be aided via this very useful script

https://community.spiceworks.com/how_to/103094-automate-wsus-cleanup

or this one…

https://community.spiceworks.com/scripts/show/2998-adamj-clean-wsus

Now that’s sorted you can make yourself a cup of tea and wait for that progress bar to crawl across the screen! Will be interesting to see how the cumulative update process goes but if it means an easier way of rolling an out-of-date machine up with one single download then it’ll have some benefits for convenience albeit at the expense of granular control… swings and roundabouts I guess…

image credit Christiaan Colen
https://www.flickr.com/photos/132889348@N07/20013670043

Office 365 PowerShell – watch out for the Object Graph error

powershell

Whilst in the Office 365 admin console the other day we noticed that many of our new user accounts that are being readied for the new term were missing their Office 365 licenses. We run a script every night to automatically license our users so something wasn’t right… let the investigation begin…

Everything *looks* OK?

Initially I thought maybe the scheduled task on the server wasn’t firing so I logged on and verified the script had completed successfully the night before, at least it appeared that way as the last result code was 0x0 (success).

I double-checked the script to ensure the logic was still sound in light of changing our MIS database and subsequent student rollover for the new academic year… nothing out the ordinary there as the script just checks for users starting with a student ID code where no licenses are applied.

Run the script step-by-step

My next plan of attack was then to run the script manually in a PowerShell window line-by-line to see what was going on. The first parts were OK, authenticating into the Office 365 service with no issues then I ran the initial filter command:

Get-MsolUser -All | Where-Object {$_.isLicensed -eq $false}

But instead of returning a list of users the command bombed out with this error:

The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://provisioning.microsoftonline.com/:ListUsersResult. The InnerException message was 'Maximum number of items that can be serialized or deserialized in an object graph is '65536'. Change the object graph or increase the MaxItemsInObjectGraph quota. '. Please see InnerException for more details.

Looking around it seems the error is fairly common, I’m not sure whether it was triggered either by the number of users in our tenancy going past a certain level (and thus exceeding the query limit) or maybe a software update.

Either way the solution is explained clearly by the posters on a thread on serverfault.com:

http://serverfault.com/questions/691667/maximum-number-of-items-that-can-be-serialized-or-deserialized-in-an-object-gra

Basically the process goes as follows for an x64 server:

  • navigate to C:\Windows\Microsoft.NET\Framework64
  • go into the correct version folder based on the version of PowerShell you’re using
  • edit the machine.config file with the lines summarised in the link above
  • save and close config file

One step that isn’t mentioned was in my case the change didn’t seem to take effect until I rebooted the server

Running the unlicensed user query again after the rebooted returned the expected (large) list of unlicensed users, which I then followed up with a full run of the script to sort out all the student accounts. After that the list of unlicensed users was back at normal levels (shared mailboxes, archives etc.)

Field notes: delprof2 shutdown script

A new twist on a familiar tale is the best way to describe this post! Recently we’d noticed quite a few of our first-gen SSD machines (60GB drives) were running low on disk space, particularly in open-access areas where lots of different users were logging on.


didn’t think I’d be seeing you again…

This probably comes as no surprise to most education network admins as it’s something we used to deal with in the days of small HDDs but became almost irrelevant as larger local drives became the norm. To some extent history has repeated itself with SSD drives and we have no such problems with our newer Samsung Evo 120GB drives.

That said a solution still needed to be found for the machines with the 60GB drives. The first port of call was the easy option, enable automatic profile cleanup via GPO after a set period of days:

Computer Configuration > Policies > Administrative Templates > System/User Profiles > Delete user profiles older than a specified number of days on system restart

A bit more thought required

However after thinking about it for a couple of seconds it’s not that easy…

Our domain structure  places the Active Directory objects into OUs based on their location (room). Nothing unusual there. However what we don’t know based on OU alone is whether the machine is a classroom PC or one that lives in a staffroom \ office.

This information is very important because our Office 365 Outlook cache, amongst other per-user profile customisations needs to stay persistent and the last thing we want is to wipe staff profiles if the user has been away for a week on holiday!

With that in mind I seemed to have two choices

  1. Alter the OU structure to split machines into class and admin
    This would take a fair bit of administration and ongoing maintenance so wasn’t keen on this option
  2. Find a way to add some logic to the profile cleanup process
    Give the process some intelligence and get it to decide what to do by looking at the machine type

Registry key

registryOne of the sections in my custom imaging scripts asks the technician what the intended role of the machine is when they start the imaging process (name and location are done at the same time).

This information then goes into a custom registry key I create in HKLM\Software\HCFHE\WorkstationType for future reference.

Then the lightbulb moment: I can use that registry key as the identifier for the profile cleanup. First thought is can I add a WMI filter on the GPO… computer says no (or not easily at least)

Ref: https://social.technet.microsoft.com/Forums/fr-FR/5cd1b80a-2f90-4d46-bf65-dba52dcf0c56/how-to-make-wmifilter-that-looks-for-a-registrykey-or-filefolder?forum=winserverGP

Time for some scripting

By this point I’d decided that the GPO on its own wasn’t going to give me enough flexibility so I decided to go down the scripting route instead. First things first, we need a tool to run the profile cleanup, time to dip into my list of handy utilities for the excellent (and free) delprof2:

https://helgeklein.com/free-tools/delprof2-user-profile-deletion-tool/

Not only does it do a thorough job of cleaning profiles but it’s also very flexible in terms of specifying which profiles to clean and runs very nicely from a script 🙂

The script needs to do a couple of things:

  1. Check a registry key for the machine type ADMIN, CLASS (or an invalid value) and proceed \ quit accordingly
  2. Run the delprof2 tool with appropriate switches
  3. Write output to the Windows Event Log

For some reason I went for VBScript rather than PowerShell this time around. After a bit of research some very handy links turned up some code snippets to use. All credit to the authors for creating and putting them out there for re-use.

The second snippet is particularly useful, having worked with Linux for a while now I was yearning for a Windows equivalent to the “tee” command and very glad that the code below does the same job!

Check if value exists in the Registry (TechNet)
Save output of command to a variable (StackOverflow)
Write to Event Log (StackOverflow)

The end result

I’ve included a generalised version of the script below. As always grab the code from my OneDrive public folder to avoid any copy \ paste issues.

  • replace REMOVEME with the prefix of accounts to remove i.e. match something consistent in your student account numbers. You can have multiple /id: switches if you have a couple of different patterns to match
  • replace LEAVEME with accounts you want to exclude e.g. accounts you may have created for specialist use with profiles that you don’t want to be removed
  • You can have multiple /id and /ed switches if you have a range of different account name patterns to match
  • change any other delprof2 parameters as required (the example below removes inactive profiles over 7 days old)
  • the use of & vbCrLf after each line of output from delprof2 gives a nicely formatted Event Log entry, otherwise everything ends up on one long line!
Const HKEY_LOCAL_MACHINE = &H80000002

strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & _ 
    strComputer & "\root\default:StdRegProv")
 
strKeyPath = "SOFTWARE\HCFHE"
strValueName = "WorkstationType"
objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

Set shell = CreateObject("WScript.Shell")

If IsNull(strValue) Then
		shell.LogEvent 4, "Machine type registry key not found, exiting without performing profile cleanup"
		wscript.quit
		
ElseIf strValue="CLASS" Then
		'wscript.Echo "The registry key exists, the type is " & strValue
		
		Dim objShell
		Set objShell = WScript.CreateObject( "WScript.Shell" )
		Dim strCMD 
		strCMD = """\\yourdomain.tld\netlogon\delprof\DelProf2.exe""" & " /u /d:7 /id:REMOVEME* /ed:LEAVEME*"
		'wscript.echo strCMD
		'objShell.Run(strCMD)

		Set objExecObject = objShell.Exec(strCMD)
		strText = ""

		Do While Not objExecObject.StdOut.AtEndOfStream
			strText = strText & objExecObject.StdOut.ReadLine() & vbCrLf
		Loop
		
		shell.LogEvent 4, "Machine type is " & strValue & " - student profile cleanup has been performed" & vbCrLf & strText
		Set objShell = Nothing
		wscript.quit
		
ElseIf strValue="ADMIN" Then
		shell.LogEvent 4, "Machine type is " & strValue & " - profile cleanup not required"
		wscript.quit
		
Else 
		shell.LogEvent 4, "Machine type is unexpected value " & strValue & ", exiting without performing profile cleanup"
		wscript.quit
	
End If

The output in the Event Viewer then looks something like this…

Surface Pro 3 joins the fleet

Image from Microsoft Store UKOK Microsoft I give in… after a year of watching the tablet market waiting for an OEM to come along and make a product that comes close to the Surface I finally bit the bullet and went for the SP3.

A few challengers have come and gone (particularly disappointed at the odd asymmetric design of the Lenovo ThinkPad 10) but in the end the Microsoft device won my custom. Having used the first-gen RT for a year or so I wasn’t expecting to be surprised by what the SP3 brought to the table but the first couple of weeks with it have done just that.

Originally I was just looking for a companion tablet, really in the Atom mould but after running the Windows 10 beta on my X100e soon realised that I was going to need a new laptop as well. Sadly the single core AMD Neo really struggles with Windows 8 \ 10 so suddenly Microsoft’s “the tablet that can replace your laptop” mantra started to make sense.

Also having the chance to try one out at Future Decoded helped realise the enlarged size of the SP3 vs SP2 isn’t as unwieldy as it first appeared. More importantly Microsoft have somehow got the thickness down to the same (or less) as the original RT and that was a real winner for me.

Buying choices

What really swung my decision to buy was Microsoft lopping £100 off the price of most models in the range, the offer started around Black Friday but seems to have reverted back to original price now. It made the sweet-spot i5 \ 128GB model come in at a slightly more palatable (but still expensive) £749. Obviously there was still the matter of the overpriced keyboard to add but the overall price didn’t feel quite as painful as before.

Although there were cashback offers around I chose to buy my SP3 from John Lewis, mainly due to the 3-year warranty included in the price. Having seen the teardown report I wanted warranty on this device for as long as I could get!

A black Type Cover 3 soon followed from the Microsoft Store to complete the set.

First impressions

Unboxing the device was a similar experience to the RT, sliding out the main section of the packaging followed by a nervy moment tipping the tablet out of the middle section. The charger is now more of a classic power “brick” rather than the large-plug variety on the RT. Truth be told I prefer the older style but it’s not a deal breaker.

I’m still amazed how Microsoft have managed to get a full i5 machine into such a thin and (relatively) light form factor. Before trying out the device I thought the 12″ 3:2 ratio screen was going to be too bulky but after using it for a while it does seem to have hit that sweet spot between portability and productivity.

Starting up goes through the usual Windows 8.x first run process then ran it through Windows Update to get the latest firmware and drivers. What really struck me was the display, so much contrast and vivid colours that truth be told I’m not used to on most PC monitors. Combined with the high resolution it took a few minutes to get used to, as did finding a desktop wallpaper that actually filled the the 2160×1440 screen.

Startup speed is really impressive; given that this is my personal device it doesn’t get used during the day so I’ve been shutting it down completely rather than using any of the sleep features. Even then from a cold start it gets to the login screen in under 10 seconds, so little time I barely even notice it.

On a related note I’d recommend setting up a picture password if using a Windows 8.x tablet, makes life a lot easier if your Microsoft Account password is of the long & complex variety as typing it in on each wake-up \ unlock gets very annoying very quickly.

Kickstand & keyboard

Probably my favourite feature of the SP3 thus far has been the improved kickstand. Now it can go in pretty much any position using the device on your lap is much easier. Likewise on a table it goes to an angle that suits the user, rather than the user having to conform to the device as was with the previous two iterations.

This is where the surprise bit comes in, so far I’ve preferred to use the SP3 without the keyboard rather than with, almost the complete opposite to my experience with the RT.

surface-pro-3-stand-on-box

In this situation I’ve tended to decouple the keyboard from the tablet rather than fold it underneath. Somehow I don’t think the keys sitting upside down and the hinge bent back will be doing either any favours in the long run, although Microsoft do show it as an option in the box. Maybe they’ve been engineered better than I’m giving credit for?

The keyboard is a nice step up from the original RT unit, backlighting is great and using the angled dock position feels much more sturdy to type on. The increased size also allows for a bit more palm rest space, which feels a bit more comfortable to type with than on the previous versions. The touchpad again is also a bit bigger and works well.

One minor change I hadn’t spotted until I started using the device was that the material used to surround the keyboard has changed from a smooth rubberised material to fabric. It’s something I’m going to have to get used to as I liked the smoother surface of the RT keyboard. I guess it was swapped due to the larger surface area of the Pro, either for cost or durability reasons (as the original material did pick up fingermarks quite easily).

Windows 8 experience

As a result of using touch more than previously I’m also breaking a habit of 10+ years and using IE on a regular basis (!) The native touch version of it works rather well when used in tablet mode, in particular I like the swipe gestures to go back to a previous page which just feels natural after a while. Using Snap View I can easily run web browsing and other apps side by side, although there have been some oddities with video playback stopping when switching apps when desktop mode is on one of the panes.

I was hoping for something similar to Metro IE using Chrome’s “Windows 8 Mode” but that’s basically ChromeOS on Windows, very disappointing. That said I’m not really surprised given the battle going on these days between Microsoft and Google’s OS and cloud platforms.

In terms of apps I tend to work more in Desktop mode but I have grown to like (!) the Start Screen and live tiles. The Mail tile is useful for keeping up-to-date and the News app is comfortable to read (if a little slow to update when launching, could do with a tweak there). I’ve already written about how much I like the OneNote app in the past so no need to revisit that 😉

I haven’t needed to use the pen as yet but to save battery life disabled Bluetooth, meaning I lose the click-and-hold activation for OneNote. Not a problem though as it’s on my Start Screen anyway. As a random aside it seems Apple might want a piece of the stylus party after all judging by these patents!

It’s not perfect…

However as with everything there’s some annoying niggles that need improvement:

    1. penThen pen holder really does look like an afterthought from the bargain bucket school of design. A sticky pad , really? The next version of the keyboard cover should have pen storage integrated neatly into the design for sure.
    2. The pricing difference between the 128GB \ 4GB (£749) and 256GB \ 8GB (£999)  i5 models is way more than the cost of the supporting components. It’s certainly one way for Microsoft to ensure they make some profit on the SP3 line but along with the keyboard does seem a bit of a rip-off. I wonder how many more they’d sell with more realistic pricing.
    3. The Windows 8.1 UI has come a long way since the mess of the original 8.0 release but does still jar in places, especially when it touch-only mode. It will be very interesting to see what improvements arrive when the Windows 10 beta gets the new Continuum interface. I wonder if the next preview release will have it in?
    4. The Metro IE design team need to tweak the UI for Surface users, at the moment the (tiny) activation area for the URL bar is tucked away in the corner which is nigh on impossible to hit when the SP3 keyboard is docked in the slanted position. Back to the drawing board with that one!

address-bar
whoever came up with this idea probably didn’t do well in their performance review…

f.lux users beware!

One of the first programs I install on any Windows device I use these days is the excellent f.lux utility. It adjusts your screen colour over the course of the day and helps reduce eye strain and improve sleep when using screens at night. Soon after I got the SP3 up and running I installed the program as normal and thought nothing more of it. After using the device for a couple of days on and off I’d counted 2-3 screen lags and one full-on crash where the machine locked up. At the time I was wondering if I’d bought a lemon but a quick Google search (via a forum) soon found this:

https://justgetflux.com/faq.html

Uh oh, my Surface Pro 3 is freezing! (or my Intel-based laptop is slow with f.lux).
Early-2014 Intel HD Windows 8.1 drivers have some bugs that give problems with f.lux, and you may not have the latest one (Surface Pro 3 does not as of September 2014).

Given that there’s no Microsoft-approved driver update out yet I’ve removed f.lux for now and will try it again once a newer version of the Intel driver is released via Windows Update. Hurry up Microsoft and get that done please!

Conclusion

4.5-out-of-5

So far so good. I’m happy with the SP3 so far and the quality of the work that went into the design clearly shows. It’s brilliant that technology has come on to such a point where an i5 CPU  and supporting components can be crammed into a case not much bigger than the original iPad. Yes it’s not cheap but if you’re after a Windows hybrid device then I don’t think there’s anything else on the market that comes close.

Save yourself from insanity… Dynamics CRM 2013 setspn unknown parameter

images
Sometimes in IT you get tasks that can drive you to the brink of madness, fortunately this series of  posts should help before you end up like the chap on the right >>>

Bizarre problem of the day goes to the setspn command that is recommended as part of a Dynamics CRM 2013 installation. I prefer to set up commands with multiple parameters in Notepad before putting them anywhere near the command prompt so did the same as usual with setspn having read the online documentation and added the required options.

I then fired up the command prompt, pasted in my carefully crafted string and… nothing… setspn spat it back at me saying the parameters entered weren’t recognised despite showing an example with exactly the same syntax!

Just to be sure I started cmd again, making doubly sure I’d ran it as elevated, under the correct user, removed any trailing spaces etc. but still no joy 😦

Finally I thought I’d try typing the command in just in case I was somehow picking up a stray character from the copy \ paste operation… success!

Moral of the story… type this one manually

I’ve never seen anything like it before but bizarrely it seems typing the command manually is the only way to get it to work. Verifying with setspn -l confirmed the records had entered correctly, definitely one for the weird fixes list…

We had to re-install CRM today when moving to a production environment; I forgot about the trick and re-found (!) the solution via TechNet forums, seems I wasn’t alone in experiencing the issue:

https://social.technet.microsoft.com/Forums/en-US/e396df7c-3cf1-47b1-8721-d2774a1f8816/setspn-unknown-parameter?forum=ilm2

https://social.microsoft.com/Forums/en-US/218667e1-2e31-44f0-b0d4-0f4f5805b05f/setspn-command-not-working?forum=crmdeployment