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

Activate Office 365 Education email encryption using your free Azure RMS licenses

ome-iconIn order to meet Data Protection requirements for sending data to external recipients we needed to find a method of providing encrypted email functionality for our users. In Office 365 this is provided as a native feature via Azure Rights Management Services.

I vaguely remembered seeing something a while back about these licenses being available at zero cost and sure enough soon found a link confirming this as part of the plan changes that also brought us eDiscovery features.

Ordering licenses

In a similar vein to how the Student Advantage licenses were made available you’ll need to ask your EES reseller to get them activated against your O365 tenancy. For reference here’s the names and part numbers of the licenses you’ll need:

azure-rms-order

Assigning licenses

Once the order has been assigned you’ll need to add the license to any user you want to be able to use the RMS features i.e. in our case anyone who needs to send an encrypted message. If you’re using the GUI look for this:

azure-rms-o365-license

Given the number of users to assign licenses to the quickest way was via PowerShell, using a variation on the script that originally assigned our student licenses.

Tip: I initially scared the living daylights out of myself when checking which licenses were assigned after I’d ran the update script as it appeared users no longer had their Office 365 licenses.
The script (below) uses column position [0] to search the field AccountSkuID, which is all well and good until your users have multiple licenses assigned and for whatever reason they aren’t all listed in the same order (!)

I ended up having to run this code twice, once with Licenses[0] and again with Licenses[1] to pick up all the staff accounts, then checked a few random samples in the GUI for good measure:

Get-MsolUser -All | select UserPrincipalName,Licenses | Where-Object {$_.Licenses[0].AccountSkuID -eq "YOURORG:STANDARDWOFFPACK_FACULTY"} | Set-MsolUserLicense -AddLicenses "YOURORG:RIGHTSMANAGEMENT_STANDARD_FACULTY"

Once done I then ran GetMsolAccountSku and confirmed the numbers match up.
The number of office 365 licenses assigned to each staff user is now 3:

  • Office 365 Education
  • Office 365 ProPlus
  • Azure RMS

I’ve since found this very handy looking GUI license assignment tool via the Office 365 Yammer group which may make any further bulk maintenance tasks a bit less scary 🙂

https://gallery.technet.microsoft.com/office/Office365-License-cfd9489c

Usual disclaimer applies, be very careful running license update scripts, especially in bulk!

Configuring Azure RMS and Office 365 Message Encryption (OME)

Now your users are licensed jump into the Admin Portal > Service Settings > Rights Management then follow this excellent guide to switch on Azure RMS, then configure Office 365 Message Encryption.

http://office365support.ca/setup-and-enable-office-365-message-encryption/

There’s not much else to say for this step as the guide is spot on 🙂

Once you’ve set up a Transport Rule in Exchange settings sending yourself a test email with the keyword(s) you specify will generate this at the recipient’s end (sample screenshot of the message arriving in a GMail inbox).

ome-email

OneDrive storage saga.. Microsoft sees sense at last

9550939064_bf4b0be0bc_zAfter making a monumentally stupid decision to claw back storage space from consumer OneDrive accounts it seems Microsoft have finally seen the light and relented on their decision… in part anyway.

Logging in this evening I spotted an interesting looking email from the Uservoice forum. Basically Microsoft have done what they should’ve in the first place and left long-term users’ current storage alone.

The backtrack on “unlimited” space has stayed in place though, which isn’t surprising really given how it was being used.

Unfortunately Microsoft have done themselves a lot of reputational damage in what they had left of the consumer space. This announcement is the first step in getting some pride back but judging by the comments it may be a bit too late to regain the trust of many contributors on the site.

Like most I signed up to Google Photos after the announcement but now end up in a better position having backups across both services so in a roundabout way it’s worked out well!

Many said that Microsoft wouldn’t go back on their policy but it just goes to show if enough people speak up it can make a difference… unless you take the more cynical view that this whole show is just a way of managing opposition to the reversal of the “unlimited” promises of barely a year ago 😉

onedrive email

If you currently have 15GB loyalty and \ or 15GB camera roll storage make sure you visit the link below asap to claim back your storage. Once done you should see the screens below 🙂

http://aka.ms/onedrivestorage

onedrive-storage

onedrive-storage2

For more commentary on the climbdown head over to the links below:

Ref: http://www.theregister.co.uk/2015/12/11/microsoft_onedrive_reduces_free_storage/
Ref: http://arstechnica.com/information-technology/2015/12/microsoft-to-give-back-some-of-the-free-onedrive-storage-its-taking-away/

Header image credit – Chris Marquardt
https://www.flickr.com/photos/nubui/9550939064

Office 365 service outage

7612.Office-365-logo_thumb_58DAF1E4

As many of you are experiencing right now Microsoft have had a major issue in Azure AD that has affected the Office 365 platform.

We can’t get to the Service Status page as it’s stuck behind the login page (!) but the Azure status seems to be best source of information at present:

Ref: https://azure.microsoft.com/en-us/status/#current

azure status

The outage seems to have some relation to the random issues we were seeing on DirSync in the last day or so, receiving messages stating “The following errors occurred during synchronization:” but with an empty Error Description field.

Ref: https://social.msdn.microsoft.com/Forums/en-US/2050fdd2-2392-4a93-aeb2-ac0c1120d314/aadconnect-identity-synchronization-error-report?forum=windowsazuremanagement

More to follow…

Random error of the day – Office 365 OWA URL change

7612.Office-365-logo_thumb_58DAF1E4

This post is another heads-up for Office 365 admins behind proxy servers as we had an odd issue last week that’s an easy fix but wasn’t so obvious to spot…

OWA loading error

In Chrome some of our users were reporting that Chrome returned an ERR_CONNECTION_RESET page when trying to load Outlook from the Office 365 apps tray. It only affected a couple of users and the link was working OK in Internet Explorer.

After a bit of playing with various ways to get to OWA I found that if we removed the end of the URL and simplified it to just the “outlook” subdomain everything loaded OK… strange.

We logged a call with our Bloxx proxy support and they responded swiftly, taking some Wireshark captures on both proxy and client. Their analysis helped pinpoint the cause of the issue…

The captures showed that the client did initially talk to the proxy but then decided to continue the next part of the connection directly, which was then blocked by outbound rules on our firewall. In our WPAD file we have a wildcard entry towards the end that returns DIRECT for any in-house servers and it seemed that the “realm=havering-college.ac.uk” part of the OWA URL in the image above was matching the rule and thus trying to bypass the proxy.

What’s changed?

Although the theory made sense on one hand it didn’t on another as we’d never had these issues before. Looking around for what’s changed in our environment put a few culprits in the frame; Google Chrome updates and the Office 365 platform itself.

At this point I went back on my VM, which was now exhibiting the same issue. At one point I had the WPAD file open and the failed web page side by side… then the lightbulb moment!

On one screen I had OWA open with a domain starting https://outlook.office365.com but on my VM it was trying to load https://outlook.office.com – that’s new!

Going back into WPAD I then added another explicit traffic entry:

   /* Send Outlook OWA traffic via proxy here*/
        if (shExpMatch(url, "*outlook.office.com*"))
      { return "PROXY X.X.X.X:8080";}

Immediately OWA started working! It’s bizarre how some applications seem to need these rules in order to route traffic using Auto Detect but it seems to consistently fix issues when they pop up. As for the OWA URL, it seems to be a bit random at present which one gets used, although both are listed in the Office 365 URLs and IP ranges KB article so maybe Microsoft are in the middle of changing them over?

eDiscovery features added to Office 365 Education

eDiscovery-top

A new term begins and with it another opportunity to see how we can make the most of our Office 365 services and this month sees some welcome additions to the Education platform 🙂

One issue that’s always nibbled away in the background with the E1 plan on Office 365 was that the advanced Compliance tools were locked away in a paid plan. To add them for a mid-large size user base would’ve taken the cost to unsustainable levels so we’ve lived without them and found our own workarounds.

However, for some products (Lync \ Skype for Business) the limitations meant that we couldn’t be confident that we had sufficient visibility of what was going on from an e-safety and Safeguarding perspective.

New features

I’m pleased to report that’s all changed – no doubt in some small part thanks to Google offering “Vault” as part of the core Google Apps offering. This competition is a great thing for us end-users as both companies have to constantly feature-match each other, giving us more functionality for the same (lack of) price!

Ref: http://blogs.msdn.com/b/ukfe/archive/2015/09/03/new-school-year-brings-new-security-features-to-office-365-education.aspx

compliance search

Accessing the Compliance Center

complianceLogging into an account with Global Administrator rights shows a new Compliance option under the Admin section.

Alternatively it can be accessed directly via https://compliance.protection.outlook.com/Ucc/?wa=wsignin1.0

Full instructions for how to use the new features (search, archiving, legal hold, user permissions) can be found at https://technet.microsoft.com/en-us/library/dn876574.aspx

 

Configuration steps

Update: Having gone into the system today to try out the functionality we stumbled at the first hurdle, experiencing the error below when trying to add an Exchange mailbox as a source:

“The connection to the search service application failed”

A bit of further research provides a list of steps that need to be completed before nominated users (which are added to a dedicated eDiscovery Security Group) can search across all content within the Office 365 tenant:

Ref: https://support.office.com/en-US/Article/Set-up-an-eDiscovery-Center-in-SharePoint-Online-a18f8975-aa7f-43b4-a7d6-001d14744d8e?ui=en-US&rs=en-US

If you’re an active OneDrive for Business user you’ve got some fun ahead to add the required permissions to each ODFB site!

Ref: https://technet.microsoft.com/library/dn765092.aspx

Once done the search works as expected, although it’s not exactly speedy. Archiving an entire mailbox via this method may take some time, although it does provide access to the Purges folder in the case of a user hard deleting items (which otherwise can only be accessed via MFCMAPI as outlined here)

7612.Office-365-logo_thumb_58DAF1E4
Name changes

At the same time Microsoft have rebranded all the the “E*” plans as Office 365 Education, no more worrying about E1, E3 and so on. Fortunately as mentioned in the blog the change doesn’t affect any licensing scripts that are already in place… phew!

For more detail see http://blog.softwareone.com/office-365-education-replaces-e1-e3-and-e4-what-you-need-to-know plus of course the main Office 365 page for a glossy summary https://products.office.com/en-gb/academic/office-365-education-plan

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.)