Set up on-premises Active Directory sync
AutoPhish can mirror the complete membership of selected on-premises Active Directory groups into managed target lists. A signed PowerShell tool runs inside your Windows domain and sends complete group snapshots to the AutoPhish public API over HTTPS.
AutoPhish never connects inbound to your domain controllers, and the ZIP file never contains your API key or Active Directory credentials.
Beta: On-premises Active Directory sync is currently a beta feature.
How it works
Active Directory domain controllers
↑
| Read-only AD queries
|
Domain-joined Windows member server
AutoPhish Scheduled Task under a gMSA
|
| Outbound HTTPS 443
↓
AutoPhish public API
↓
Managed AutoPhish target lists
The local tool:
- Fetches enabled group mappings from AutoPhish.
- Resolves every group by its stable
objectGUID. - Reads recursive group membership and the required user attributes.
- Builds one complete snapshot in memory.
- Uploads the snapshot to AutoPhish.
- AutoPhish validates it and atomically reconciles the managed target list.
AutoPhish does not remotely execute the tool. Windows Task Scheduler controls when it runs.
Requirements
You need:
- Company-admin access in AutoPhish.
- A domain-joined Windows Server 2019, 2022, or 2025 that is always available.
- Windows PowerShell 5.1 or newer.
- The RSAT Active Directory PowerShell module.
- A pre-created group Managed Service Account (gMSA).
- Outbound HTTPS access to your exact AutoPhish hostname.
- DNS, Kerberos, AD DS, and Active Directory Web Services connectivity from the sync server to your domain controllers.
- At least one Active Directory group to map.
- Verified email domains configured in AutoPhish.
Use a normal member server, not a domain controller. A small dedicated management or integration server is preferred. Installing the tool on a domain controller is unnecessary and places the API credential, Scheduled Task, scripts, and logs on a Tier-0 system.
Version 1 supports one Active Directory connection per AutoPhish company, one forest, and up to 10,000 recursively resolved users per mapped group. Installing the sync server in the same domain as the mapped groups is recommended.
Network requirements
No inbound connection from AutoPhish is required.
Allow the sync server to make outbound TCP 443 connections to the exact hostname shown as baseUrl in the downloaded config.json. The tool uses the Windows system proxy configuration where applicable.
The AutoPhish hostname must present a certificate that:
- is valid for that hostname;
- chains to a certificate authority trusted by Windows; and
- is within its validity period.
The tool never disables certificate validation and refuses non-HTTPS URLs. It also:
- rejects origins containing credentials, paths, query strings, or fragments;
- restricts requests to
/api/v1/directory-sync/; and - does not follow HTTP redirects.
AutoPhish does not pin the public TLS certificate or the Let’s Encrypt certificate authority. Public certificates and issuing chains rotate, and pinning a public CA would not uniquely identify AutoPhish.
If your organization performs TLS inspection, its trusted interception CA may decrypt the connection. If end-to-end TLS is required, exclude the exact AutoPhish hostname from TLS inspection.
For strict data-egress control, create an outbound firewall or proxy allowlist for the exact AutoPhish FQDN on TCP 443. Do not create a broad allow rule for all Let’s Encrypt destinations.
The client-side URL and redirect checks provide defense in depth, but an exact-FQDN network allowlist is the strongest way to prevent directory data from being sent to another destination.
Step 1: Prepare the sync server
Join the Windows Server to the Active Directory domain containing the groups you want to synchronize.
Open an elevated Windows PowerShell prompt and install the Active Directory administration tools:
Install-WindowsFeature -Name RSAT-AD-Tools -IncludeAllSubFeature
Import-Module ActiveDirectory
Get-ADDomain
Get-ADDomain must return the expected domain without prompting for alternate credentials.
Step 2: Create a read-only gMSA
Run the following commands from an authorized Active Directory administration host. Replace the example names before running them:
$SyncServer = 'AP-SYNC01'
$SyncHostGroup = 'AutoPhishSyncHosts'
$ServiceAccount = 'AutoPhishSync'
$Domain = Get-ADDomain
$DomainDnsName = $Domain.DNSRoot
$ServiceAccountPath = $Domain.UsersContainer
New-ADGroup `
-Name $SyncHostGroup `
-SamAccountName $SyncHostGroup `
-GroupScope Global `
-GroupCategory Security `
-Path $ServiceAccountPath
Add-ADGroupMember `
-Identity $SyncHostGroup `
-Members "${SyncServer}$"
New-ADServiceAccount `
-Name $ServiceAccount `
-DNSHostName "${ServiceAccount}.${DomainDnsName}" `
-PrincipalsAllowedToRetrieveManagedPassword $SyncHostGroup
Change $ServiceAccountPath first if your organization uses a dedicated service-account organizational unit.
If the forest does not already have a KDS root key, have an Active Directory administrator create one according to your organization’s gMSA procedure and allow time for replication.
After adding the server to the host group, restart the sync server so its computer-account group membership is refreshed.
On the sync server, run:
Install-ADServiceAccount -Identity 'AutoPhishSync'
Test-ADServiceAccount -Identity 'AutoPhishSync'
The final command must return True.
Do not add the gMSA to Domain Admins, Account Operators, Server Operators, or local Administrators. Normal authenticated read access is sufficient in a standard Active Directory deployment.
If your organization has restricted directory ACLs, delegate read access only to the mapped groups and the required user attributes.
Step 3: Create the Active Directory connection
- Sign in to AutoPhish as a company admin.
- Select the correct active company.
- Open Settings → Directory Sync → On-Prem Active Directory.
- Select Create connection.
Only one on-premises Active Directory connection can exist per company.
Step 4: Add group mappings
Find the stable GUID of each Active Directory group:
Get-ADGroup -Identity 'Finance' |
Select-Object Name, DisplayName, ObjectGUID, GroupCategory
In AutoPhish, enter:
- Group display name: A recognizable label for administrators.
- objectGUID: The exact GUID returned by Active Directory.
Select Add mapping. AutoPhish creates a managed target list for the group.
The display name is informational. Every sync resolves the group by its stable objectGUID.
Do not manually edit a managed target list. Pause or unlink its mapping first if manual management is required.
Step 5: Create the sync API key
On the Active Directory setup page, select Generate one-time key.
The generated key:
- has only the
directory-sync:writescope; - is assigned only to the active company;
- is shown once;
- remains tied to the company authorization of the administrator who created it; and
- is never placed in the ZIP file.
Copy it immediately and keep the page open until installation is complete.
Do not place the key in a command-line argument, script, ticket, or log.
Step 6: Download and verify the ZIP
Select Download configured ZIP. AutoPhish displays the SHA-256 checksum returned with the download.
Verify the downloaded archive before extracting it:
Get-FileHash `
-LiteralPath '.\AutoPhish-AD-Sync-1.0.0.zip' `
-Algorithm SHA256
The hash must match the checksum displayed by AutoPhish.
Extract the archive:
Expand-Archive `
-LiteralPath '.\AutoPhish-AD-Sync-1.0.0.zip' `
-DestinationPath '.\AutoPhish-AD-Sync'
Set-Location '.\AutoPhish-AD-Sync\AutoPhish-AD-Sync'
Inspect the non-secret configuration:
Get-Content -LiteralPath '.\config.json'
Confirm that baseUrl is the exact expected AutoPhish HTTPS origin. It must not contain a path, query string, or fragment.
The file also contains non-secret company and connection IDs, the tool version, timeout, and proxy preference. It must not contain the API key.
Check the installer signature:
Get-AuthenticodeSignature `
-LiteralPath '.\Install-AutoPhishDirectorySync.ps1' |
Format-List Status, StatusMessage, SignerCertificate
Status must be Valid. Do not install a package with a missing, unknown, or invalid signature.
Step 7: Install and validate the Scheduled Task
From an elevated Windows PowerShell 5.1 prompt in the extracted package directory, run:
Import-Module ActiveDirectory
$DomainNetBIOS = (Get-ADDomain).NetBIOSName
.\Install-AutoPhishDirectorySync.ps1 `
-ServiceAccount "${DomainNetBIOS}\AutoPhishSync$"
To choose a different daily schedule:
$DomainNetBIOS = (Get-ADDomain).NetBIOSName
.\Install-AutoPhishDirectorySync.ps1 `
-ServiceAccount "${DomainNetBIOS}\AutoPhishSync$" `
-DailyAt '02:00' `
-RandomDelayMinutes 30
The installer securely prompts for the API key. Paste it only into that prompt.
Before enabling the recurring task, the installer validates the following in a temporary Scheduled Task running as the gMSA:
- package hashes and Authenticode signatures;
- gMSA availability;
- Active Directory read access;
- HTTPS API access;
- API-key scope and company assignment; and
- resolution and complete enumeration of every configured mapping.
If validation fails, the recurring task is not enabled.
When updating an existing installation, the installer restores the previous working installation if the update fails.
Installed files are stored in:
C:\Program Files\AutoPhish\DirectorySyncConfiguration, the encrypted credential, and logs are stored in:
C:\ProgramData\AutoPhish\DirectorySyncThe API key is protected with machine-scope Windows DPAPI. Directory ACLs permit access only to the gMSA, SYSTEM, and local administrators.
Step 8: Run the first sync
Start an immediate run:
Start-ScheduledTask -TaskName 'AutoPhish Directory Sync'
Check its status:
Get-ScheduledTask -TaskName 'AutoPhish Directory Sync'
Get-ScheduledTaskInfo -TaskName 'AutoPhish Directory Sync'
Review the local logs:
Get-ChildItem `
-LiteralPath 'C:\ProgramData\AutoPhish\DirectorySync\logs' `
-File |
Sort-Object LastWriteTime -Descending |
Select-Object -First 5 Name, Length, LastWriteTime
Return to the mapping in AutoPhish and open History.
A successful run shows source, added, updated, removed, and skipped counts together with the tool version.
Synchronization behavior
- Mappings are fetched from AutoPhish at every execution.
- Only enabled mappings are processed.
- Nested group membership is expanded recursively.
- User objects are loaded; computer objects are ignored.
- Disabled users are excluded from the managed target list.
mailis preferred, withuserPrincipalNameas fallback.- Email addresses are normalized and deduplicated.
- Users outside the company’s verified AutoPhish domains are skipped.
- An empty Active Directory group produces an empty managed target list.
- Each mapping is processed independently.
- Membership changes are atomic after the complete snapshot passes validation.
- A missing group, unresolved user, foreign security principal, directory query error, oversized group, API error, or interrupted enumeration uploads nothing for that mapping.
- When a snapshot fails, the existing target-list membership remains unchanged.
- API retries use the same client run ID, preventing the same snapshot from being applied twice.
The snapshot sent to AutoPhish contains:
- group GUID;
- group display name and category;
- collection time;
- tool version;
- user GUID;
- email address;
- user principal name;
- given name;
- surname; and
- enabled state.
It does not contain:
- passwords or password hashes;
- Active Directory bind credentials;
- group credentials;
- computer objects; or
- arbitrary Active Directory attributes.
Transport and package security
Two separate certificate controls are used:
- PowerShell package signing: Every
.ps1,.psm1, and.psd1file is Authenticode-signed. The installer verifies the signed release manifest, every file hash, every signature, and the expected signer-certificate SHA-256 fingerprint before trusting or installing the package. - HTTPS server authentication: API requests use the normal Windows TLS trust store and hostname validation. Certificate validation is never bypassed. Requests require a clean HTTPS base URL and do not follow redirects.
The Authenticode signer pin protects the PowerShell software package. It is not a pin for the website’s TLS certificate.
For strict egress control, allow only the exact AutoPhish FQDN on TCP 443. If TLS inspection is not acceptable for directory data, exclude that FQDN from interception.
Day-to-day administration
Run a sync immediately
Start-ScheduledTask -TaskName 'AutoPhish Directory Sync'
Pause a mapping
Use Pause in AutoPhish. The local task continues to run but skips that mapping.
Resume a mapping
Use Resume in AutoPhish. No local configuration change or new ZIP is required.
Unlink a mapping
Use Unlink in AutoPhish. The target list and its current members remain, and the list becomes manually manageable again.
Rotate the API key
- Generate a new
directory-sync:writekey in AutoPhish. - Download the current ZIP.
- Rerun the installer and enter the new key when prompted.
- Start an immediate sync and confirm success.
- Revoke the old key in AutoPhish.
Update the sync tool
Download the latest ZIP and rerun the installer with the existing gMSA and schedule.
The installer waits for an active run to finish and rolls back on validation failure.
Troubleshooting
Test-ADServiceAccount returns False
- Confirm that the sync server computer account belongs to the group in
PrincipalsAllowedToRetrieveManagedPassword. - Restart the server after changing that group membership.
- Confirm that the gMSA exists and that the domain has a valid KDS root key.
- Run
Install-ADServiceAccountagain from an elevated prompt.
The Active Directory module cannot be imported
Install-WindowsFeature -Name RSAT-AD-Tools -IncludeAllSubFeature
Import-Module ActiveDirectory
A group cannot be resolved
- Confirm that the
objectGUIDin AutoPhish matches the Active Directory group. - Confirm that the sync server can reach the domain containing that group.
- Confirm that the gMSA can read the group and its recursive members.
- For version 1, prefer groups from the sync server’s own domain.
The task reports an HTTPS or certificate error
- Confirm that
baseUrlinC:\ProgramData\AutoPhish\DirectorySync\config.jsonis the exact expected HTTPS origin. - Confirm that the server clock is correct.
- Confirm that the Windows trust store trusts the current certificate chain.
- Check whether a corporate proxy or TLS-inspection product is replacing the certificate.
- AutoPhish does not follow redirects; correct the configured base URL instead.
The API returns 401 or 403
- Confirm that the key has
directory-sync:write. - Confirm that it is assigned to the active AutoPhish company.
- Confirm that it has not been revoked.
- Confirm that the administrator who created it still has authorization for that company.
A mapping fails without changing its target list
This is deliberate fail-closed behavior.
Check the mapping history and local logs for:
- a missing group;
- an unresolved user;
- a foreign security principal;
- a permissions failure;
- the 10,000-member limit; or
- an API error.
AutoPhish does not remove members unless it receives a complete and valid snapshot.
Logs
Logs are stored under:
C:\ProgramData\AutoPhish\DirectorySync\logsThey contain timestamps, mapping and group IDs, counts, durations, HTTP status, and sanitized errors. API keys and member PII are not logged. Files are bounded and retained for 30 days.
Uninstall
Run from an elevated Windows PowerShell prompt:
& 'C:\Program Files\AutoPhish\DirectorySync\Uninstall-AutoPhishDirectorySync.ps1'
To remove local logs as well:
& 'C:\Program Files\AutoPhish\DirectorySync\Uninstall-AutoPhishDirectorySync.ps1' `
-RemoveLogs
Uninstall removes the Scheduled Task, installed scripts, configuration, and encrypted API key. It retains logs by default.
Revoke the API key and remove or unlink mappings separately in AutoPhish.
Security checklist
- The sync host is a member server, not a domain controller.
- The gMSA is not a privileged Active Directory or local administrator account.
- The server can reach only the required AutoPhish FQDN over outbound HTTPS.
- TLS inspection is explicitly accepted or bypassed for the AutoPhish FQDN.
- The ZIP checksum matches the value displayed by AutoPhish.
- The installer Authenticode signature is valid.
config.jsoncontains the expected HTTPSbaseUrland no API key.- The API key has only
directory-sync:writeand one company assignment. - The first Scheduled Task run completes successfully.
- Mapping history and member counts are plausible.
- The old API key is revoked after any key rotation.
Related Microsoft documentation
- Install Remote Server Administration Tools
- Manage group Managed Service Accounts
- Get-ADGroupMember
- PowerShell script signing
- DPAPI-backed credential export behavior
Updated on: 06/08/2026
Thank you!