Domain Join Cleanup Script

๐Ÿ”’ Secure Bits ๐Ÿ’ก
๐—๐—ผ๐—ถ๐—ป๐—ถ๐—ป๐—ด ๐—ฑ๐—ฒ๐˜ƒ๐—ถ๐—ฐ๐—ฒ๐˜€ ๐˜๐—ผ ๐˜†๐—ผ๐˜‚๐—ฟ ๐—”๐—— ๐—ฑ๐—ผ๐—บ๐—ฎ๐—ถ๐—ป? ๐—ง๐—ต๐—ฒ๐—ฟ๐—ฒโ€™๐˜€ ๐—บ๐—ผ๐—ฟ๐—ฒ ๐˜๐—ผ ๐—ถ๐˜.
(Updated version โ€” thanks to the great feedback from Adonis Moreira & Andreas Vikerup ๐Ÿ‘)

A few weeks ago I posted a Secure Bits on creating a ๐—ต๐—ฎ๐—ฟ๐—ฑ๐—ฒ๐—ป๐—ฒ๐—ฑ ๐˜€๐—ฒ๐—ฟ๐˜ƒ๐—ถ๐—ฐ๐—ฒ ๐—ฎ๐—ฐ๐—ฐ๐—ผ๐˜‚๐—ป๐˜ for domain joins. Since then, Iโ€™ve ๐˜‚๐—ฝ๐—ฑ๐—ฎ๐˜๐—ฒ๐—ฑ ๐—ฏ๐—ผ๐˜๐—ต my guide and tools โ€” and made a short video walkthrough. Hereโ€™s whatโ€™s new and what to watch out for:

๐—›๐—ฎ๐—ฟ๐—ฑ๐—ฒ๐—ป๐—ถ๐—ป๐—ด ๐—ผ๐—ณ ๐˜†๐—ผ๐˜‚๐—ฟ ๐—ฑ๐—ผ๐—บ๐—ฎ๐—ถ๐—ป ๐—ท๐—ผ๐—ถ๐—ป ๐—ฝ๐—ฟ๐—ผ๐—ฐ๐—ฒ๐˜€๐˜€:
โœ… Create a dedicated service account (complex password, no extra rights).
โœ… Delegate the required permissions on the Computers OU.
โœ… Set โ€œAdd workstations to domainโ€ GPO privilege โ†’ your service account + Domain Admins.
โœ… Set ms-DS-MachineAccountQuota to 0 โ†’ block default behavior allowing any authenticated user to join 10 devices.

Devices can be joined either via the โ€œAdd workstations to domainโ€ user right (limited by ms-DS-MachineAccountQuota โ€” default 10 per Authenticated User) or via delegated Create Computer Objects on the target OU (no quota/user-right needed). Set the attribute to 0 to block the default Authenticated Users path, and keep the GPO scoped only to your joiners/DA group so intent stays explicit.

๐Ÿ“Œ ๐——๐—ผ๐—ปโ€™๐˜ ๐—ณ๐—ผ๐—ฟ๐—ด๐—ฒ๐˜:ย after joining, always move devices out of the default Computers container to avoid inherited permissions (you also want to apply some GPOs, right?)

๐Ÿ’ฅ ๐—•๐˜‚๐˜ ๐—ต๐—ฒ๐—ฟ๐—ฒโ€™๐˜€ ๐˜„๐—ต๐—ฎ๐˜ ๐—œ ๐—บ๐—ถ๐˜€๐˜€๐—ฒ๐—ฑ ๐—น๐—ฎ๐˜€๐˜ ๐˜๐—ถ๐—บ๐—ฒย โ€”
When you join a device using a service account, that account becomes ๐—ผ๐˜„๐—ป๐—ฒ๐—ฟ of the new computer object and may have dangerous Access Control Entries (๐—”๐—–๐—˜๐˜€).

๐—ง๐—ต๐—ถ๐˜€ ๐—ฐ๐—ฟ๐—ฒ๐—ฎ๐˜๐—ฒ๐˜€ ๐—ฎ ๐—ต๐—ถ๐—ฑ๐—ฑ๐—ฒ๐—ป ๐—ฟ๐—ถ๐˜€๐—ธ:
๐Ÿ”“ If the join account is compromised, it can abuse permissions on existing joined computers.

๐—ก๐—ฒ๐˜„ ๐—ฅ๐—ฒ๐˜€๐—ผ๐˜‚๐—ฟ๐—ฐ๐—ฒ๐˜€ ๐˜๐—ผ ๐—™๐—ถ๐˜… ๐—ง๐—ต๐—ถ๐˜€:
๐Ÿ”น ๐—”๐——๐—ฃ๐—ฟ๐—ผ๐—ฏ๐—ฒ ๐˜‚๐—ฝ๐—ฑ๐—ฎ๐˜๐—ฒ:
โ†’ Now detects foreign object ownership after domain join.

๐Ÿ”นย ๐——๐—ผ๐—บ๐—ฎ๐—ถ๐—ป ๐—๐—ผ๐—ถ๐—ป ๐—š๐˜‚๐—ถ๐—ฑ๐—ฒ ๐˜‚๐—ฝ๐—ฑ๐—ฎ๐˜๐—ฒ:
โ†’ Now includes a PowerShell cleanup script to:
โ€ข Change object ownership to Domain Admins
โ€ข Remove join account ACEs from computer objects

๐Ÿ“น Links for products and write-up from Andreas are in comments.

โธป

๐Ÿ’ฌ How do you manage secure domain joins?
Do you clean up ACEs and ownership after provisioning?