Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

pre-adding computer objects to AD

18 views
Skip to first unread message

Randy Reimers

unread,
Jul 9, 2003, 4:47:51 PM7/9/03
to
I would like to develop a script that would add computers to our AD - we
precreate them in a container called Workstations, which is in another
container, that exists in our domain "Corp.ccd.inet". using the MMC "Active
Directory Users and Computers", I create the computer in "Workstation",
enter the computer ID tag, then change the "User or Group:" from "Domain
Admins" to a different security group "Help Desk" so that the Help Desk
members (includes me) can add, manage, and delete the computer objects. The
AD path would be fixed at "corp.ccd.inet/TRC/Workstations". I don't change
any other options (yet).
I've seen several scripts, but haven't seen one that changes the default
group. I can enter the ID numbers with an inbox or from a file, and can
script the computer creation other than getting the proper group in. Anyone
with a good idea?

Thank you - Randy


Jeff Jones [MSFT]

unread,
Jul 10, 2003, 11:08:35 AM7/10/03
to
I can tell you what Active Directory Users and Computers (ADUC) does but I
don't know much about scripting so I can't tell you how to do it through
script.

ADUC reads the defaultSecurityDescriptor from the computer class definition
in the schema. It then reads all the ACEs and privileges that Creator/Owner
has on newly created computer objects and gives the specified group ("Help
Desk" in your case) the same rights and privileges that Creator/Owner has in
the defaultSecurityDescriptor.

--
Jeff Jones [MS]
Active Directory Administration Tools Development
Microsoft Corporation
This posting is provided "AS IS" with no warranties, and confers no rights.

"Randy Reimers" <rreimers (at) hotmail (dot) com> wrote in message
news:#i#getlRD...@TK2MSFTNGP12.phx.gbl...

Richard Mueller [MVP]

unread,
Jul 12, 2003, 3:48:49 PM7/12/03
to
Hi,

By experimenting, I find that 4 ACE's are added to the DACL for the computer
object when you give a group permission to join the computer to the domain.
These seem to correspond to the 4 permissions given to the group on the
Security tab for the computer object. These permissions are:

1. Reset Password
2. Validated write to DNS host name
3. Validated write to service principal name
4. Write Account Restrictions

Searching on the Microsoft site for information on the GUID's of the ACE's
added to the DACL, I find that they are called:

1. RESET_PASSWORD_GUID
2. VALIDATED_DNS_HOST_NAME
3. VALIDATED_SPN
4. USER_ACCOUNT_RESTRICTIONS

Sure enough, the VBScript program below will add the 4 ACE's to the DACL for
the group, with the specified trustee. Then, on the Security tab for the
computer object in AD Users & Computers you will see that the proper group
has the 4 permissions.

I have to caution that this appears to work, but I have not found any
documentation to support it. The computer Distinguished Name is hard coded
in the program below. The NT name of the group that will have permission to
add the computer to the domain is also hard coded. The NT name of the group
(the trustee) is in the form "MyDomain\TestGroup", where "MyDomain" is the
NetBIOS domain name and "TestGroup" is the sAMAccountName of the group. If
you can, reply with whether this works for you or not.

Option Explicit

Const USER_ACCOUNT_RESTRICTIONS = "{4C164200-20C0-11D0-A768-00AA006E0529}"
Const VALIDATED_SPN = "{F3A64788-5306-11D1-A9C5-0000F80367C1}"
Const VALIDATED_DNS_HOST_NAME = "{72E39547-7B18-11D1-ADEF-00C04FD8D5CD}"
Const RESET_PASSWORD_GUID = "{00299570-246D-11D0-A768-00AA006E0529}"
Const ADS_RIGHT_DS_CONTROL_ACCESS = &H100
Const ADS_RIGHT_DS_WRITE_PROP = &H20
Const ADS_RIGHT_DS_SELF = &H8
Const ADS_ACETYPE_ACCESS_ALLOWED = &H0
Const ADS_ACETYPE_ACCESS_DENIED = &H1
Const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = &H5
Const ADS_ACETYPE_ACCESS_DENIED_OBJECT = &H6
Const ADS_ACEFLAG_INHERITED_ACE = &H10
Const ADS_ACEFLAG_OBJECT_TYPE_PRESENT = &H1

Dim objSecDescriptor, objDACL, objComputer
Dim strComputerDN, strTrustee
Dim objACE1, objACE2, objACE3, objACE4

' Specify the trustee - NT group name.
strTrustee = "MyDomain\Help Desk"

' Bind to the computer object with the LDAP provider.
strComputerDN = "cn=Beta,cn=Computers,dc=MyDomain,dc=com"
On Error Resume Next
Err.Clear
Set objComputer = GetObject("LDAP://" & strComputerDN)
If Err.Number <> 0 Then
Err.Clear
Wscript.Echo "Computer not found" & vbCrLf & strComputerDN
Wscript.Quit(1)
End If
On Error GoTo 0

' Bind to the computer security objects.
Set objSecDescriptor = objComputer.Get("ntSecurityDescriptor")
Set objDACL = objSecDescriptor.discretionaryAcl

' Create ACE 1.
Set objACE1 = CreateObject("AccessControlEntry")
objACE1.Trustee = strTrustee
objACE1.AceFlags = 0
objACE1.AceType = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
objACE1.Flags = ADS_ACEFLAG_OBJECT_TYPE_PRESENT
objACE1.objectType = USER_ACCOUNT_RESTRICTIONS
objACE1.AccessMask = ADS_RIGHT_DS_WRITE_PROP
objDACL.AddAce objACE1

' Create ACE 2.
Set objACE2 = CreateObject("AccessControlEntry")
objACE2.Trustee = strTrustee
objACE2.AceFlags = 0
objACE2.AceType = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
objACE2.Flags = ADS_ACEFLAG_OBJECT_TYPE_PRESENT
objACE2.objectType = VALIDATED_SPN
objACE2.AccessMask = ADS_RIGHT_DS_SELF
objDACL.AddAce objACE2

' Create ACE 3.
Set objACE3 = CreateObject("AccessControlEntry")
objACE3.Trustee = strTrustee
objACE3.AceFlags = 0
objACE3.AceType = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
objACE3.Flags = ADS_ACEFLAG_OBJECT_TYPE_PRESENT
objACE3.objectType = VALIDATED_DNS_HOST_NAME
objACE3.AccessMask = ADS_RIGHT_DS_SELF
objDACL.AddAce objACE3

' Create ACE 4.
Set objACE4 = CreateObject("AccessControlEntry")
objACE4.Trustee = strTrustee
objACE4.AceFlags = 0
objACE4.AceType = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
objACE4.Flags = ADS_ACEFLAG_OBJECT_TYPE_PRESENT
objACE4.objectType = RESET_PASSWORD_GUID
objACE4.AccessMask = ADS_RIGHT_DS_CONTROL_ACCESS
objDACL.AddAce objACE4

' Reorder ACE's in DACL.
objSecDescriptor.discretionaryACL = Reorder(objDACL)

' Update the Computer object.
objComputer.Put "ntSecurityDescriptor", objSecDescriptor
objComputer.SetInfo

' Clean up.
Set objComputer = Nothing
Set objACE1 = Nothing
Set objACE2 = Nothing
Set objACE3 = Nothing
Set objACE4 = Nothing
Set objDACL = Nothing
Set objSecDescriptor = Nothing

Wscript.Echo "Done"

Function Reorder(objDACL)
' Reorder ACE's in DACL.

Dim objNewDACL, objInheritedDACL, objAllowDACL, objDenyDACL
Dim objAllowObjectDACL, objDenyObjectDACL, objACE

Set objNewDACL = CreateObject("AccessControlList")
Set objInheritedDACL = CreateObject("AccessControlList")
Set objAllowDACL = CreateObject("AccessControlList")
Set objDenyDACL = CreateObject("AccessControlList")
Set objAllowObjectDACL = CreateObject("AccessControlList")
Set objDenyObjectDACL = CreateObject("AccessControlList")

For Each objACE In objDACL
If ((objACE.AceFlags And ADS_ACEFLAG_INHERITED_ACE) = _
ADS_ACEFLAG_INHERITED_ACE) Then
objInheritedDACL.AddAce objACE
Else
Select Case objACE.AceType
Case ADS_ACETYPE_ACCESS_ALLOWED
objAllowDACL.AddAce objACE
Case ADS_ACETYPE_ACCESS_DENIED
objDenyDACL.AddAce objACE
Case ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
objAllowObjectDACL.AddAce objACE
Case ADS_ACETYPE_ACCESS_DENIED_OBJECT
objDenyObjectDACL.AddAce objACE
End Select
End If
Next

For Each objACE In objDenyDACL
objNewDACL.AddAce objACE
Next

For Each objACE In objDenyObjectDACL
objNewDACL.AddAce objACE
Next

For Each objACE In objAllowDACL
objNewDACL.AddAce objACE
Next

For Each objACE In objAllowObjectDACL
objNewDACL.AddAce objACE
Next

For Each objACE In objInheritedDACL
objNewDACL.AddAce objACE
Next

objNewDACL.ACLRevision = objDACL.ACLRevision
Set Reorder = objNewDACL

Set objNewDACL = Nothing
Set objInheritedDACL = Nothing
Set objAllowDACL = Nothing
Set objDenyDACL = Nothing
Set objAllowObjectDACL = Nothing
Set objDenyObjectDACL = Nothing
Set objACE = Nothing

End Function

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Jeff Jones [MSFT]" <jef...@online.microsoft.com> wrote in message
news:eMnmsUvR...@tk2msftngp13.phx.gbl...

Joe Richards [MVP]

unread,
Jul 13, 2003, 1:11:41 AM7/13/03
to
I can assure you that those are the four rights needed, our script used to set those exact ace's until we changed our OU
structures to just have the permissions in place already for the proper groups...

Here is a snipet from my old perl code to do it....


$sd = $adsnewcomputer->ntSecurityDescriptor;
$dACL = $sd->DiscretionaryAcl;

#
# Everyone - Write Account Restrictions
#
$ace = Win32::OLE->CreateObject("AccessControlEntry");
$ace->{Trustee}=$securitygroup;
$ace->{ObjectType}="{4C164200-20C0-11D0-A768-00AA006E0529}";
$ace->{AccessMask}=32;
$ace->{Flags}=$ADS_FLAG_OBJECT_TYPE_PRESENT;
$ace->{AceType}=$ADS_ACETYPE_ACCESS_ALLOWED_OBJECT;
$ace->{aceflags}=0;
$dACL->AddAce($ace);

#
# Everyone - Validated Write Service Principle Name
#
$ace = Win32::OLE->CreateObject("AccessControlEntry");
$ace->{Trustee}=$securitygroup;
$ace->{ObjectType}="{F3A64788-5306-11D1-A9C5-0000F80367C1}";
$ace->{AccessMask}=8;
$ace->{Flags}=$ADS_FLAG_OBJECT_TYPE_PRESENT;
$ace->{AceType}=$ADS_ACETYPE_ACCESS_ALLOWED_OBJECT;
$ace->{aceflags}=0;
$dACL->AddAce($ace);

#
# Everyone - Validated Write dNSHostName
#
$ace = Win32::OLE->CreateObject("AccessControlEntry");
$ace->{Trustee}=$securitygroup;
$ace->{ObjectType}="{72E39547-7B18-11D1-ADEF-00C04FD8D5CD}";
$ace->{AccessMask}=8;
$ace->{Flags}=$ADS_FLAG_OBJECT_TYPE_PRESENT;
$ace->{AceType}=$ADS_ACETYPE_ACCESS_ALLOWED_OBJECT;
$ace->{aceflags}=0;
$dACL->AddAce($ace);

#
# Everyone - Reset Password
#
$ace = Win32::OLE->CreateObject("AccessControlEntry");
$ace->{Trustee}=$securitygroup;
$ace->{ObjectType}="{00299570-246D-11D0-A768-00AA006E0529}";
$ace->{AccessMask}=256;
$ace->{Flags}=$ADS_FLAG_OBJECT_TYPE_PRESENT;
$ace->{AceType}=$ADS_ACETYPE_ACCESS_ALLOWED_OBJECT;
$ace->{aceflags}=0;
$dACL->AddAce($ace);

$sd->LetProperty('DiscretionaryAcl',$dACL);
$lasterror=Win32::OLE->LastError();
if ($lasterror)
{
print "Adding security 1 Error: $lasterror\n";
exit;
}

$adsnewcomputer->put("ntSecurityDescriptor",[$sd]);
$lasterror=Win32::OLE->LastError();
if ($lasterror)
{
print "Adding security 2 Error: $lasterror\n";
exit;
}
$adsnewcomputer->SetInfo();
$lasterror=Win32::OLE->LastError();
if ($lasterror)
{
print "Adding security 3 Error: $lasterror\n";
exit;
}

--
Joe Richards
www.joeware.net

--

"Richard Mueller [MVP]" <rlmu...@ameritech.net> wrote in message news:OFxvfMLS...@TK2MSFTNGP11.phx.gbl...

Randy Reimers

unread,
Jul 14, 2003, 11:45:48 AM7/14/03
to
I tried changing strTrustee and strComputerDN to correct values, and then
ran it using a computer object I created. I get an error in line 89
(objComputer.SetInfo) of "General access denied error". I don't know why
this would fail there - I obviously have the proper rights, as I can create
computer objects there. Also, this script seems to require an existing
object to bind to, how would I create it instead?

Thank you - Randy

"Richard Mueller [MVP]" <rlmu...@ameritech.net> wrote in message
news:OFxvfMLS...@TK2MSFTNGP11.phx.gbl...

Richard Mueller [MVP]

unread,
Jul 14, 2003, 11:35:32 PM7/14/03
to
Hi,

Yes, the script I posted assumed that the computer object already exists. To
create one, you bind to the parent container (the container or OU the
computer object should be in) and invoke the Create method:

Set objContainer = GetObject("LDAP://ou=Sales,dc=MyDomain,dc=com")
Set objComputer = objContainer.Create("computer", cn="NewComputer")
objComputer.Put "sAMAccountName", "NewComputer"
objComputer.SetInfo

Once the SetInfo is invoked, the object should exist and you should be able
to add the ACE's.

You got an error on the SetInfo statement. This indicates that you were able
to bind to the computer object. You were also able to retrieve the security
descriptor, so ADsSecurity.dll must be registered. However, there was a
problem with the modified security descriptor. When I specify an invalid
trustee an error is raised on the line where the security descriptor is
assigned (objComputer.Put "ntSecurityDescriptor"). The error message is "The
security ID structure is invalid". Your error is on the following line,
which I cannot explain.

To help troubleshoot, you might want to run the program linked below on a
computer object:

http://www.rlmueller.net/DACL.htm

This program documents the ACE's in the DACL for the specified object. You
hard code the Distinguished Name of the object (a computer object), and the
file that the output will be written to. You will see how trustees are
identified. If the computer is one that a group has been authorized to join
a domain, you will see entries for the 4 ACE's I described.

Good luck.

--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--

"Randy Reimers" <rreimers (at) hotmail (dot) com> wrote in message
news:#byQE8hS...@tk2msftngp13.phx.gbl...

0 new messages