|
1 | 1 | --- |
2 | 2 | title: Creating an AD FS farm without Domain Administrator privileges |
3 | 3 | description: Using the Install-AdfsFarm cmdlet and script to create an AD FS farm using delegated admin credentials |
4 | | -ms.date: 02/13/2024 |
| 4 | +ms.date: 07/09/2026 |
5 | 5 | ms.topic: how-to |
6 | 6 |
|
7 | 7 | --- |
@@ -175,6 +175,55 @@ if ($pscmdlet.ShouldProcess("$ou", "Creating DKM container and assigning access" |
175 | 175 | New-ADObject -Name $ouName -Type Container -Path $ouPath |
176 | 176 | } |
177 | 177 |
|
| 178 | +####################################### |
| 179 | +## Harden DKM container: disable inheritance, purge |
| 180 | +## Authenticated Users and Pre-Windows 2000 Compatible Access. |
| 181 | +## This prevents broad principals from reading thumbnailPhoto |
| 182 | +## (where the DKM key material is stored on child Contact objects). |
| 183 | +####################################### |
| 184 | +if ($pscmdlet.ShouldProcess("$ou", "Disabling inheritance and purging Authenticated Users / Pre-Windows 2000")) |
| 185 | +{ |
| 186 | + $acl = get-acl -Path $ou |
| 187 | +
|
| 188 | + # Block inheritance and discard all inherited ACEs. |
| 189 | + $acl.SetAccessRuleProtection($true, $false) |
| 190 | +
|
| 191 | + # Purge Authenticated Users |
| 192 | + $authenticatedUsers = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::AuthenticatedUserSid, $null) |
| 193 | + $acl.PurgeAccessRules($authenticatedUsers) |
| 194 | +
|
| 195 | + # Purge Pre-Windows 2000 Compatible Access |
| 196 | + $preWin2k = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::BuiltinPreWindows2000CompatibleAccessSid, $null) |
| 197 | + $acl.PurgeAccessRules($preWin2k) |
| 198 | +
|
| 199 | + set-acl -Path $ou -AclObject $acl |
| 200 | +} |
| 201 | +
|
| 202 | +####################################### |
| 203 | +## Grant Domain Admins, Enterprise Admins, and SYSTEM full control. |
| 204 | +## These are the approved principals for the DKM container. |
| 205 | +####################################### |
| 206 | +if ($pscmdlet.ShouldProcess("$ou", "Granting DA, EA, and SYSTEM GenericAll")) |
| 207 | +{ |
| 208 | + $acl = get-acl -Path $ou |
| 209 | + [System.DirectoryServices.ActiveDirectorySecurityInheritance]$adSecInEnum = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::All |
| 210 | +
|
| 211 | + # Domain Admins |
| 212 | + $domainSid = (Get-ADDomain).DomainSID |
| 213 | + $domainAdminsSid = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::AccountDomainAdminsSid, $domainSid) |
| 214 | + $acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $domainAdminsSid,"GenericAll","Allow",$adSecInEnum)) |
| 215 | +
|
| 216 | + # Enterprise Admins (forest root domain) |
| 217 | + $rootDomainSid = (Get-ADForest).RootDomain | Get-ADDomain | Select-Object -ExpandProperty DomainSID |
| 218 | + $enterpriseAdminsSid = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::AccountEnterpriseAdminsSid, $rootDomainSid) |
| 219 | + $acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $enterpriseAdminsSid,"GenericAll","Allow",$adSecInEnum)) |
| 220 | +
|
| 221 | + # SYSTEM |
| 222 | + $systemSid = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::LocalSystemSid, $null) |
| 223 | + $acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $systemSid,"GenericAll","Allow",$adSecInEnum)) |
| 224 | +
|
| 225 | + set-acl -Path $ou -AclObject $acl |
| 226 | +} |
178 | 227 |
|
179 | 228 | ####################################### |
180 | 229 | ## Grant the following permission to the service account |
@@ -274,5 +323,4 @@ if ($pscmdlet.ShouldProcess("$strSID", "Granting GenericRead, CreateChild, Write |
274 | 323 | } |
275 | 324 |
|
276 | 325 | pop-location |
277 | | -
|
278 | 326 | ``` |
0 commit comments