When reading the "Delegate not working" thread on the MS Technet (http://social.technet.microsoft.com/Forums/windowsserver/en-US/2b8b6afb-a712-4b4f-9613-bf8ff9330127/delegate-control-not-working?forum=winserverDS) I remembered companies I worked for in the past usually create new computer objects for the computers they bought. Computers are then installed and delivered to the user by onsite support teams that work as a local Administrator but have limited access to the Active Directory.
Even though they need to join a newly installed computer to your Directory.
The process is as followed
1. In a first step your onsite services provides a consolidated list of computer names and Ous to store the computers.
2. Now you go and create all the computer objects and you set up the permission to join a computer to the domain by the onsite teams.
In my case we created a group called "ComputerJoinAdmins". All onsite team admin accounts are member of that group.
3. In the final step the onsite team can install the computer and join it to your domain.
You can set up the permission to join a computer to a domain via GUI when you create the computer object. When you can see the "New Computer" dialog you are able to also set a group name or user name who is allowed to join that computer to your domain. In the screenshot below you can see that a group named "ComputerJoinAdmins", including the onsite support group of our test lab, ill be allowed to join that computer to the domain.
Unfortunately that procedure is not very useful for your production environment where you may have hundreds of computers that are changed (replaced, re-installed, …) over the day. In that case I am asked frequently for a procedure to set up a computer object from a script, using powershell.
You may have already noticed , when using the ActiveDirectory module with Windows Server 2008 or 2012, in Powershell there is a cmdlet called "new-adcomputer" , (see also http://technet.microsoft.com/en-us/library/ee617245.aspx). While the cmdlet is able to create your computer object you cannot directly set up the "that users can join that computer to the domain" setting. So you still need to setup the permission to allow a user or group to join a computer to your domain, even if you already created /pre-populated the object.
The difference between a computer set up with "default" permissions, so it will only inherit permissions from your OrganizationalUnit and a computer object with the join permissions is seven ACL entries.
ActiveDirectoryRights | ObjectType | ObjectFlags | AccessControlType | IdentityReference |
DeleteTree, ExtendedRight, Delete, GenericRead | 00000000-0000-0000-0000-000000000000 | None | Allow | mydomain\ComputerJoinAdmins |
WriteProperty | 4c164200-20c0-11d0-a768-00aa006e0529 | ObjectAceTypePresent | Allow | mydomain\ComputerJoinAdmins |
Self | f3a64788-5306-11d1-a9c5-0000f80367c1 | ObjectAceTypePresent | Allow | mydomain\ComputerJoinAdmins |
Self | 72e39547-7b18-11d1-adef-00c04fd8d5cd | ObjectAceTypePresent | Allow | mydomain\ComputerJoinAdmins |
WriteProperty | 3e0abfd0-126a-11d0-a060-00aa006c33ed | ObjectAceTypePresent | Allow | mydomain\ComputerJoinAdmins |
WriteProperty | bf967953-0de6-11d0-a285-00aa003049e2 | ObjectAceTypePresent | Allow | mydomain\ComputerJoinAdmins |
WriteProperty | bf967950-0de6-11d0-a285-00aa003049e2 | ObjectAceTypePresent | Allow | mydomain\ComputerJoinAdmins |
WriteProperty | 5f202010-79a5-11d0-9020-00c04fc2d4cf | ObjectAceTypePresent | Allow | mydomain\ComputerJoinAdmins |
As we said before, that permissions are not inherited, so I removed the "InheritedObjectType", "InheritanceType", "InheritanceFlags" and "IsInherited" property from that table. As a computer workstation is not a container object, I also removed the PropagationFlags property.
Now we can do the required tasks
1. Create the computer object to have an object you can grant permissions for your ComputerJoinAdmins.
2. Add access rule entries (ACEs) to your object for the group ComputerJoinAdmins.
And here we go for a single computer called mobile 1000 in an example OU called "OU=JP,OU=Sites,DC=mgtest1,DC=com".
# Initially we set up the names for our Onsite team group
$mycomputeradmins = "ComputerJoinAdmins"
# and our computer name
$computername = "mobile1000"
# as we need the SID for the Onsite team group instead of the name we get that on run-time from AD
# my case that is finally transferred to a variable called UserSID
$mycomputeradminssid = (Get-ADGroup $mycomputeradmins ).sid
$usersid = $mycomputeradminssid
# now we create the new AD computer object and receive the object in a variable called $mycomputer
new-adcomputer -path "OU=JP,OU=Sites,DC=mgtest1,DC=com" $computername
$mycomputer = get-adcomputer $computername
# from the distinguishedname we can get the ACL of the computer object.
# (in Powershell you have the syntax AD:distinguishedname to get the AD object object with get-acl)
# in the result you have a copy of the current ACL stored in $mycomputeracl
$mycomputerdn = $mycomputer.distinguishedname
$mycomputeracl = get-acl "AD:$mycomputerdn"
# now we can create a new ruleset for the AD access rules (one rule set is one permission entry in the objects ACL you can see with the GUI) …
$rule1 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($usersid,'DeleteTree, ExtendedRight, Delete, GenericRead', 'Allow', [GUID]'00000000-0000-0000-0000-000000000000')
$rule2 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($usersid,'WriteProperty', 'Allow', [GUID]'4c164200-20c0-11d0-a768-00aa006e0529')
$rule3 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($usersid,'Self', 'Allow', [GUID]'f3a64788-5306-11d1-a9c5-0000f80367c1')
$rule4 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($usersid,'Self', 'Allow', [GUID]'72e39547-7b18-11d1-adef-00c04fd8d5cd')
$rule5 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($usersid,'WriteProperty', 'Allow', [GUID]'3e0abfd0-126a-11d0-a060-00aa006c33ed')
$rule6 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($usersid,'WriteProperty', 'Allow', [GUID]'bf967953-0de6-11d0-a285-00aa003049e2')
$rule7 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($usersid,'Extendedright', 'Allow', [GUID]'5f202010-79a5-11d0-9020-00c04fc2d4cf')
$rule8 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($usersid,'WriteProperty', 'Allow', [GUID]'bf967953-0de6-11d0-a285-00aa003049e2')
# … and add it to the already present ACL
$mycomputeracl.AddAccessRule($rule1)
$mycomputeracl.AddAccessRule($rule2)
$mycomputeracl.AddAccessRule($rule3)
$mycomputeracl.AddAccessRule($rule4)
$mycomputeracl.AddAccessRule($rule5)
$mycomputeracl.AddAccessRule($rule6)
$mycomputeracl.AddAccessRule($rule7)
$mycomputeracl.AddAccessRule($rule8)
# now we have still a current ACL with the object while we have the ACL we need in $mycomputeracl.
# finally we apply the new ACL to the computer object using set-acl.
$mycomputeracl | set-acl "AD:$mycomputerdn"
Now we are finished with that computer and you can create a loop to go through your list of computers.