Active Directory Fine-Grained Password Policies

This post isn’t going to set the world on fire because of it’s revelations and new features; instead, I am going to talk about a feature that has been around since Windows Server 2008 called Fine Grained Password Policies.

Active Directory Password Policies are, even in 2018, still misunderstood. For all the consulting engagements I do, I still encounter customer environments where admins have tried to configure multiple Group Policy Objects to control password policy at various levels within their OU structure. An example of this behaviour would be to set the Default Domain Policy object to a standard password complexity and then have an OU containing administrative accounts for Domain Admins which has a GPO applying a more complex policy.

Setting the Record Straight

Before we go any further then, let’s set the record straight. In a standard configuration AD domain there can be only one password policy. It matters not where or how many times you try to link and create GPOs to set different policies, it will not work. In a default AD domain, the password policy is configured in the Default Domain Policy which is applied at the root, the top-level of the domain. The password policy is enacted and controlled by the Domain Controllers not by the computer or user object of a client.

In the modern era of PowerShell, we can see that the default password policy for the domain is by using the Get-ADDefaultDomainPasswordPolicy PowerShell command which outputs similar to the screenshot below. In this example, the lockout duration and observation windows are 15 minutes each, accounts are locked out after five failed attempts and passwords must be at least seven characters long, meet complexity requirements, be no older than 90 days but more than 1 day old, and the previous 12 passwords are remembered.

Defining Granular Password Policies

Enter Windows Server 2008 R2 which brought with it a feature, as part of Active Directory, called Fine Grained Password Policies. What this new feature allows us to do, at last, it to have control over the password policy for specific users or groups. Want uber complex admin account passwords? Sure, do it. Want to force HR or Finance staff to have a slightly more complex policy than normal users but a little less than admins? Go right ahead! Now, it’s time to be honest. The feature was first introduced in Windows Server 2008, however, it got a lot easier with Windows Server 2012. In this post I will be concentrating on the latter.

To make this work, there are two things we need to do and one thing we need to understand.

  1. We need to create password policy objects
  2. We need to link password policy objects to users or groups
  3. We need to understand the precendence

Understanding Precedence

Clearing the understanding out of the way first, we need to make sure that the correct policy is applied to the correct user or group. When we create a policy, one of the parameters required is precedence. The value for this must be a positive integer starting from 1. A user or a group can be assigned multiple policies: when this happens, the policy which wins is determined by the precedence. If a user has a direct policy linked to them with a value of 10 but they are also a member of a group which has a policy value of 5, the policy with the value of 5 will win.

Creating the Password Policy

The first real step is to create the policy. This is one, albeit long, line of PowerShell. The full list of parameters and possible values are in the Microsoft documentation at https://technet.microsoft.com/ru-ru/library/hh852234(v=wps.620).aspx. In this example, I have created a policy which backs off the default policy to allow users to keep their current password for up to 365 days.

The command executed in the example and the screenshot below:

New-ADFineGrainedPasswordPolicy -Name "MaxPassword365Days" -DisplayName "Max Password Age 365 Days" -ComplexityEnabled $true -Description "Increases the Maximum Password Age to 365 days." -LockoutDuration 00:15:00 -LockoutObservationWindow 00:15:00 -LockoutThreshold 5 -MaxPasswordAge 365:00:00:00 -MinPasswordAge 1:00:00:00 -MinPasswordLength 7 -PasswordHistoryCount 12 -ReversibleEncryptionEnabled $false -Precedence 100

With our policy now created, it won’t do anything because it isn’t linked to a user or a group so the next step is to link it. If you are testing this then by all means link it to a single user, however, in the real-world I would always use a group to allow you to be flexible and manage these policies more effectively.

To link the policy, we use the Add-ADFineGrainedPasswordPolicySubject PowerShell command. Once linked, we can use the Get-ADFineGrainedPasswordPolicy command to verify that the policy is linked.

Add-ADFineGrainedPasswordPolicySubject MaxPassword365Days -Subjects Max_Password_Age_365_Days_GG

In the example above, we can see that I used the Add-ADFineGrainedPasswordPolicySubject command. In the command we give the name of the Password Settings Object that we want to use. We then use the -Subjects parameter to declare who it should be applied to. In my case, this is a Global Group in Active Directory but this could just as easily be a user object.

Once the policy has been applied we can use the Get-ADFineGrainedPasswordPolicy to see what’s being applied. In the screenshot, we see that the MaxPassword365Days policy has an AppliesTo value of the Global Group that I set in the former command.

Meltdown and Spectre CPU Flaws on Windows Systems

Over the course of the last few days, there has been much said online about a security flaw which is affecting the X86 CPU architecture and more specifically Intel CPUs*. This is an issue which has been known since earlier in 2017 but has only recently started doing the rounds. The issue was uncovered by Google (https://security.googleblog.com/2018/01/todays-cpu-vulnerability-what-you-need.html?m=1) and was not scheduled to be made public just yet, however, growing information and leaks online led Google to release it early. The issue has also been logged under three CVEs: CVE-2017-5715, CVE-2017-5753, and CVE-2017-5754. Microsoft also has their own article at https://support.microsoft.com/en-us/help/4073119/windows-client-guidance-for-it-pros-to-protect-against-speculative-exe.

The early release by Google prompted various things that were already in-play to also happen early. Microsoft was forced to release the hotfix for Windows immediately and the Microsoft Azure planned VM maintenance which was scheduled for the 10th January has been brought forward to happen almost immediately.

* There are numerous reports including the original publication from Google that the issues also affect ARM and AMD CPUs as well. I do not wish to get embroiled in a debate whether or not AMD and ARM are affected as there is arguments coming from both sides. For the purposes of this article, I will focus on Intel as we know 100% that their processors are affected. Intel is keen to point out that while they are still affected, CPUs based on the newer platforms like Skylake and Kaby Lake will experience a lesser performance drop-off.

Read the Full Post

Set the thumbnailPhoto in Active Directory with PowerShell

For years and years, as @LupoLoopy could probably attest to, I have been a fan of dumping user photos into Active Directory. Even as far back as Exchange 2010 we have been able to light up Outlook with user photos downloaded as part of the Global Address List and today; with the likes of Azure AD, Office 365, and more; the users’ photo is more and more prominent. Over the years, I have relied on a tool from Cjwdev called AD Photo Edit, however, only this week, I discovered that we can actually do this natively with PowerShell negating the need for the tool to be used at all.

The PowerShell for this requires you to have the Active Directory PowerShell Module imported but other than that, there are no complex requirements.

$photo = [byte[]](Get-Content "" -Encoding byte)
Set-ADUser  -Replace @{thumbnailPhoto=$photo}

It really is that simple! I do, however, have a segway here: there still, to this day, does not seem to be a way to reverse the flow of profile pictures with Azure AD Connect. It is possible and always has been to export the thumbnailPhoto attribute from Active Directory to Azure AD for use in Office 365. There does not, however, seem to be a way to have Azure AD and Office 365 act as the image source and have them imported into Active Directory from the cloud. This is a shame because in Azure AD and Office 365 we have native interface elements that allow the user to self-service upload and edit their own user photo but the same tools don’t exist on-premises. One day, I hope, we will have the ability to import to AD from AAD but until that time comes, I am planning on looking into building a really small web application that will execute the PowerShell code behind the scenes and allow users to self-service their images.

Active Directory 2016 Time-Based Group Membership

Group membership control and management is one of the cornerstones of Active Directory Domain Services. In Windows Server 2016, Microsoft introduced a new feature to Active Directory that forms part of the Microsoft Privileged Access Management (PAM) strategy.

When used in conjunction with automation, this can be used to provide Just-In-Time (JIT) access to protected and administratively sensitive services. When used in an environment that is synchronised with Azure Active Directory using Azure AD Connect, this can be used to provide JIT for hybrid solutions in Microsoft Azure (when RBAC has been applied to Azure Resource Manager objects).

In this post, I will briefly explain the processing for implementing time-based group membership in Active Directory.

Read the Full Post

Apply Updates on Windows Nano Server 2016

In my previous post, List Updates on Windows Nano Server 2016, I talked about reporting the updates which are installed or missing from your Nano Servers. With that information in hand, you can now move to the more powerful aspect of actually patching them.

In my environment, I don’t want my hosts going out to Microsoft Update on their own, nor do I want to run an entire WSUS server just for a couple of Nano Servers so I patch them manually and this manual patching effort is something which will possibly resonate with others so I thought I would share it.

As it stands, the script requires you to fetch the updates yourself. I am going to work on something using Invoke-WebRequest in PowerShell to automate that step too, but that’s a small price to pay given the minimal number of updates Nano Server requires. Use the Microsoft Update Catalog at https://catalog.update.microsoft.com to obtain any updates you need. Something that was pointed out by Thomas Maurer in his Nano Server updates post at http://www.thomasmaurer.ch/2016/10/how-to-install-updates-on-nano-server/, there is an update for your Nano Servers which is not actually listed and this is the Servicing Stack Update for Windows 10 Version 1607, KB3176939 which you can download from http://catalog.update.microsoft.com/v7/site/Search.aspx?q=KB3176936. This update is designed to be installed first and it improves the reliability and stability of the servicing stack in Windows which is used by the update process.

Read the Full Post

List Updates on Windows Nano Server 2016

Windows Server 2016 introduced the new SKU, Nano Server. Nano Server is an extremely low footprint operating system designed for micro services and rapid deployment and provisioning and currently supports roles including Failover Clustering, Hyper-V, File Server, Web Server and DNS Server.

With Nano Server being completely headless and at this moment in time, not supporting a Configuration Manager agent for managing operating system patches, there needs to be a way for you to to track and manage patching on them. At home I run two Nano Server hosts using Hyper-V to host some virtual machines and a third running inside a VM for some testing workloads. I decided I wanted to script a way of at least going some way to automate the patching.

The first script below lists the updates that your Nano Server has installed already for reporting purposes. The second lists the updates which are available and require installation. It’s worth noting that for this to work, your Nano Server machines will need access to an update service to find out what updates are available, be it Microsoft Update or WSUS. If you are reading this thinking that you didn’t know Nano Server could use WSUS, well sure it can, you just need to populate the same registry keys you would on a normal Windows machine.

The code for returning the list of updates comes direct from the Microsoft Blog at https://blogs.technet.microsoft.com/nanoserver/2016/10/07/updating-nano-server/ however this assumes a manual process so I have wrapped this up to provide a level of automation.

Read the Full Post

RDS and the Case of the Mistaken PKI OID

Earlier this morning, I was working with our support team to work out an issue they were having in an environment where Remote Desktop Services had stopped working. Trying to connect to a server via RDS simply failed with a Network Level Authentication warning, strange, given it was a domain environment and everything should be trusted and all good. The issue started life as support seeing Event ID 1058 and Event ID 36870 errors in the event log and they had been looking at https://blogs.technet.microsoft.com/askperf/2014/10/22/rdp-fails-with-event-id-1058-event-36870-with-remote-desktop-session-host-certificate-ssl-communication/ for guidance to this point with no success.

I quickly discovered that a GPO had recently been implemented that enforced NLA for RDS and also assigned a certificate template to use for Remote Desktop instead of the default self-signed version. I hopped onto the certificate authority to check out the certificate template that had been configured and compared it to the recommendations of the Microsoft article for assigning certificates to RDS sessions at https://blogs.technet.microsoft.com/enterprisemobility/2010/04/09/configuring-remote-desktop-certificates/ as this is an article I have referred to before and know it works.

Read the Full Post

Hunting and Decrypting EFS Encrypted Files

At home last week, I started doing some preparations for upgrading my home server from Windows Server 2012 R2 to Windows Server 2016. This server was originally installed using Windows Server 2012 R2 Essentials and since, I have performed a Standard edition, edition upgrade on the machine which means that the host has ADDS, ADCS, NPS and some other roles installed as part of the original Essentials server installation. We all know that unbinding ADDS and ADCS can be a bit of a bore which is why nobody in the age of virtualization should be installing ADDS and ADCS on a single server together but that’s by the by.

When I started looking at decommissioning the ADCS role, I noticed that an EFS certificate had been issued to my domain user account. I’ve never knowingly used EFS but the presence of a certificate for that purpose lead me to believe there may be some files out there so I started looking.

EFS was a technology that appeared circa Windows XP to allow users to encrypt files before BitLocker was a thing. It was a nice idea but it was troubled and flawed in that it was enabled by default and users could self-encrypt files without IT having implemented the proper tools to allow them to recover the files when disaster struck.

Read the Full Post

Hyper-V Replication Firewall Rules on Nano Server

Nano Server is the newest edition in the Windows Server family and because of it’s ultra-low footprint and patching requirement, makes it an ideal Hyper-V host for running your private cloud infrastructure.

One of the resiliency features in Hyper-V, Hyper-V Replicas allows you to replicate a VM on a timed interval of as low as 30 seconds. This isn’t a new feature but is a great one none-the-less and is ideally suited to organisations with multiple data centres wanting to protect their VMs across two or more sites without the need for expensive SAN replication technologies.

Nano Server ships by default with the Windows Firewall enabled and there are two rules for Hyper-V Replicas which are both disabled by default. If you want to use Hyper-V Replica, even once you’ve configured everything you need via the Hyper-V Manager console or via PowerShell such as virtual networks and enabling the Hyper-V Replica feature, you will still need to configure this rule.

Read the Full Post

Setting PowerShell as the Default Shell in Server Core

As part of a little weekend project I’ve embarked on this week, I’ve built myself a pair of new Domain Controllers for my home AD environment running on Server Core. Not only does using Server Core for Domain Controllers make great sense because they take up less resources (CPU, Memory and Storage) but they also need less patching which means we can keep them up more often. Sure, it would be nice to be able to use Nano Server for Domain Controllers but least in Technical Preview 5 at the time of writing, this isn’t a role that’s available. DNS is but AD isn’t and hopefully it will come.

Living in the present though, with Windows Server 2012 R2 and Server Core being the best we can do for Active Directory, there is a problem that most people will notice when they start using Server Core and that is that it uses Command Prompt as it’s default shell. This means that if you want to use any PowerShell Cmdlets, you need to step up to PowerShell first. I know this doesn’t seem like a hardship but if you do it enough, it gets tiresome, especially when you think that the Active Directory Cmdlets all live in PowerShell.

Luckily, we can fix this and make PowerShell the default shell in Server Core. If you’ve only got one server to do this against then the easiest thing to do it do it manually but if you’ve got a larger estate of Server Core machines, you can go it with Group Policy Preferences too.

Setting PowerShell as the Default Shell Manually

If you’ve only got one server, a couple of servers or maybe your Server Core machines are workgroup members so you can’t use Group Policy and if any of these are true, the manual method is for you. It’s a simple PowerShell one-liner:

Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Name Shell -Value 'PowerShell.exe -NoExit'

 Setting PowerShell as the Default Shell via Group Policy

As I mentioned, we can use a Group Policy Object to ensure that all of our Server Core machines get PowerShell as their default shell.

The first step is to setup a WMI Filter in Active Directory to detect Server Core machines and the second is to create and link the GPO itself. To create a new WMI Filter, using Group Policy Management Console create a new WMI Filter. Name it whatever you chose but I called mine Windows Server 2012 R2 Server Core Only. For the query itself, use the following WMI Query:

SELECT InstallState FROM Win32_OptionalFeature WHERE (Name = "Server-Gui-Shell") AND (InstallState = "2")

To break it down, this queries WMI in the Win32_OptionalFeature class and grabs the InstallState property. It then checks to see whether InstallState is equal two for the Server-Gui-Shell value. In Windows server 2008 and 2008 R2, this was a little easier as Server GUI and Server Core identified themselves as different SKUs of the operating system however because Windows Server 2012 R2 allows us to install and uninstall the GUI as a feature that means there isn’t a different in the SKU so the way to tell the two apart is the installation state of the Server-Gui-Shell feature. On a server with a GUI, this will equal 1 and on a server without the GUI this will equal 2.

With the WMI Filter now created, we can create the GPO itself. Create a new GPO and configure it to use the WMI Filter we just created. Once created and filtered, open up the GPO Editor so that we can add our setting.

With the GPO Editor, expand Computer Configuration Preferences Windows Preferences Registry. Right-click the Registry node on the left and select New Registry Item and configure the registry item as follows:

Action: Update
Hive: HKEY_LOCAL_MACHINE
Key Path: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
Value Name: Shell
Value Type: REG_SZ
Value Data: PowerShell.exe -NoExit

Once you set this, hit OK and you’re done. Link the GPO to an OU in your Active Directory hierarchy that contains your servers and once it has applied, you’ll start to get PowerShell as your default prompt when you logon. Because the WMI Filter only applies to Server Core machines, it’s safe to link this GPO to a root OU that contains all of your servers so that when any Server Core machines get dropped in, they will automatically pick this GPO up.