This post is part of a series, for the series contents see: Azure MFA
With the foundations in place (i.e. DNS + SSL cert all sorted) next up is building the ADFS server itself. Obviously in the real world you’ll want two for resilience but as this is just a lab environment I’m only building one. It’s cheaper that way.
ADFS VM Build
First up let’s build the base VM in my internal resource group (see my Azure Lab series for details):
#Login to Azure resource manager
#Just in case you have multiple subscriptions check which one you're working in
# Setup Windows ADFS VM #
#Change to the internal resource group
$RGName = "internal-rg"
#Define VM basics
$VMName = "adfs-vm"
$VMSize = "Standard_A1"
$OSDiskName = $VMName + "OSDisk"
$StorageAccount = Get-AzureRmStorageAccount -ResourceGroupName $RGName -Name internalvmstr
$vnet = Get-AzureRmVirtualNetwork -ResourceGroupName $RGName -Name internal-vnet
#Define VM network details
$NIC1 = New-AzureRmNetworkInterface -Name "adfs-vm-eth0" -ResourceGroupName $RGName -Location $Location -SubnetId $vnet.Subnets.Id -PrivateIpAddress 220.127.116.11
Set-AzureRmNetworkInterface -NetworkInterface $NIC1
#Define the VM config
$VirtualMachine = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
$VirtualMachine = Set-AzureRmVMOperatingSystem -VM $VirtualMachine -ComputerName $VMName -Windows -Credential $Credential
$VirtualMachine = Set-AzureRmVMSourceImage -VM $VirtualMachine -PublisherName "MicrosoftWindowsServer" -Offer "WindowsServer" -Skus "2016-Datacenter" -Version "latest"
$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $NIC1.Id
$OSDiskUri = $StorageAccount.PrimaryEndpoints.Blob.ToString() + "vhds/" + $OSDiskName + ".vhd"
$VirtualMachine = Set-AzureRmVMOSDisk -VM $VirtualMachine -Name $OSDiskName -VhdUri $OSDiskUri -CreateOption FromImage
#Create the VM
New-AzureRmVM -ResourceGroupName $RGName -Location $Location -VM $VirtualMachine
This is my internal ADFS server so the next step is to login and get it joined to my AD domain:
#Login to the newly built machine and add to the domain with:
Add-Computer -DomainName "irankon.tk" -Restart
At this point there is one last key thing to do on the VM in preparation: install the Let’s Encrypt SSL Cert!
I simply copied over the certificate pfx file, that I’d exported from my cert-vm before, double-clicked and installed it to the local machine.
Service Account Setup
Once you install ADFS, your going to need an account to run the service as. This can be a normal old school service account or something a bit more fancy like a group managed service account (gMSA). Every now and then fancy is good so here’s how to prepare the gMSA.
First up you need generate the Key Distribution Service (KDS) Root Key which is what the domain controller needs to begin generating gMSA passwords. Normally you have to wait 10 hours after generating this to allow for replication but in a single DC lab environment like mine you can set the “EffectiveTime” to 10 hours in the past as a fudge to get you up and running straight away. There’s a TechNet article about it here, and this is the PowerShell to run:
#I ran this on my ad-vm
Add-KdsRootKey –EffectiveTime (Get-Date).AddHours(-10)
The next step with a gMSA is to create an AD group whose members will be allowed to use the account. Those members will be computer accounts.
#Create an AD group, the members of which will be able to use the gMSA
New-ADGroup –name "grp-adfs-gmsa" –groupscope Global
#Add my ADFS VM as a member of that group
Add-ADGroupMember "grp-adfs-gmsa" –members “adfs-vm$”
Then it’s time to finally create the gMSA itself:
#Now create the gMSA
#I think the DNSHostName switch is specifying the DC on which to create the account
-name adfs-gmsa `
-DNSHostName ad-vm.irankon.tk `
You’d think that you’d be done by now but, no wait, you still need to install the newly created gMSA on the ADFS VM:
#Run on adfs-vm
Install-ADServiceAccount -Identity adfs-gmsa
Right, finally, you should now be ready to install the ADFS role on the server which you can do by simply firing up “Add Roles And Features” from Server Manager:
Similar to a lot of Windows role installs, once the main install has completed you’ll then be prompted to go through a separate configuration wizard.
For the first step I chose the first federation server in a new farm option. I made a mental note of the O365 comment at the bottom of the page as I’m planning to lab about that in the future so I guess I’ll have to do some retro-fitting:
Because this is essentially part of the AD infrastructure you next need to specify an account with admin privileges. I used my domain/enterprise admin account:
For the service properties I was able to choose my Let’s Encrypt SSL cert, thanks to installing it beforehand, and for the federation service display name I simply chose “irankon”. All that is really specifying is what will be displayed on the ADFS web login page that is presented to users.
The next step is where you get to specify your service account, or in our case the gMSA
Then you choose the database type to store your ADFS configuration data. Unless you have a particularly huge environment (more than 30 ADFS servers) then you’re going to choose the WID option here. There’s a Microsoft article here about the requirements.
Finally you get to review the options you’ve chosen
Then before the wizard completes it runs some final prerequisites checks. I got a couple of warnings here but nothing to worry about
And that was that, although again I did have a couple of warnings once it was all complete:
Verifying the Install
There’s no better way of verifying that ADFS is up and running than by browsing to it.
As we’re still all internal at the moment (no ADFS proxy servers setup) you’ll need to configure an internal DNS record pointing to ADFS:
-Name "sts" `
-ZoneName "irankon.tk" `
-IPv4Address "18.104.22.168" `
Now, here’s an interesting thing, on Windows Server 2012 R2 there was an ADFS test page you could use but in 2016 that is disabled by default. There’s a nice TechNet article about it here where the author, Rhoderick Milne, handily also tells you how to re-enable it:
#Enable viewing the test sign-in page
Set-AdfsProperties -EnableIdPInitiatedSignonPage $true
With that in place I was then able to browse to my ADFS login page:
And login successfully: