How to Upgrade Your Domain Functional Level (DFL) in Active Directory

A complete Guide on what DFL even is, to how to upgrade it, and what to do if something goes wrong.

If you've been running Active Directory for a while, chances are you're due for a Domain Functional Level (DFL) upgrade. Whether you're prepping for Windows Server 2025, looking to tighten up security, or just tired of dragging legacy baggage around—this guide's for you.

Let's walk through what it means, what it unlocks, and how to do it safely.

What's a Domain Functional Level Anyway?

A Domain Functional Level defines what features are available in your domain, based on the oldest Windows Server version running as a domain controller (DC). It's like unlocking bonus features in your domain; but only when everyone's playing the same version of the game. The Forest Functional Level (FFL) is similar but applies to the entire forest, not just one domain. To upgrade the FFL, you must first all domains to the desired DFL. Once all domains are upgraded, you can upgrade the FFL.

Member servers and client devices don't care about the DFL / FFL, it only affects domain controllers and Active Directory behavior

What's New With Higher Functional Levels?

As you move up the DFL / FFL ladder, you get better security features, more control over authentication, and enhanced compatibility with modern tools. Here's a rundown:

Windows Server 2025

Supports the following DC OS versions:

  • Windows Server 2025

Windows Server 2016

  • Privileged Access Management (Optimal) - using Microsoft Identity Manager
  • Support for smartcard-required accounts to auto-roll NTLM secrets
  • Conditional NTLM support (only from specific domain-joined devices)
  • Better PKInit Freshness handling in Kerberos

Supports the following DC OS versions:

  • Windows Server 2025
  • Windows Server 2022
  • Windows Server 2019
  • Windows Server 2016

Windows Server 2012 R2

  • DC-side protections for Protected Users
  • Authentication Policies and Policy Silos

Supports the following DC OS versions:

  • Windows Server 2022
  • Windows Server 2019
  • Windows Server 2016
  • Windows Server 2012R2

Windows Server 2012

  • KDC support for claims
  • Compound authentication
  • Kerberos armoring

Officaly supports the following DC OS versions:

  • Windows Server 2012R2
  • Windows Server 2012

Windows Server 2008 R2

  • Active Directory Recycle Bin (Optimal) - recover deleted objects without a backup
  • Automatic SPN management for services
  • Authentication mechanism assurance for the type of authentication used

Officaly supports the following DC OS versions:

  • Windows Server 2012R2
  • Windows Server 2012
  • Windows Server 2008R2

Windows Server 2008

  • Distributed File System (DFS) replication support for SYSVOL (Optimal) - replaces last supported version of FRS is 2008R2
  • Domain-based DFS namespaces support for access-based enumeration and increased scalability
  • Advanced Encryption Standard (AES 128 and AES 256) support for the Kerberos protocol
  • Last Interactive Logon Information
  • Fine-grained password policies
  • Personal Virtual Desktops

Officaly supports the following DC OS versions:

  • Windows Server 2012R2
  • Windows Server 2012
  • Windows Server 2008R2
  • Windows Server 2008

Windows Server 2003

  • Adds domain management tool netdom.exe
  • Logon time stamp updates
  • The ability to set the userPassword attribute as the effective password on inetOrgPerson and user objects
  • The ability to redirect Users and Computers containers
  • The ability for Authorization Manager to store its authorization policies in AD DS
  • Constrained delegation
  • Selective authentication

Officaly supports the following DC OS versions:

  • Windows Server 2012R2
  • Windows Server 2012
  • Windows Server 2008R2
  • Windows Server 2008
  • Windows Server 2003

Windows 2000 (Native)

  • Universal groups
  • Group nesting
  • Group conversion
  • Security identifier (SID) history
  • Kerberos protocol transition and constrained delegation
  • SID filtering
  • SPN management

Officaly supports the following DC OS versions:

  • Windows Server 2008R2
  • Windows Server 2008
  • Windows Server 2003
  • Windows 2000

As you may noticed, I started to use the termin "Officaly" in the last few sections. This is because Microsoft while Microsoft does not support running other OS versions on the mentioned DFLs, I have seen it work in the wild. However, it is not recommended to do so - and let's be honest, you should not be running Windows Server 2008R2 or older in 2025.

Pre-Upgrade Checklist: What to Check First

All Domain Controllers Are Running the Right OS

Before you can upgrade to a specific DFL, all DCs must be running that version or newer. For example:

Target DFL All DCs Must Be At Least
2025 Windows Server 2025
2016 Windows Server 2016
... ...

Check DC OS versions with PowerShell:

Get-ADDomainController -Filter * | Select-Object Name, OperatingSystem

2. SYSVOL Replication Method = DFSR

Still using FRS (File Replication Service)? Time to move on! FRS was deprecated in Windows Server 2008 R2 and isn't supported in Server 2012 or later.

FRS came with Windows 2000 Server, but Microsoft replaced it with DFSR (Distributed File System Replication) in Server 2003 R2. By Server 2008, DFSR supported SYSVOL replication and became the preferred method. FRS was limited to SYSVOL-only replication in Server 2008 R2. You'd only see it if your domain used a 2003 or 2000 functional level. From Server 2012 onward, new domains default to DFSR, and by Server 2012 R2, you can't even choose FRS anymore when creating a domain.

Check your SYSVOL replication method with PowerShell:

function Get-SYSVOLReplicationType {

    $currentDC = (Get-ADDomainController).Hostname
    $domainInfo = Get-ADDomain
    $defaultNamingContext = ([ADSI]"LDAP://$currentDC/rootDSE").defaultNamingContext

    $dcSearchRoot = "LDAP://$currentDC/OU=Domain Controllers,$defaultNamingContext"

    # Retrieve Domain Controller LDAP path
    $dcSearcher = [ADSISearcher]::new(
        [ADSI]$dcSearchRoot,
        "(&(objectClass=computer)(dNSHostName=$currentDC))"
    )

    $dcResult = $dcSearcher.FindOne()

    if (-not $dcResult) {
        Write-Warning "Domain controller object not found."
        return
    }

    $dcObjectPath = $dcResult.Path

    # Check DFSR Replication
    $dfsrSearcher = [ADSISearcher]::new(
        [ADSI]$dcObjectPath,
        "(&(objectClass=msDFSR-Subscription)(name=SYSVOL Subscription))"
    )

    $dfsrResult = $dfsrSearcher.FindOne()

    if ($dfsrResult) {
        return [PSCustomObject]@{
            "Domain"                       = $domainInfo.DNSRoot
            "Forest"                       = $domainInfo.Forest
            "Queried DC"                   = $currentDC
            "SYSVOL Replication Mechanism" = "DFSR"
            "Path"                         = $dfsrResult.Properties["msDFSR-RootPath"][0]
        }
    }

    # Check FRS Replication
    $frsSearcher = [ADSISearcher]::new(
        [ADSI]$dcObjectPath,
        "(&(objectClass=nTFRSSubscriber)(name=Domain System Volume (SYSVOL share)))"
    )

    $frsResult = $frsSearcher.FindOne()

    if ($frsResult) {
        return [PSCustomObject]@{
            "Domain"                       = $domainInfo.DNSRoot
            "Forest"                       = $domainInfo.Forest
            "Queried DC"                   = $currentDC
            "SYSVOL Replication Mechanism" = "FRS"
            "Path"                         = $frsResult.Properties["frsRootPath"][0]
        }
    }

    Write-Warning "No SYSVOL replication mechanism found."
}

Get-SYSVOLReplicationType

3. Check Current Domain & Forest Functional Levels

Get-ADDomain | Select Name, DomainMode
Get-ADForest | Select Name, ForestMode

The output will show the current domain and forest functional levels, e.g. Windows2008R2Domain and Windows2008R2Forest.

4. Verify Functional Level Attributes

These give you the raw values behind the scenes:

Get-ADObject (Get-ADDomain).DistinguishedName -Properties msDS-Behavior-Version # Gives you the domain functional level value
Get-ADObject "CN=Partitions,$((Get-ADRootDSE).ConfigurationNamingContext)" -Properties msDS-Behavior-Version # Gives you the forest functional level value
Get-ADObject (Get-ADDomain).DistinguishedName -Properties ntMixedDomain # Checks if the domain is in mixed mode

msDS-Behavior-Version Values

Value DFL / FFL
8 2025
7 2016
6 2012R2
5 2012
4 2008R2
3 2008
2 2003
0 2000

ntMixedDomain Values

Value Description
0 native mode (desired state)
1 mixed mode (legacy, undesirable)

5. Active Directory Recycle Bin Enabled?

If you're on 2008 R2 or later, you can enable the Active Directory Recycle Bin. It's a lifesaver for accidental deletions. Check if it's enabled:

Get-ADOptionalFeature -Filter 'Name -like "Recycle Bin Feature"'

If it's enabled, the EnabledScopes property will show ForestOrConfigurationSet or should otherwise be populated.

6. Check Replication Health

repadmin /replsum /bysrc /bydest /sort:delta
repadmin /showrepl * /csv > replication_status.csv

The first command gives you a summary of replication status, while the second exports detailed replication status to a CSV file.

7. Verify DNS, GPO, Time Sync, and Kerberos

dcdiag /test:dns
gpotool.exe /verbose
w32tm /monitor /domain:yourdomain.com
klist

These commands check DNS, GPOs, time sync, and Kerberos, respectively.

8. FSMO Roles Check

Before doing a DFL upgrade, make sure your FSMO roles are in order. You can check them with PowerShell:

Get-ADForest | Select SchemaMaster, DomainNamingMaster
Get-ADDomain | Select PDCEmulator, RIDMaster, InfrastructureMaster

Upgrade Prep Steps

Run ADPrep from Installation Media

For most environments, you probably don't need to run ADPrep manually anymore, as it's now automatically executed when promoting a new domain controller with a higher OS version (e.g., adding a Windows Server 2025 DC to a 2016 domain). However, it's still considered good practice to run it manually. If your domain is already at the version you're upgrading to (or higher), ADPrep will inform you that no updates are necessary.

You can check the current schema version with:

Get-ADObject (Get-ADRootDSE).SchemaNamingContext -Properties objectVersion
Value Schema Version
91 Windows 2025
88 Windows 2019 / 2022 (yes they share the same schema version)
87 Windows 2016
69 Windows 2012 R2
56 Windows 2012
47 Windows 2008 R2
44 Windows 2008
31 Windows 2003 R2
30 Windows 2003
13 Windows 2000

Navigate to the \support\adprep\ folder on your Windows Server (the version to which you want to upgrade) ISO or installation media.

Forest Prep

adprep.exe /forestprep

Domain Prep

adprep.exe /domainprep

Group Policy Prep (Optional but recommended)

adprep.exe /domainprep /gpprep

Time to Upgrade

Using Graphical Interface

  1. Open Active Directory Domains and Trusts
  2. Right-click your domain and select Raise Domain Functional Level
  3. Select the desired level and click Raise
  4. Do this for all domains in the forest
  5. Right-click the root node and select Raise Forest Functional Level
  6. Select the desired level and click Raise

Using PowerShell

Raise Domain Functional Level

Set-ADDomainMode -Identity (Get-ADDomain).DistinguishedName -DomainMode Windows2016Domain

Possible values are Windows2008R2Domain, Windows2012Domain, Windows2012R2Domain, Windows2016Domain, and Windows2025Domain.

Raise Forest Functional Level

Set-ADForestMode -Identity (Get-ADForest).DistinguishedName -ForestMode Windows2016Forest

Possible values are Windows2008R2Forest, Windows2012Forest, Windows2012R2Forest, Windows2016Forest, and Windows2025Forest.

Post-Upgrade Checklist

After upgrading, double-check that everything went smoothly.

Confirm the Levels:

Get-ADDomain | Select Name, DomainMode
Get-ADForest | Select Name, ForestMode

Check FFL Change Replication:

repadmin.exe /showattr * "cn=partitions,$((Get-ADRootDSE).ConfigurationNamingContext)" /atts:msDS-Behavior-Version

Check krbtgt Password Replication:

repadmin.exe /showattr * "cn=krbtgt,$((Get-ADRootDSE).DefaultNamingContext)" /atts:pwdLastSet

Optional: NTDS Database Integrity Check

Important: Stopping NTDS will stop dependent services, like Kerberos Authentication and Netlogon, resulting in temporary authentication issues.

net stop ntds /y

ntdsutil
activate instance ntds
files
integrity
quit
quit

net start ntds

There might be additional services, which you need to start. You will see all services that you have to start again when you stop the ntds service.

Rollback Strategy (Just in Case)

  • Take System State backups of at least 2 domain controllers
  • Isolate 1–2 DCs before upgrade by disabling replication
    • If upgrade fails, remove new DCs and reconnect the isolated ones
    • Restore from backup only if necessary

Wrapping Up

Upgrading your Domain Functional Level is like upgrading the foundation of your home—it's not flashy, but it makes everything else stronger, faster, and more secure. Plus, it unlocks new features that help you keep up with modern security practices and operating systems.

Just remember:

  • Plan ahead
  • Migrate off FRS if needed
  • Backup everything
  • Test, test, test!