Skip to content

Instantly share code, notes, and snippets.

@adiberr
Last active March 8, 2026 01:57
Show Gist options
  • Select an option

  • Save adiberr/961cd388415824be19ec451f28024f5d to your computer and use it in GitHub Desktop.

Select an option

Save adiberr/961cd388415824be19ec451f28024f5d to your computer and use it in GitHub Desktop.
Setting up AD LDS locally for development

AD LDS Setup on Windows Server 2022 Core

1. Download & Install

  • Get ISO from Microsoft Evaluation Center
  • Install in Proxmox VM: 2 vCPU, 4GB RAM, 50GB disk, VirtIO network
  • Pick Windows Server 2022 Standard (no Desktop Experience)

2. Install VirtIO Network Driver

pnputil /add-driver D:\NetKVM\2k22\amd64\*.inf /install

3. Set Static IP

$i = (Get-NetAdapter).ifIndex
New-NetIPAddress -InterfaceIndex $i -IPAddress 192.168.1.100 -PrefixLength 24 -DefaultGateway 192.168.1.1
Set-DnsClientServerAddress -InterfaceIndex $i -ServerAddresses ("8.8.8.8","8.8.4.4")

4. Enable SSH

Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22

5. Install AD LDS

Install-WindowsFeature ADLDS

6. Create Answer File & Run Setup

Set-Content C:\Users\Administrator\Documents\answer.txt @"
[ADAMInstall]
InstallType=Unique
InstanceName=TestLDS
LocalLDAPPortToListenOn=389
LocalSSLPortToListenOn=636
NewApplicationPartitionToCreate=CN=App,DC=ma,DC=local
DataFilesPath=C:\ADAM\data
LogFilesPath=C:\ADAM\logs
ServiceAccount=WIN-6Q4NTRN07G2\Administrator
ServicePassword=YourPassword
AddPermissionsToServiceAccount=Yes
Administrator=WIN-6Q4NTRN07G2\Administrator
ImportLDIFFiles=MS-User.LDF
SourceUserName=WIN-6Q4NTRN07G2\Administrator
SourcePassword=YourPassword
"@

& "C:\Windows\ADAM\ADAMInstall.exe" /answer:C:\Users\Administrator\Documents\answer.txt
# Output: You have successfully completed the AD LDS Setup Wizard.

7. Populate Directory

Set-Content C:\Users\Administrator\Documents\populate.ldf @"
dn: CN=People,CN=App,DC=ma,DC=local
changetype: add
objectClass: container
cn: People

dn: CN=Roles,CN=App,DC=ma,DC=local
changetype: add
objectClass: container
cn: Roles

dn: CN=admin,CN=Roles,CN=App,DC=ma,DC=local
changetype: add
objectClass: group
cn: admin

dn: CN=developer,CN=Roles,CN=App,DC=ma,DC=local
changetype: add
objectClass: group
cn: developer

dn: CN=viewer,CN=Roles,CN=App,DC=ma,DC=local
changetype: add
objectClass: group
cn: viewer

dn: CN=jdoe,CN=People,CN=App,DC=ma,DC=local
changetype: add
objectClass: user
cn: jdoe
givenName: John
sn: Doe
mail: jdoe@ma.local
userPrincipalName: jdoe@ma.local

dn: CN=asmith,CN=People,CN=App,DC=ma,DC=local
changetype: add
objectClass: user
cn: asmith
givenName: Alice
sn: Smith
mail: asmith@ma.local
userPrincipalName: asmith@ma.local

dn: CN=blee,CN=People,CN=App,DC=ma,DC=local
changetype: add
objectClass: user
cn: blee
givenName: Bob
sn: Lee
mail: blee@ma.local
userPrincipalName: blee@ma.local

dn: CN=admin,CN=Roles,CN=App,DC=ma,DC=local
changetype: modify
add: member
member: CN=jdoe,CN=People,CN=App,DC=ma,DC=local
-

dn: CN=developer,CN=Roles,CN=App,DC=ma,DC=local
changetype: modify
add: member
member: CN=asmith,CN=People,CN=App,DC=ma,DC=local
-

dn: CN=developer,CN=Roles,CN=App,DC=ma,DC=local
changetype: modify
add: member
member: CN=blee,CN=People,CN=App,DC=ma,DC=local
-

dn: CN=viewer,CN=Roles,CN=App,DC=ma,DC=local
changetype: modify
add: member
member: CN=blee,CN=People,CN=App,DC=ma,DC=local
-
"@

ldifde -i -f C:\Users\Administrator\Documents\populate.ldf -s localhost:389 -b "Administrator" "WIN-6Q4NTRN07G2" "YourPassword" -k

8. Allow Password Set Over Unsecured Connection

dsmgmt "DS Behavior" "Connections" "Connect to server localhost:389" "q" "Allow Passwd op on unsecured connection" "q" "q"
# Output: Successfully modified AD DS/LDS Behavior to reset password over unsecured network.

9. Set User Passwords

$pass = "UserP@ssw0rd!"
$encoded = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("`"$pass`""))

Set-Content C:\Users\Administrator\Documents\setpwd.ldf @"
dn: CN=jdoe,CN=People,CN=App,DC=ma,DC=local
changetype: modify
replace: unicodePwd
unicodePwd:: $encoded
-

dn: CN=asmith,CN=People,CN=App,DC=ma,DC=local
changetype: modify
replace: unicodePwd
unicodePwd:: $encoded
-

dn: CN=blee,CN=People,CN=App,DC=ma,DC=local
changetype: modify
replace: unicodePwd
unicodePwd:: $encoded
-
"@

ldifde -i -f C:\Users\Administrator\Documents\setpwd.ldf -s localhost:389 -b "Administrator" "WIN-6Q4NTRN07G2" "YourPassword" -k
# Output: 3 entries modified successfully.

10. Create Bind User

Set-Content C:\Users\Administrator\Documents\binduser.ldf @"
dn: CN=binduser,CN=People,CN=App,DC=ma,DC=local
changetype: add
objectClass: user
cn: binduser
givenName: Bind
sn: User
mail: binduser@ma.local
userPrincipalName: binduser@ma.local
"@

ldifde -i -f C:\Users\Administrator\Documents\binduser.ldf -s localhost:389 -b "Administrator" "WIN-6Q4NTRN07G2" "YourPassword" -k
# Set password
$pass = "BindP@ssw0rd!"
$encoded = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("`"$pass`""))

Set-Content C:\Users\Administrator\Documents\setbindpwd.ldf @"
dn: CN=binduser,CN=People,CN=App,DC=ma,DC=local
changetype: modify
replace: unicodePwd
unicodePwd:: $encoded
-
"@

ldifde -i -f C:\Users\Administrator\Documents\setbindpwd.ldf -s localhost:389 -b "Administrator" "WIN-6Q4NTRN07G2" "YourPassword" -k
# Output: 1 entry modified successfully.
# Enable account (disabled by default in AD LDS)
Set-Content C:\Users\Administrator\Documents\enable-binduser.ldf @"
dn: CN=binduser,CN=People,CN=App,DC=ma,DC=local
changetype: modify
replace: msDS-UserAccountDisabled
msDS-UserAccountDisabled: FALSE
-
"@

ldifde -i -f C:\Users\Administrator\Documents\enable-binduser.ldf -s localhost:389 -b "Administrator" "WIN-6Q4NTRN07G2" "YourPassword" -k
# Output: 1 entry modified successfully.

11. Grant Bind User Read Access

$root = New-Object System.DirectoryServices.DirectoryEntry("LDAP://localhost:389/CN=App,DC=ma,DC=local", "WIN-6Q4NTRN07G2\Administrator", "YourPassword")
$acl = $root.ObjectSecurity

$binduser = New-Object System.DirectoryServices.DirectoryEntry("LDAP://localhost:389/CN=binduser,CN=People,CN=App,DC=ma,DC=local", "WIN-6Q4NTRN07G2\Administrator", "YourPassword")
$sid = New-Object System.Security.Principal.SecurityIdentifier($binduser.ObjectSid[0], 0)

$rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $sid,
    [System.DirectoryServices.ActiveDirectoryRights]::GenericRead,
    [System.Security.AccessControl.AccessControlType]::Allow,
    [System.DirectoryServices.ActiveDirectorySecurityInheritance]::All
)
$acl.AddAccessRule($rule)
$root.ObjectSecurity = $acl
$root.CommitChanges()

Final LDAP Tree

CN=App,DC=ma,DC=local
├── CN=People
│   ├── CN=jdoe      (John Doe,    jdoe@ma.local,    pw: UserP@ssw0rd!)
│   ├── CN=asmith    (Alice Smith, asmith@ma.local,  pw: UserP@ssw0rd!)
│   ├── CN=blee      (Bob Lee,     blee@ma.local,    pw: UserP@ssw0rd!)
│   └── CN=binduser  (bind account for LDAP clients, pw: BindP@ssw0rd!)
└── CN=Roles
    ├── CN=admin      → jdoe
    ├── CN=developer  → asmith, blee
    └── CN=viewer     → blee

Apache Directory Studio

Download from: https://directory.apache.org/studio/downloads.html

New connection wizard — Network tab:

Field Value
Connection name AD LDS Local
Hostname 192.168.1.100
Port 389
Encryption No encryption
Provider Apache Directory LDAP Client API

Authentication tab:

Field Value
Authentication method Simple Authentication
Bind DN CN=binduser,CN=People,CN=App,DC=ma,DC=local
Bind password BindP@ssw0rd!

Click Check Network Parameter → then Check AuthenticationFinish.
You should see the tree under CN=App,DC=ma,DC=local in the LDAP Browser view.


Keycloak LDAP Connection

Field Value
Connection URL ldap://192.168.1.100:389
Bind DN CN=binduser,CN=People,CN=App,DC=ma,DC=local
Bind Password BindP@ssw0rd!
User DN CN=People,CN=App,DC=ma,DC=local
Username Attribute userPrincipalName
RDN Attribute cn
UUID Attribute objectGUID
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment