Version: v1.3-dev Β |Β Last update: 2026-02 Β |Β Author: Jan Weis
Automate Active Directory delegation with reusable JSON templates.
Apply, audit, and revert permissions β consistently, transparently, and in seconds.
# 1. List all available templates
.\Invoke-ADDelegationTemplate.ps1 -ShowTemplates -TemplatePath .\templates
# 2. Apply template 101 to an OU
.\Invoke-ADDelegationTemplate.ps1 `
-Identity "Contoso\Helpdesk-Berlin" `
-Path "OU=UsersBerlin,DC=contoso,DC=local" `
-TemplateIDs 101 `
-TemplatePath .\templates
# 3. Apply with change logging (for easy rollback)
.\Invoke-ADDelegationTemplate.ps1 `
-Identity "Contoso\Helpdesk-Berlin" `
-Path "OU=UsersBerlin,DC=contoso,DC=local" `
-TemplateIDs 101,102 `
-TemplatePath .\templates `
-LogChanges `
-LogPath "$env:USERPROFILE\DelegationLog.log"| Requirement | Details |
|---|---|
| PowerShell | Version 3.0 or later |
| Module | ActiveDirectory (RSAT or AD DS role) |
| Permissions | Must be able to modify ACLs on the target OU/object |
| Parameter | Type | Description |
|---|---|---|
-Identity |
string |
AD principal (user/group) receiving the permissions |
-Path |
string |
Target object in distinguishedName format (e.g. an OU) |
-TemplateIDs |
int[] |
One or more template IDs to apply |
-TemplatePath |
string |
Path to a JSON file or a directory of JSON files |
-ShowTemplates |
switch |
List all loaded templates |
-IncludeDetails |
switch |
Show rule details and source file per template |
-LogChanges |
switch |
Enable change logging (requires -LogPath) |
-LogPath |
string |
Path to the log file |
Note: If
-TemplatePathis omitted, the script auto-loads from atemplates\subdirectory next to the script.
# Overview (ID, description, source file)
.\Invoke-ADDelegationTemplate.ps1 -ShowTemplates -TemplatePath .\templates
# Detailed view (includes rules & AppliesTo info)
.\Invoke-ADDelegationTemplate.ps1 -ShowTemplates -IncludeDetails -TemplatePath .\templates# Single template
.\Invoke-ADDelegationTemplate.ps1 `
-Identity "Helpdesk-Team" `
-Path "OU=UsersBerlin,DC=contoso,DC=local" `
-TemplateIDs 102 `
-TemplatePath .\templates
# Multiple templates at once
.\Invoke-ADDelegationTemplate.ps1 `
-Identity "Helpdesk-Team" `
-Path "OU=UsersBerlin,DC=contoso,DC=local" `
-TemplateIDs 101,102,103 `
-TemplatePath .\templates.\Invoke-ADDelegationTemplate.ps1 `
-Identity "Helpdesk-Team" `
-Path "OU=UsersBerlin,DC=contoso,DC=local" `
-TemplateIDs 102 `
-TemplatePath .\templates `
-LogChanges `
-LogPath "$env:USERPROFILE\DelegationLog.log"Logged changes can be reviewed and reverted at any time:
# Show all logged changes
Show-ADDelegationTemplateChanges -LogFilePath "$env:USERPROFILE\DelegationLog.log"
# Show with formatted output
Show-ADDelegationTemplateChanges -LogFilePath "$env:USERPROFILE\DelegationLog.log" -FormatOutput
# Revert all logged changes
Show-ADDelegationTemplateChanges -LogFilePath "$env:USERPROFILE\DelegationLog.log" | `
Revert-ADDelegationTemplate
# Revert only a specific template
Show-ADDelegationTemplateChanges -LogFilePath "$env:USERPROFILE\DelegationLog.log" | `
Where-Object { $_.TemplateID -eq "102" } | `
Revert-ADDelegationTemplateTemplates are shipped as JSON files in the templates\ folder:
| File | Category | Examples |
|---|---|---|
100-user.json |
User objects | Reset password, edit properties, manage accounts |
200-group.json |
Group objects | Manage membership, create/delete groups |
300-computer.json |
Computer objects | Join domain, reset password |
400-organizationalUnit.json |
Organizational Units | Create, rename, manage OUs |
500-inetOrgPerson.json |
inetOrgPerson | LDAP / schema-based environments |
600-groupPolicy.json |
Group Policy | Link/unlink GPOs, read RSoP |
700-wmiFilters.json |
WMI Filters | Create, delete, assign WMI filters |
Use
-ShowTemplates -IncludeDetailsto see the exact template IDs and rules in each file.
The Berlin helpdesk team needs to reset user passwords in a specific OU:
.\Invoke-ADDelegationTemplate.ps1 `
-Identity "Contoso\Helpdesk-Berlin" `
-Path "OU=UsersBerlin,DC=contoso,DC=local" `
-TemplateIDs 102 `
-TemplatePath .\templatesGrant a team full user management rights and log every change:
.\Invoke-ADDelegationTemplate.ps1 `
-Identity "UserAdmins" `
-Path "OU=Users,OU=Corp,DC=contoso,DC=local" `
-TemplateIDs 101,102,103 `
-TemplatePath .\templates `
-LogChanges `
-LogPath "$env:USERPROFILE\DelegationLog.log"Allow a group to link/unlink GPOs on an OU:
.\Invoke-ADDelegationTemplate.ps1 `
-Identity "GPO-Managers" `
-Path "OU=Sites,DC=contoso,DC=local" `
-TemplateIDs 601 `
-TemplatePath .\templatesEach JSON file contains an array of templates:
[
{
"ID": "101",
"Description": "User: read & write all properties",
"AppliesToClasses": "domainDNS,organizationalUnit,container",
"ObjectTypes": "SCOPE,user",
"Template": [
{ "ObjectType": "user", "Property": "@", "Right": "ReadProperty|WriteProperty" },
{ "ObjectType": "user", "Property": "Reset Password", "Right": "ExtendedRight" }
]
}
]| Key | Type | Description |
|---|---|---|
ID |
string |
Unique template identifier |
Description |
string |
Human-readable description |
AppliesToClasses |
string |
Comma-separated AD object classes this template targets |
ObjectTypes |
string |
Comma-separated AD object classes this template applies permissions to |
Template |
array |
Array of permission rules |
Template[].ObjectType |
string |
AD object class (e.g. user, group, computer, SCOPE) |
Template[].Property |
string |
Property or extended right name (@ = all properties) |
Template[].Right |
string |
Full ActiveDirectoryRights enum name(s) |
- Files are loaded alphabetically.
- Duplicate IDs across files: last-writer-wins (the later file overrides).
- Invalid templates are skipped with a warning β remaining templates still load.
Before (v1.2): Templates used abbreviations like RP, WP, CC, CONTROLRIGHT.
Now (v1.3-dev): Templates must use the full System.DirectoryServices.ActiveDirectoryRights enum names.
| Old abbreviation | New full name |
|---|---|
RP |
ReadProperty |
WP |
WriteProperty |
CC |
CreateChild |
DC |
DeleteChild |
SD |
Self |
WD |
WriteDacl |
CONTROLRIGHT |
ExtendedRight |
GA |
GenericAll |
GR |
GenericRead |
GW |
GenericWrite |
GE |
GenericExecute |
LC |
ListChildren |
Multiple rights per rule are supported β separate with | or ,:
{ "ObjectType": "user", "Property": "@", "Right": "ReadProperty|WriteProperty" }Validation is case-insensitive. Invalid
Rightvalues produce a clear warning listing all allowed enum names.
| Problem | Solution |
|---|---|
| Template is skipped | Check the warning message β it tells you whether Right, ObjectType, or Property is invalid |
| JSON parse error | Validate syntax: Get-Content .\templates\100-user.json -Raw | ConvertFrom-Json |
| "No template with ID X found" | Run -ShowTemplates to verify the ID exists and is loaded |
| "Template path not found" | Verify -TemplatePath points to an existing file or directory |
| Old abbreviations rejected | Replace abbreviations with full enum names (see migration table above) |
| Script | Purpose |
|---|---|
Revert-ADDelegationTemplate.ps1 |
Revert previously applied permissions using a log file |
Show-ADDelegationTemplateChanges.ps1 |
Display logged permission changes (formatted or raw) |
tools\ConvertFrom-DelegwizToTemplate.ps1 |
Convert legacy delegwiz.ini files to JSON templates |
tools\ConvertFrom-ObjectAclToTemplate.ps1 |
Reverse-engineer: generate a template from existing AD permissions |
tools\Test-DelegationTemplate.ps1 |
Validate a JSON template against the AD schema |
Suggestions, bug reports, and contributions are welcome!
Please open an issue or submit a pull request with a clear explanation.
Template source @Microsoft: Appendix O: Active Directory Delegation Wizard File