# Entra Password Protection for On-Premises AD: Deploy Agents Step by Step

> Block weak and organization-specific passwords on Active Directory domain controllers with the Entra Password Protection proxy and DC agent, starting in audit mode.

Source: https://www.epifive.com/blog/entra-password-protection-on-premises-ad · Published 2026-10-19 · EpiFive

Microsoft Entra Password Protection extends the same global and custom banned password lists used in Entra ID to your on-premises Active Directory domain controllers. You install a proxy service on one or more member servers and a DC agent on every writable domain controller, register the forest and proxy with Entra ID, and then switch the policy from audit mode to enforced mode once you have seen its impact.

This guide walks through the full deployment in the order that avoids surprises: licensing and prerequisites, the proxy, forest registration, the DC agent, policy configuration, verification through event logs and PowerShell, and troubleshooting.

## Who this is for and what you will have

This is for identity and Active Directory administrators in hybrid environments who want to stop users and help desks from setting passwords such as a company name followed by a year. It also applies to domains that are not synchronized to Entra ID at all, because on-premises users that are not synchronized benefit from the licensing of synchronized users.

At the end you will have:

- A password filter running on every writable domain controller that rejects passwords matching the Microsoft global banned list and your custom list.
- A policy that started in audit mode, with a clear way to read what it would have blocked.
- Monitoring through the DC agent event logs and the `AzureADPasswordProtection` PowerShell module.
- A rollback path if the agent causes problems.

If you also let users change passwords in the cloud and write them back, see [Entra SSPR with password writeback](https://www.epifive.com/blog/entra-sspr-setup-password-writeback). Those changes are validated in Entra ID first, so the on-premises agent never sees a rejection for them.

## How it works

Three components cooperate:

| Component | Where it runs | What it does |
| --- | --- | --- |
| Proxy service | Any domain-joined member server in the forest | Forwards policy download requests from DCs to Entra ID and returns the answer. It is stateless and caches nothing. |
| DC agent | Every writable domain controller | Its password filter DLL receives password validation requests from Windows and passes them to the local DC agent service, which returns pass or fail using the cached policy. |
| Policy | Entra ID, cached in SYSVOL | The combination of the global banned list and your tenant's custom list, plus the enabled and audit/enforce settings. |

The design principles Microsoft documents are worth knowing because they answer most security review questions:

- Domain controllers never need to talk to the internet. Only the proxy does.
- No new network ports are opened on domain controllers, and the DC agent never listens on a network port.
- No schema changes are made. The software uses existing container and serviceConnectionPoint objects.
- Clear-text passwords never leave the domain controller.
- Any supported domain or forest functional level works.

The flow is: the proxy advertises itself by creating a serviceConnectionPoint object, the DC agent finds it by querying the forest, and the DC agent asks it to download the policy from Entra ID. The agent stores the policy in a dedicated folder at the root of the domain SYSVOL share, which means other DCs receive it through replication. The agent requests a new policy at service start and then checks the policy age hourly, downloading a new one if it is more than an hour old.

Two behaviors matter for planning. First, if no policy is available on a DC, passwords are accepted and a warning event is logged, so a broken deployment fails open. Second, the feature supplements your existing AD password policy and any other password filter DLLs. AD only accepts a password when all validation components agree.

## Prerequisites and licensing

### Licensing

| Users | Global banned list | Custom banned list |
| --- | --- | --- |
| Cloud-only users | Entra ID Free | Entra ID P1 or P2 |
| Users synchronized from on-premises AD DS | Entra ID P1 or P2 | Entra ID P1 or P2 |

### Environment requirements

- Universal C Runtime on every machine with a component installed (Windows Update normally covers this).
- .NET Framework 4.7.2 on the DC agent and proxy machines.
- Windows Server 2012 R2 or later for both the DC agent and the proxy, including Server Core.
- DFSR for SYSVOL replication in every domain that runs the DC agent. The agent installs on FRS domains but does not work correctly there, so migrate to DFSR first.
- The Key Distribution Service must be enabled on domain controllers running Windows Server 2012 and later. The default of manual trigger start is fine.
- Network connectivity from at least one DC in each domain to a proxy server on RPC endpoint mapper port 135 and the proxy's RPC server port. By default that is a dynamic port in the range 49152 to 65535, and you can pin it to a static port.
- Proxy hosts must be able to reach `https://login.microsoftonline.com`, `https://enterpriseregistration.windows.net` and `https://autoupdate.msappproxy.net` over TLS 1.2, plus the ports and URLs listed for Microsoft Entra application proxy connectors.
- Domain controllers must be granted "Access this computer from the network" on the proxy host.
- The Windows Firewall service must be running when you install the proxy.
- Do not install the proxy on the same machine as Microsoft Entra application proxy. The two install incompatible versions of the Connect Agent Updater. Co-locating the proxy with Entra Connect is fine.

### Accounts

- Global Administrator for the first proxy registration in a tenant. Later proxy and forest registrations can use at least Security Administrator.
- Active Directory Enterprise Administrator and local administrator rights to run forest registration, and a domain administrator in the forest root domain.
- At least Authentication Administrator to enable the policy in the Entra admin center.

### Design decisions

- Plan at least two proxy servers per forest. DC agents round-robin across proxies and skip any that do not respond. If every proxy is down, agents keep enforcing their cached policy.
- Each forest and every proxy in it must register to the same Entra tenant. Multi-tenant organizations must pick one tenant per forest.
- Each proxy serves a single forest. Multiple forests are configured independently, and agents in one forest know nothing about another.
- Do not install the DC agent on read-only domain controllers, because password changes are forwarded to writable DCs. Running the proxy on an RODC is not supported.
- You can run the proxy on a DC for testing, but then that DC needs internet access. Use a member server in production.

## Step 1: Install and register the proxy

Download both installers from the Microsoft Download Center (`https://www.microsoft.com/download/details.aspx?id=57071`): `AzureADPasswordProtectionProxySetup.exe` and `AzureADPasswordProtectionDCAgentSetup.msi`.

On each proxy server, run the installer. No reboot is needed.

```powershell
.\AzureADPasswordProtectionProxySetup.exe /quiet
```

Open an elevated 64-bit PowerShell session (some cmdlets fail in the x86 shell), import the module and confirm the service is running.

```powershell
Import-Module AzureADPasswordProtection
Get-Service AzureADPasswordProtectionProxy | fl
```

The service is running but has no credentials yet. Register the proxy. Interactive mode does not work on Server Core, so use device code there.

```powershell
# Interactive (supports MFA)
Register-AzureADPasswordProtectionProxy -AccountUpn 'admin@contoso.com'

# Device code (supports MFA, works on Server Core)
Register-AzureADPasswordProtectionProxy -AccountUpn 'admin@contoso.com' -AuthenticateUsingDeviceCode
```

A silent mode using `-AzureCredential` exists, but it fails when MFA is required for the account, which is the normal state of a privileged account. The first registration against a tenant can pause noticeably before completing; Microsoft says not to worry unless a failure is reported. Registration is needed once in the life of the proxy.

### Optional: HTTP proxy and static port

If the proxy server must use an HTTP proxy to reach Azure, create `AzureADPasswordProtectionProxy.exe.config` in `%ProgramFiles%\Azure AD Password Protection Proxy\Service` and restart the service.

```xml
<configuration>
   <system.net>
      <defaultProxy enabled="true">
      <proxy bypassonlocal="true"
         proxyaddress="http://proxy.contoso.com:8080" />
      </defaultProxy>
   </system.net>
</configuration>
```

Add `useDefaultCredentials="true"` to `defaultProxy` if the proxy needs authentication. The service cannot use specific stored credentials for an HTTP proxy, so grant the proxy host's computer account access instead.

To pin the RPC port so firewall rules are predictable, set a static port and restart the proxy service. Ports 135 and your chosen port must then be open.

```powershell
Set-AzureADPasswordProtectionProxyConfiguration -StaticPort 49200
Restart-Service AzureADPasswordProtectionProxy
Get-AzureADPasswordProtectionProxyConfiguration | fl
```

The port number here is an example; choose one that suits your network. Setting `-StaticPort 0` returns the service to dynamic ports.

## Step 2: Register the forest

Forest registration happens once per forest and can be run from any proxy. You need Enterprise Admin rights and local administrator rights, and the Azure account can differ from the AD account.

```powershell
Register-AzureADPasswordProtectionForest -AccountUpn 'admin@contoso.com' -AuthenticateUsingDeviceCode
```

If the signed-in user is not a domain administrator in the root domain, pass different AD credentials with `-ForestCredential`. At least one DC running Windows Server 2012 or later must be reachable from the proxy's domain. The DC agent does not need to be installed yet, and Microsoft states that any order of proxy install, DC agent install, forest registration and proxy registration is supported.

Check that registration took effect:

```powershell
Test-AzureADPasswordProtectionProxyHealth -TestAll
```

A healthy run lists `VerifyTLSConfiguration`, `VerifyProxyRegistration` and `VerifyAzureConnectivity` as `Passed`.

## Step 3: Install the DC agent

Install the MSI on each writable domain controller. A restart is required because password filter DLLs are only loaded at boot. Plan this across DCs and avoid rebooting them all at once.

```powershell
msiexec.exe /i AzureADPasswordProtectionDCAgentSetup.msi /quiet /qn /norestart
```

There is nothing else to configure on the DC. You can also install it on a server that is not yet a DC; it stays inactive until promotion. Upgrades run the newer MSI in place and also need a reboot. The proxy supports automatic upgrade through the Connect Agent Updater service, but the DC agent does not.

To see which agents and proxies exist and which software versions they run:

```powershell
Get-AzureADPasswordProtectionDCAgent
Get-AzureADPasswordProtectionProxy
```

Both show the registered `AzureTenant`, which should be identical across every item. These cmdlets read serviceConnectionPoint objects, so values are subject to AD replication latency. A stale `HeartbeatUTC` suggests the service is stopped, uninstalled or the machine was demoted.

## Step 4: Enable the policy in audit mode

Policy is administered only in Entra ID; it cannot be edited at the Active Directory level.

1. Sign in to the [Microsoft Entra admin center](https://entra.microsoft.com) as at least Authentication Administrator.
2. Go to **Entra ID** > **Authentication methods** > **Password protection**.
3. Set **Enable password protection on Windows Server Active Directory** to **Yes**. When this is **No**, every agent goes quiescent: all passwords are accepted, nothing is validated and no audit events are generated.
4. Set **Mode** to **Audit**.
5. Optionally set **Enforce custom list** to **Yes** and add terms, one per line. The list is case-insensitive, takes up to 1,000 terms, treats common substitutions such as "o" and "0" as equivalent, and each term must be 4 to 16 characters long. Updates can take several hours to apply in Entra ID.
6. Select **Save**.

Audit mode is the default recommendation. A password that would be blocked is accepted but logged. Leave it on for a meaningful period, and include at least one DC promotion and one demotion in that window, because DSRM and local administrator passwords go through the same filter (see troubleshooting).

### Choose custom terms well

Put base terms in the list, not variations. For a company named Contoso in London that makes a product called Widget, add `Contoso`, `London` and `Widget`. The algorithm handles variants and combinations.

Passwords are evaluated like this:

1. Normalization converts uppercase to lowercase and substitutes characters such as 0 to o, 1 to l, $ to s and @ to a.
2. Fuzzy matching finds banned terms within an edit distance of one.
3. Substring matching checks the user's first and last name (four characters or more). Tenant name matching is not performed on domain controllers.
4. Scoring gives one point per banned term found and one per remaining character. A password needs at least five points.

In Microsoft's example, `C0ntos0Blank12` normalizes to `contosoblank12`, contains two banned terms, scores four points and is rejected. `ContoS0Bl@nkf9!` scores five and is accepted. Microsoft notes the algorithm and global list can change at any time, and on-premises agents only get algorithm changes when upgraded.

The cloud and on-premises checks are described separately by Microsoft and may not give identical results for the same password, so test against the on-premises policy rather than assuming.

## Step 5: Verify and read the results

### Check the policy arrived

Open **Applications and Services Logs** > **Microsoft** > **AzureADPasswordProtection** > **DCAgent** > **Admin** on a DC. Event 30006 shows the policy in force:

```text
The service is now enforcing the following Azure password policy.

Enabled: 1
AuditOnly: 1
Global policy date: 2018-05-15T00:00:00.000000000Z
Tenant policy date: 2018-06-10T20:15:24.432457600Z
Enforce tenant policy: 1
```

`AuditOnly: 1` means audit mode, and `0` means enforced. Restarting the DC agent service forces a policy sync, producing two 30006 events: the first for the policy cached in SYSVOL and the second for the one downloaded from Azure. The agent also syncs hourly, so changes are not immediate. Changes to the custom list are not reflected in the event text.

### Key event IDs

| Outcome | Password change | Password set |
| --- | --- | --- |
| Pass | 10014 | 10015 |
| Fail, customer list | 10016, 30002 | 10017, 30003 |
| Fail, Microsoft list | 10016, 30004 | 10017, 30005 |
| Fail, both lists | 10016, 30026 | 10017, 30027 |
| Fail, user name | 10016, 30021 | 10017, 30022 |
| Audit-only pass, customer list | 10024, 30008 | 10025, 30007 |
| Audit-only pass, Microsoft list | 10024, 30010 | 10025, 30009 |
| Audit-only pass, both lists | 10024, 30028 | 10025, 30029 |

A change is a user choosing a new password knowing the old one. A set is an administrator replacing it, including help desk resets and creation of a new account. The policy treats both the same, but the events differ. Paired events share a CorrelationId.

### Summary report

```powershell
Get-AzureADPasswordProtectionSummaryReport -Domain contoso.com
```

The report counts events such as `PasswordChangesValidated`, `PasswordSetsRejected` and `PasswordChangeAuditOnlyFailures`. Scope it with `-Forest`, `-Domain` or `-DomainController`; the default is the whole forest. It opens a PowerShell remote session to each DC and queries the Admin log, so enable remoting and use it sparingly on busy production DCs. Reading the audit-only counters before enforcement tells you how many users would be affected.

### Test on a lab DC

For a repeatable test, reset a test account's password from the command line on a DC in a test environment, restarting the agent after policy changes (`net stop AzureADPasswordProtectionDCAgent && net start AzureADPasswordProtectionDCAgent`). Remember that while the agent service is stopped, all passwords are accepted. Delete test accounts afterward.

## Step 6: Switch to enforced mode

After the audit period, change **Mode** to **Enforced** and save. Watch the Admin log closely for the following days. Affected users see the usual Windows complexity error, for example: "Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain." You cannot customize this text because the client machine controls it, so brief the help desk and users in advance.

Existing passwords are not validated retroactively. Users move to validated passwords as they expire, and you can accelerate this with a one-time manual expiry. For a related approach to reducing password reliance altogether, see [passkeys in Entra ID](https://www.epifive.com/blog/passkeys-entra-id-deployment-guide).

## Troubleshooting

| Symptom | Likely cause and fix |
| --- | --- |
| Event 30001: password accepted because no policy is available | Forest not registered, no proxy registered, no connectivity from the DC to a proxy, or no connectivity to other DCs. Fix whichever applies. |
| Event 30016: forest has not been registered | Run `Register-AzureADPasswordProtectionForest`. If it appears only on Windows Server 2012 or 2012 R2 DCs, the KDS buffer format difference is the cause. |
| Event 30017: cannot locate a proxy | No proxy is registered, or AD replication has not yet delivered it. |
| Event 30018: cannot communicate with a proxy | Port 135 or the proxy RPC port blocked, firewall rules removed, or DCs lack "Access this computer from the network" on the proxy host. |
| Proxy cannot reach Azure | Check the required endpoints. Compare `AzureTenant` on all agents and proxies and re-run the registration cmdlets with the same tenant if they differ. |
| Encrypt or decrypt errors | KDS is disabled, or the DC object is outside the default Domain Controllers OU. Mixing 2012/2012 R2 with 2016 or later DCs can cause intermittent failures. |
| Weak passwords still accepted | Policy still in Audit, policy disabled, no policy downloaded, agent missing on some DCs, or the algorithm scored the password as acceptable. |

### Directory Services Repair Mode passwords

Because the filter validates DSRM passwords, `ntdsutil` can fail with:

```text
Setting password failed.
        WIN32 Error Code: 0xa91
        Error Message: Password doesn't meet the requirements of the filter dll's
```

Promotion can fail with: "The Directory Services Restore Mode password doesn't meet a requirement of the password filter(s). Supply a suitable password." Demotion validates the new local Administrator password the same way. Update automation to use strong values. Events for these cases have empty user names, and a DC booted into DSRM disables validation and logs event 10023.

### Emergency rollback

Stop the DC agent service (the filter then accepts all passwords but logs warning events 10012 and 10013) and optionally set its startup type to Disabled. Alternatively set **Enable password protection on Windows Server Active Directory** to **No** and wait for agents to download the updated policy.

### Removal

Remove in order, because running services recreate their state: uninstall the proxy everywhere, uninstall the DC agent from all DCs (reboot required), then delete the proxy and DC agent serviceConnectionPoint objects, the `CN=Azure AD Password Protection,CN=Services` container in the configuration naming context, and the `AzureADPasswordProtection` folder under the domain SYSVOL.

## Operational notes

- Expect at least 5 MB of SYSVOL space for the policy files.
- Custom smart lockout settings in Entra ID do not affect on-premises AD.
- Audit mode applies only on-premises. Entra ID always enforces its own checks.
- Text logging for the agent is off by default; enable it with the `EnableTextLogging` registry value only while investigating, since it is high volume.
- Use `Test-AzureADPasswordProtectionDCAgentHealth -TestAll` for checks such as filter DLL loading, forest registration, KDS encryption, DFSR and Azure connectivity.

For wider hardening that complements this, pair it with [Conditional Access policies](https://www.epifive.com/blog/zero-trust-identity-device-access-policies) so a guessed password alone is not enough.

## Checklist

- [ ] Licences confirmed for your user types, and DFSR in use on all domains.
- [ ] Two or more proxy servers installed and registered, forest registered to the same tenant.
- [ ] DC agent installed and rebooted on every writable DC, not on RODCs.
- [ ] Policy enabled in audit mode, with base terms in the custom list.
- [ ] Event 30006 seen on each DC, and the summary report reviewed.
- [ ] DC promotion and demotion tested during the audit period.
- [ ] Help desk and users informed, then mode switched to Enforced.
- [ ] Event log alerts set for 30001, 30016, 30017 and 30018, and a stale `HeartbeatUTC`.

## References

- https://learn.microsoft.com/en-us/entra/identity/authentication/concept-password-ban-bad-on-premises
- https://learn.microsoft.com/en-us/entra/identity/authentication/howto-password-ban-bad-on-premises-deploy
- https://learn.microsoft.com/en-us/entra/identity/authentication/howto-password-ban-bad-on-premises-operations
- https://learn.microsoft.com/en-us/entra/identity/authentication/howto-password-ban-bad-on-premises-monitor
- https://learn.microsoft.com/en-us/entra/identity/authentication/howto-password-ban-bad-on-premises-troubleshoot
- https://learn.microsoft.com/en-us/entra/identity/authentication/howto-password-ban-bad-on-premises-faq
- https://learn.microsoft.com/en-us/entra/identity/authentication/concept-password-ban-bad
- https://learn.microsoft.com/en-us/entra/identity/authentication/tutorial-configure-custom-password-protection

## Frequently asked questions

### Does Entra Password Protection check passwords that already exist in Active Directory?

No. It can only evaluate a clear-text password during a password change or set operation. Passwords accepted before deployment keep working until they are changed. Accounts set to "password never expires" are not forced to change unless you expire their passwords manually.

### Do I need Microsoft Entra Connect or password hash sync for on-premises password protection?

No. The software does not depend on other Microsoft Entra features, and password hash sync is not required. You do need an Entra tenant with the right licence, because the policy and the banned lists are stored and administered in Entra ID.

### Does it have to be installed on every domain controller?

For consistent enforcement, yes. The DC agent only validates password changes that land on the domain controller it runs on, and you cannot control which domain controller a client chooses. Partial deployments are supported for testing only. Read-only domain controllers do not need the agent.

### Can I apply on-premises password protection to only some users?

No. Once deployed and enabled, it applies equally to all users in the forest. Microsoft documents scoping it to a subset of users as not supported.

