Last active
October 21, 2025 19:02
-
-
Save zjorz/d3221678d2fa4f4579f4c35eefd39333 to your computer and use it in GitHub Desktop.
Code to create a DSRM Placeholder Account in AD for RODCs as described in the blog post https://jorgequestforknowledge.wordpress.com/2010/06/15/managing-the-dsrm-administrator-account/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # SOURCE: https://gist.github.com/zjorz/d3221678d2fa4f4579f4c35eefd39333/ | |
| Invoke-Command -ScriptBlock { | |
| Clear-Host | |
| $scriptMode = "ADSIorSDSP" # "ADSIorSDSP" Or "ADPoSH" | |
| Write-Host "" | |
| Write-Host "###############################################################################" -Foregroundcolor Yellow | |
| Write-Host "### CREATING THE DSRM PLACEHOLDER ACCOUNT FOR RODCs ###" -Foregroundcolor Yellow | |
| Write-Host "###############################################################################" -Foregroundcolor Yellow | |
| # Some Basics | |
| $systemSecurityPrincipalStringSID = "S-1-5-18" # 'NT AUTHORITY\SYSTEM' Well-Known Security Principal | |
| $systemSecurityPrincipal = $(New-Object System.Security.Principal.SecurityIdentifier($systemSecurityPrincipalStringSID)).Translate([System.Security.Principal.NTAccount]) | |
| $rightsCollection = [System.DirectoryServices.ActiveDirectoryRights]::"GenericAll" # Full Control | |
| $aclTypeAllow = [System.Security.AccessControl.AccessControlType]::"Allow" # Allow ACE | |
| $aclTypeDeny = [System.Security.AccessControl.AccessControlType]::"Deny" # Deny ACE | |
| $accessInheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::"None" # This Object Only | |
| $scopedObjectSchemaIDGuid = "00000000-0000-0000-0000-000000000000" # All | |
| $scopedAttributeSchemaIDGuid = "00000000-0000-0000-0000-000000000000" # All | |
| $aceDefinitionDeny = $systemSecurityPrincipal,$rightsCollection,$aclTypeDeny,$scopedAttributeSchemaIDGuid,$accessInheritanceType,$scopedObjectSchemaIDGuid | |
| If ($scriptMode -eq "ADSIorSDSP") { | |
| $adDomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain() | |
| $adDomainFQDN = $adDomain.Name | |
| $adDomainDN = $adDomain.GetDirectoryEntry().Properties["DistinguishedName"].Value | |
| $adDomainSIDBytes = $adDomain.GetDirectoryEntry().Properties["ObjectSid"].Value | |
| $adDomainSID = (New-Object System.Security.Principal.SecurityIdentifier($adDomainSIDBytes, 0)).Value | |
| $adDomainNetBIOSName = $adDomain.GetDirectoryEntry().Properties["Name"].Value | |
| $rwdcPDCFSMOFQDN = $adDomain.PdcRoleOwner.Name | |
| $OU = "CN=Users,$adDomainDN" # As The Account Created Below Should Be Considered A Tier 0 Resource, Preferably Use An OU That Is Part Of Tier 0 Protecting And Hiding Tier 0 Resources)" # As The Account Created Below Should Be Considered A Tier 0 Resource, Preferably Use An OU That Is Part Of Tier 0 Protecting And Hiding Tier 0 Resources | |
| } | |
| If ($scriptMode -eq "ADPoSH") { | |
| Import-Module ActiveDirectory | |
| $adDomain = Get-ADdomain -Current LocalComputer | |
| $adDomainFQDN = $adDomain.DnsRoot | |
| $adDomainDN = $adDomain.DistinguishedName | |
| $adDomainSID = $adDomain.DomainSID.value | |
| $adDomainNetBIOSName = $adDomain.NetBIOSName | |
| $rwdcPDCFSMOFQDN = $adDomain.PDCEmulator | |
| $OU = "CN=Users,$adDomainDN" # As The Account Created Below Should Be Considered A Tier 0 Resource, Preferably Use An OU That Is Part Of Tier 0 Protecting And Hiding Tier 0 Resources)" # As The Account Created Below Should Be Considered A Tier 0 Resource, Preferably Use An OU That Is Part Of Tier 0 Protecting And Hiding Tier 0 Resources | |
| } | |
| # Define The Random Password 2x 32 Characters In Total For The Placeholder DSRM Account For RODCs | |
| $pwdPart1DSRMRODCs = $(-join (33..126 | ForEach-Object {[char]$_} | Get-Random -Count 32)) | |
| $pwdPart2DSRMRODCs = $(-join (33..126 | ForEach-Object {[char]$_} | Get-Random -Count 32)) | |
| $pwdDSRMRODCs = $pwdPart1DSRMRODCs + $pwdPart2DSRMRODCs | |
| # Create The DSRM Placeholder AD User Account For RODCs | |
| $dsrmRODCsSamAccountName = "dsrm.RODCs" | |
| $dsrmRODCsAccountName = "DSRM Placeholder Account For RODCs" | |
| Write-Host "" | |
| Write-Host "Creating DSRM Placeholder AD User Account For RODCs ('$dsrmRODCsSamAccountName')" -Foregroundcolor Yellow | |
| Write-Host "" | |
| If ($scriptMode -eq "ADSIorSDSP") { | |
| $ouObject = [ADSI]"LDAP://$rwdcPDCFSMOFQDN/$OU" | |
| $dsrmAccountObject = $ouObject.Create("user", "CN=$dsrmRODCsAccountName") | |
| $userAccountControl = 512 # NORMAL_ACCOUNT | |
| $userAccountControl = $userAccountControl -bor 2 # ACCOUNTDISABLE | |
| $userAccountControl = $userAccountControl -bor 65536 # DONT_EXPIRE_PASSWORD | |
| $userAccountControl = $userAccountControl -bor 1048576 # NOT_DELEGATED | |
| $dsrmAccountObject.Put("userAccountControl", $userAccountControl) | |
| $dsrmAccountObject.Put("givenName", "DSRM") | |
| $dsrmAccountObject.Put("sn", "Placeholder Account For RODCs") | |
| $dsrmAccountObject.Put("displayName", $dsrmRODCsAccountName) | |
| $dsrmAccountObject.Put("description", "$dsrmRODCsAccountName To Sync The Password From - !!! DO NOT ENABLE !!!") | |
| $dsrmAccountObject.Put("sAMAccountName", $dsrmRODCsSamAccountName) | |
| $dsrmAccountObject.Put("userPrincipalName", "$dsrmRODCsSamAccountName@$adDomainFQDN") | |
| $dsrmAccountObject.SetInfo() | |
| $dsrmAccountObject.RefreshCache() | |
| $dsrmAccountObject.SetPassword($pwdDSRMRODCs) | |
| $dsrmAccountObject = [ADSI]"LDAP://$rwdcPDCFSMOFQDN/CN=$dsrmRODCsAccountName,$OU" | |
| $selfSecurityPrincipalStringSID = "S-1-5-10" # SELF | |
| $selfSecurityPrincipal = $(New-Object System.Security.Principal.SecurityIdentifier($selfSecurityPrincipalStringSID)).Translate([System.Security.Principal.NTAccount]) | |
| $rightsCollection = [System.DirectoryServices.ActiveDirectoryRights]::"ExtendedRight" # Extended Right | |
| $aclType = [System.Security.AccessControl.AccessControlType]::"Deny" # Deny ACE | |
| $carChangePassword = "ab721a53-1e2f-11d0-9819-00aa0040529b" # Control Access Right "Change Password" | |
| $inheritanceScope = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::"None" # This Object Only | |
| $schemaIDguidUSER = "bf967aba-0de6-11d0-a285-00aa003049e2" # Schema ID Guid For "USER" | |
| $aceDefinition = $selfSecurityPrincipal,$rightsCollection,$aclType,$carChangePassword,$inheritanceScope,$schemaIDguidUSER | |
| $accessRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($aceDefinition) | |
| $dsrmAccountObject.PSBase.ObjectSecurity.AddAccessRule($accessRule) | |
| $dsrmAccountObject.PSBase.CommitChanges() | |
| $dsrmAccountObject.RefreshCache() | |
| } | |
| If ($scriptMode -eq "ADPoSH") { | |
| $dsrmParametersHT = @{ | |
| Path = $OU | |
| Enabled = $false | |
| Name = $dsrmRODCsAccountName | |
| GivenName = "DSRM" | |
| Surname = "Placeholder Account For RODCs" | |
| DisplayName = $dsrmRODCsAccountName | |
| Description = "$dsrmRODCsAccountName To Sync The Password From - !!! DO NOT ENABLE !!!" | |
| SamAccountName = $dsrmRODCsSamAccountName | |
| UserPrincipalName = "$dsrmRODCsSamAccountName@$adDomainFQDN" | |
| AccountPassword = $(ConvertTo-SecureString $pwdDSRMRODCs -AsPlainText -Force) | |
| CannotChangePassword = $true | |
| AccountNotDelegated = $true | |
| PasswordNeverExpires = $true | |
| SmartcardLogonRequired = $false | |
| Server = $rwdcPDCFSMOFQDN | |
| } | |
| New-ADUser @dsrmParametersHT | |
| Start-Sleep -s 1 | |
| $dsrmAdmAccount = Get-ADUser -Identity $dsrmRODCsSamAccountName -Server $rwdcPDCFSMOFQDN | |
| $dsrmAdmAccountDN = $dsrmAdmAccount.DistinguishedName | |
| } | |
| Write-Host " > Script Mode...........: $scriptMode" -Foregroundcolor Yellow | |
| Write-Host " > Container/OU..........: $OU" -Foregroundcolor Yellow | |
| Write-Host " > Name/DisplayName......: $dsrmRODCsAccountName" -Foregroundcolor Yellow | |
| Write-Host " > sAMAccountName........: $dsrmRODCsSamAccountName" -Foregroundcolor Yellow | |
| Write-Host " > msDS-PrincipalName....: $adDomainNetBIOSName\$dsrmRODCsSamAccountName" -Foregroundcolor Yellow | |
| Write-Host " > Password..............: ...RANDOM AND UNKNOWN..." -Foregroundcolor Cyan | |
| Write-Host "" | |
| # Add The DSRM Placeholder AD User Account For RODCs To The Domain Guests Group And Reconfiguring Primary Group ID | |
| Write-Host "" | |
| Write-Host "Adding DSRM Placeholder AD User Account For RODCs ('$dsrmRODCsSamAccountName') To Domain Guests Group And Reconfiguring Primary Group ID" -Foregroundcolor Yellow | |
| Write-Host "" | |
| If ($scriptMode -eq "ADSIorSDSP") { | |
| $domainGuestsGroupSID = "$adDomainSID-514" | |
| $domainGuestsGroupPrincipalName = $(New-Object System.Security.Principal.SecurityIdentifier($domainGuestsGroupSID)).Translate([System.Security.Principal.NTAccount]).Value | |
| $domainGuestsGroupSamAccountName = $domainGuestsGroupPrincipalName.Split("\")[1] | |
| $adsiSearcher = New-Object DirectoryServices.DirectorySearcher | |
| $adsiSearcher.SearchRoot = [ADSI]"LDAP://$rwdcPDCFSMOFQDN/$adDomainDN" | |
| $adsiSearcher.Filter = "(sAMAccountName=$domainGuestsGroupSamAccountName)" | |
| $domainGuestsGroupObject = $adsiSearcher.FindOne() | |
| ([ADSI]"LDAP://$rwdcPDCFSMOFQDN/$($domainGuestsGroupObject.Properties.distinguishedname[0])").Add($dsrmAccountObject.ADSPath) | |
| $dsrmAccountObject.Put("primaryGroupId", 514) | |
| $dsrmAccountObject.SetInfo() | |
| $dsrmAccountObject.RefreshCache() | |
| } | |
| If ($scriptMode -eq "ADPoSH") { | |
| Add-ADGroupMember -Identity "$adDomainSID-514" -Members $dsrmRODCsSamAccountName -Server $rwdcPDCFSMOFQDN | |
| Set-ADUser -Identity $dsrmRODCsSamAccountName -Replace @{"primaryGroupID" = "514"} -Server $rwdcPDCFSMOFQDN | |
| } | |
| # Remove The DSRM Placeholder AD User Account For RODCs From The Domain Users Group | |
| Write-Host "" | |
| Write-Host "Removing DSRM Placeholder AD User Account For RODCs ('$dsrmRODCsSamAccountName') From Domain Users Group" -Foregroundcolor Yellow | |
| Write-Host "" | |
| If ($scriptMode -eq "ADSIorSDSP") { | |
| $domainUsersGroupSID = "$adDomainSID-513" | |
| $domainUsersGroupPrincipalName = $(New-Object System.Security.Principal.SecurityIdentifier($domainUsersGroupSID)).Translate([System.Security.Principal.NTAccount]).Value | |
| $domainUsersGroupSamAccountName = $domainUsersGroupPrincipalName.Split("\")[1] | |
| $adsiSearcher = New-Object DirectoryServices.DirectorySearcher | |
| $adsiSearcher.SearchRoot = [ADSI]"LDAP://$rwdcPDCFSMOFQDN/$adDomainDN" | |
| $adsiSearcher.Filter = "(sAMAccountName=$domainUsersGroupSamAccountName)" | |
| $domainUsersGroupObject = $adsiSearcher.FindOne() | |
| ([ADSI]"LDAP://$rwdcPDCFSMOFQDN/$($domainUsersGroupObject.Properties.distinguishedname[0])").Remove($dsrmAccountObject.ADSPath) | |
| } | |
| If ($scriptMode -eq "ADPoSH") { | |
| Remove-ADGroupMember -Identity "$adDomainSID-513" -Members $dsrmRODCsSamAccountName -Confirm:$false -Server $rwdcPDCFSMOFQDN | |
| } | |
| # Add The DSRM Placeholder AD User Account For RODCs To The ALLOWED RODC Password Replication Group | |
| Write-Host "" | |
| Write-Host "Adding DSRM Placeholder AD User Account For RODCs ('$dsrmRODCsSamAccountName') To ALLOWED RODC Password Replication Group" -Foregroundcolor Yellow | |
| Write-Host "" | |
| If ($scriptMode -eq "ADSIorSDSP") { | |
| $domainRODCsPRPAllowGroupSID = "$adDomainSID-571" | |
| $domainRODCsPRPAllowGroupPrincipalName = $(New-Object System.Security.Principal.SecurityIdentifier($domainRODCsPRPAllowGroupSID)).Translate([System.Security.Principal.NTAccount]).Value | |
| $domainRODCsPRPAllowGroupSamAccountName = $domainRODCsPRPAllowGroupPrincipalName.Split("\")[1] | |
| $adsiSearcher = New-Object DirectoryServices.DirectorySearcher | |
| $adsiSearcher.SearchRoot = [ADSI]"LDAP://$rwdcPDCFSMOFQDN/$adDomainDN" | |
| $adsiSearcher.Filter = "(sAMAccountName=$domainRODCsPRPAllowGroupSamAccountName)" | |
| $domainRODCsPRPAllowGroupObject = $adsiSearcher.FindOne() | |
| ([ADSI]"LDAP://$rwdcPDCFSMOFQDN/$($domainRODCsPRPAllowGroupObject.Properties.distinguishedname[0])").Add($dsrmAccountObject.ADSPath) | |
| } | |
| If ($scriptMode -eq "ADPoSH") { | |
| Add-ADGroupMember -Identity "$adDomainSID-571" -Members $dsrmRODCsSamAccountName -Server $rwdcPDCFSMOFQDN | |
| } | |
| # Adding Restrictions To NOT Allow The Synchronization Of The Password From The DSRM Placeholder AD User Account For RODCs | |
| Write-Host "" | |
| Write-Host "Adding Restrictions To NOT Allow Synchronization Of Password From DSRM Placeholder AD User Account For RODCs ('$dsrmRODCsSamAccountName')" -Foregroundcolor Yellow | |
| Write-Host "" | |
| If ($scriptMode -eq "ADSIorSDSP") { | |
| $accessRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($aceDefinitionDeny) | |
| $dsrmAccountObject.PSBase.ObjectSecurity.RemoveAccess($systemSecurityPrincipal, $aclTypeAllow) | |
| $dsrmAccountObject.PSBase.ObjectSecurity.AddAccessRule($accessRule) | |
| $dsrmAccountObject.PSBase.CommitChanges() | |
| } | |
| If ($scriptMode -eq "ADPoSH") { | |
| $accessRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($aceDefinitionDeny) | |
| $adDrive = New-PSDrive -Name "CustomADDrive" -Root "" -PSProvider ActiveDirectory -Server $rwdcPDCFSMOFQDN | |
| $dsrmAdmAccountRODCsACL = Get-Acl "$($adDrive.Name):\$dsrmAdmAccountDN" | |
| $dsrmAdmAccountRODCsACL.RemoveAccess($systemSecurityPrincipal, $aclTypeAllow) | |
| $dsrmAdmAccountRODCsACL.AddAccessRule($accessRule) | |
| $dsrmAdmAccountRODCsACL | Set-Acl "$($adDrive.Name):\$dsrmAdmAccountDN" | |
| Remove-PSDrive $adDrive | |
| } | |
| Write-Host "" | |
| Write-Host "Secure This Account ('$adDomainFQDN\$dsrmRODCsSamAccountName') As Best As Possible As It Should Be Considered A High-Privileged Account!" -Foregroundcolor Magenta | |
| Write-Host "" | |
| Write-Host "" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment