Active Directory and Computers

Computers and users actually have a lot in common, at least from Active Directory's point of view. This article, the first in a four-part series, will explore how Active Directory handles computers. It is excerpted from chapter eight of the Active Directory Cookbook, Second Edition, written by Robbie Allen and Laura E. Hunter (O'Reilly; ISBN: 059610202X). Copyright © 2006 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 4
January 10, 2008
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

As far as Active Directory is concerned, computers are very similar to users. In fact, computer objects inherit directly from the user object class, which is used to represent user accounts. That means thatcomputerobjects possess all of the attributes ofuserobjects and then some. Computers need to be represented in Active Directory for many of the same reasons users do, including the need to access resources securely, utilize GPOs, and have permissions assigned to them.

To participate in a domain, computers need a secure channel to a domain controller. A secure channel is an authenticated connection that can transmit encrypted data. To set up the secure channel, a computer must present a password to a domain controller. Similar to the way in which it authenticates a user account, Active Directory will use Kerberos authentication to verify the identity of a computer account. Without thecomputer object and, by association, the password stored with it that is changed behind the scenes on a regular basis by the operating system, there would be no way for the domain controller to verify a computer is what it claims to be.

The Anatomy of a Computer

The default location for computer objects in a domain is thecn=Computerscontainer located directly off the domain root. You can, however, createcomputer objects anywhere in a domain. And in Windows Server 2003, you can modify the default location forcomputerobjects as described in Recipe 8.12. Table 8-1 contains a list of some of the interesting attributes that are available oncomputerobjects.

Table 8-1. Attributes of computer objects

Attribute Description
cn Relative distinguished name ofcomputerobjects.
dnsHostName Fully qualified DNS name of the computer.

Table 8-1. Attributes of computer objects (continued)

Attribute Description
lastLogonTimestamp The approximate timestamp of the last time the computer logged in to the domain. This is a new attribute in Windows Server 2003.
managedBy The distinguished name (DN) of user or group that manages the computer.
memberOf List of DNs of the groups the computer is a member of.
operatingSystem Textual description of the operating system running on the computer. See Recipe 8.13 for more information.
operatingSystemHotFix Currently not being used, but will hopefully be populated at some point.
operatingSystemServicePack Service pack version installed on the computer. See Recipe 8.13 for more information.
operatingSystemVersion Numeric version of the operating system installed on the computer. See Recipe 8.13 for more information.
pwdLastSet Large integer that can be translated into the last time the computer’s password was set. See Recipe 8.9 for more information.
sAMAccountName NetBIOS-style name of the computer. This is typically the name of the computer with$at the end.
userAccountControl Account flag that defines various account properties. In the case of a computer object, this specifies whether the computer is a member computer or a domain controller.

Creating a Computer

Problem

You want to create a computer account.

Solution

Using a graphical user interface

  1. Open the ADUC snap-in.

  2. If you need to change domains, right-click on Active Directory Users and Computers in the left pane, select “Connect to Domain,” enter the domain name, and click OK.
  3. In the left pane, browse to the parent container for the computer, right-click on it, and select New -> Computer.
  4. Enter the name of the computer. If necessary, place a checkmark next to “Assign this computer as a pre-Windows 2000 computer” or “Assign this computer as a backup domain controller.” Click Next to continue.
  5. If you will be using this computer account as part of an RIS deployment, place a checkmark next to “This is a managed computer” and enter the GUID that it should use, and then click Next. Otherwise, just click Next to continue.
  6. Click Finish.
Using a command-line interface

You can create a computer object using either the built-in DSAdd utility or AdMod. To create an account using DSAdd, use the following syntax:

  > dsadd computer "<ComputerDN>" -desc "<Description>"

To create a computer account using AdMod, enter the following:

  > admod -b "<ComputerDN>" objectclass::computer
    sAMAccountName::<ComputerName>$ userAccountControl::4096
    description::"<Description>" -add

Using VBScript

  ' This code creates a computer object.
  ' ------ SCRIPT CONFIGURATION -----
  strBase = "<ParentComputerDN>" ' e.g. cn=Computers,dc=rallencorp,dc=com
  strComp = "<ComputerName>"     ' e.g.
joe-xp
  strDescr = "<Description>"     ' e.g. Joe's Windows XP workstation
  ' ------ END CONFIGURATION --------

  ' ADS_USER_FLAG_ENUM
  Const ADS_UF_WORKSTATION_TRUST_ACCOUNT = &h1000 ' 4096

  set objCont = GetObject("LDAP://" & strBase)
  set objComp = objCont.Create("computer", "cn=" & strComp)
  objComp.Put "sAMAccountName", strComp & "$"
  objComp.Put "description", strDesc
  objComp.Put "userAccountControl", ADS_UF_WORKSTATION_TRUST_ACCOUNT
  objComp.SetInfo
  Wscript.Echo "Computer account for " & strComp & " created"

Discussion

Creating a computer object in Active Directory is not much different from creating auser object. We set thedescriptionattribute in the CLI and API solutions, but it is not a mandatory attribute. The only mandatory attribute issAMAccountName, which should be set to the name of the computer with$appended. Also note that these solutions simply create acomputerobject. This does not mean any user can join a computer to the domain with that computer account. For more information on creating acomputer object and allowing a specific user or group to join the computer to the domain, see Recipe 8.2.

See Also

Recipe 8.2 for creating a computer for a user, MS KB 222525 (Automating the Creation of Computer Accounts), MS KB 283771 (How to Prestage Windows 2000 Computers in Active Directory), MS KB 315273 (Automating the Creation of Computer Accounts), MS KB 320187 (How to Manage Computer Accounts in Active Directory in Windows 2000), and MSDN: ADS_USER_FLAG_ENUM

Creating a Computer for a Specific User or Group

Problem

You want to create a computer account for a specific user or group to join to the domain. This requires setting permissions on the computer account so that the user or group can modify certain attributes.

Solution

Using a graphical user interface

  1. Open the ADUC snap-in.
  2. If you need to change domains, right-click on Active Directory Users and Computers in the left pane, select “Connect to Domain,” enter the domain name, and click OK.
  3. In the left pane, browse to the parent container for the computer, right-click on it, and select New -> Computer.
  4. Enter the name of the computer.
  5. Under “The following user or group can join this computer to a domain,” click the Change button.
  6. Use the Object Picker to select a user or group to join the computer to the domain.
  7. Click OK.

Using a command-line interface

In the following solution, replace <ComputerDN> with the distinguished name of thecomputerobject and <UserOrGroup>with the user principal name or NT-style name of a user or group you want to manage the computer:

  > dsadd computer <ComputerDN>
  > dsacls <ComputerDN> /G <UserOrGroup>:CALCGRSDDTRC;;
  > dsacls <ComputerDN> /G <UserOrGroup>:WP;description;
  > dsacls <ComputerDN> /G <UserOrGroup>:WP;sAMAccountName;
  > dsacls <ComputerDN> /G <UserOrGroup>:WP;displayName;
  > dsacls <ComputerDN> /G <UserOrGroup>:WP;"userAccountControl;
  > dsacls <ComputerDN> /G <UserOrGroup>:WS;"Validated write to service principal\
  name";
  > dsacls <ComputerDN> /G <UserOrGroup>:WS;"Validated write to DNS host name";

You can replace the first line of this code with the AdMod code from Recipe 8.1 if you choose.

Using VBScript

  ' This code creates a computer object and grants a user/group rights over it.
  ' ------ SCRIPT CONFIGURATION ------
  strComputer = "<ComputerName>"   ' e.g. joe-xp 
  strUser     = "<UserOrGroup>"    ' e.g.
joe@rallencorp.com or RALLENCORP\joe
  strDescr    = "<ComputerDescr>"  ' e.g. Joe's workstation
  strDomain   = "<ComputerDomain>" ' e.g. rallencorp.com
  ' ------ END CONFIGURATION ---------

  '############################
  ' Constants
  '############################

  ' ADS_USER_FLAG_ENUM
  Const ADS_UF_PASSWD_NOTREQD             = &h0020
  Const ADS_UF_WORKSTATION_TRUST_ACCOUNT  = &h1000

  ' ADS_ACETYPE_ENUM
  Const ADS_ACETYPE_ACCESS_ALLOWED        = &h0
  Const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = &h5

  ' ADS_FLAGTYPE_ENUM
  Const ADS_FLAG_OBJECT_TYPE_PRESENT = &h1

  ' ADS_RIGHTS_ENUM
  Const ADS_RIGHT_DS_SELF           = &h8
  Const ADS_RIGHT_DS_WRITE_PROP     = &h20
  Const ADS_RIGHT_DS_CONTROL_ACCESS = &h100
  Const ADS_RIGHT_ACTRL_DS_LIST     = &h4
  Const ADS_RIGHT_GENERIC_READ      = &h80000000
  Const ADS_RIGHT_DELETE            = &h10000
  Const ADS_RIGHT_DS_DELETE_TREE    = &h40
  Const ADS_RIGHT_READ_CONTROL      = &h20000

  ' schemaIDGUID values
  Const DISPLAY_NAME     = "{bf967953-0de6-11d0-a285-00aa003049e2}"
  Const SAM_ACCOUNT_NAME = "{3e0abfd0-126a-11d0-a060-00aa006c33ed}"
  Const DESCRIPTION      = "{bf967950-0de6-11d0-a285-00aa003049e2}"

  ' controlAccessRight rightsGUID values
  Const USER_LOGON_INFORMATION    = "{5f202010-79a5-11d0-9020-00c04fc2d4cf}"
  Const USER_ACCOUNT_RESTRICTIONS = "{4C164200-20C0-11D0-A768-00AA006E0529}"
  Const VALIDATED_DNS_HOST_NAME   = "{72E39547-7B18-11D1-ADEF-00C04FD8D5CD}"
  Const VALIDATED_SPN             = "{F3A64788-5306-11D1-A9C5-0000F80367C1}"

  '############################
  ' Create Computer 
  '############################

  set objRootDSE = GetObject("LDAP://" & strDomain & "/RootDSE")
  set objContainer = GetObject("LDAP://cn=Computers," & _
                              objRootDSE.Get("defaultNamingContext"))
  set objComputer = objContainer.Create("Computer", "cn=" & strComputer)
  objComputer.Put "sAMAccountName", strComputer & "$"
  objComputer.Put "userAccountControl", _
                  
ADS_UF_PASSWD_NOTREQD Or ADS_UF_WORKSTATION_TRUST_ACCOUNT
  objComputer.Put "description", strDescr
  objComputer.SetInfo

  '############################
  ' Create ACL
  '############################

  set objSD = objComputer.Get("nTSecurityDescriptor")
  set objDACL = objSD.DiscretionaryAcl

  ' Special: Control Rights, List Children
  '          Generic Read, Delete,
  '          Delete Subtree, Read Permission 
  set objACE1 = CreateObject("AccessControlEntry")
  objACE1.Trustee    = strUser
  objACE1.AccessMask = ADS_RIGHT_DS_CONTROL_ACCESS Or _
                    
ADS_RIGHT_ACTRL_DS_LIST Or _
                     ADS_RIGHT_GENERIC_READ Or _
                     ADS_RIGHT_DELETE Or _ 
                    ADS_RIGHT_DS_DELETE_TREE Or ADS_RIGHT_READ_CONTROL
  objACE1.AceFlags  = 0
  objACE1.AceType   = ADS_ACETYPE_ACCESS_ALLOWED

  ' Write Property: description
  set objACE2 = CreateObject("AccessControlEntry")
  objACE2.Trustee     = strUser
  objACE2.AccessMask  = ADS_RIGHT_DS_WRITE_PROP
  objACE2.AceFlags    = 0
  objACE2.Flags       = ADS_FLAG_OBJECT_TYPE_PRESENT
  objACE2.AceType     = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
 
objACE2.ObjectType  = DESCRIPTION

  ' Write Property: sAMAccountName
  set objACE3 = CreateObject("AccessControlEntry")
  objACE3.Trustee     = strUser
  objACE3.AccessMask  = ADS_RIGHT_DS_WRITE_PROP
  objACE3.AceFlags    = 0
  objACE3.Flags       = ADS_FLAG_OBJECT_TYPE_PRESENT
  objACE3.AceType     = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
  objACE3.ObjectType  = SAM_ACCOUNT_NAME

  ' Write Property: displayName
  set objACE4 = CreateObject("AccessControlEntry")
  objACE4.Trustee     = strUser
  objACE4.AccessMask  = ADS_RIGHT_DS_WRITE_PROP
  objACE4.AceFlags    = 0
  objACE4.Flags       = ADS_FLAG_OBJECT_TYPE_PRESENT
  objACE4.AceType     = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
  objACE4.ObjectType  = DISPLAY_NAME

  ' Write Property: Logon Information
  set objACE5 = CreateObject("AccessControlEntry")
  objACE5.Trustee     = strUser
  objACE5.AccessMask  = ADS_RIGHT_DS_WRITE_PROP
 
objACE5.AceFlags    = 0
  objACE5.AceType     = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
  objACE5.Flags       = ADS_FLAG_OBJECT_TYPE_PRESENT
 
objACE5.ObjectType  = USER_LOGON_INFORMATION

  ' Write Property: Account Restrictions
  set objACE6 = CreateObject("AccessControlEntry")
  objACE6.Trustee     = strUser
  objACE6.AccessMask  = ADS_RIGHT_DS_WRITE_PROP
  objACE6.AceFlags    = 0
  objACE6.AceType     = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
  objACE6.Flags       = ADS_FLAG_OBJECT_TYPE_PRESENT
  objACE6.ObjectType  = USER_ACCOUNT_RESTRICTIONS

  ' Write Self: Validated SPN
  set objACE7 = CreateObject("AccessControlEntry")
  objACE7.Trustee     = strUser
  objACE7.AccessMask  = ADS_RIGHT_DS_SELF
  objACE7.AceFlags    = 0
  objACE7.AceType     = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
  objACE7.Flags       = ADS_FLAG_OBJECT_TYPE_PRESENT
  objACE7.ObjectType  = VALIDATED_SPN

  ' Write Self: Validated DNS Host Name
  set objACE8 = CreateObject("AccessControlEntry")
  objACE8.Trustee     = strUser
  objACE8.AccessMask  = ADS_RIGHT_DS_SELF
  objACE8.AceFlags    = 0
  objACE8.AceType     = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
  objACE8.Flags       = ADS_FLAG_OBJECT_TYPE_PRESENT
  objACE8.ObjectType  = VALIDATED_DNS_HOST_NAME

  objDACL.AddAce objACE1
  objDACL.AddAce objACE2
  objDACL.AddAce objACE3
  objDACL.AddAce objACE4
  objDACL.AddAce objACE5
  objDACL.AddAce objACE6
  objDACL.AddAce objACE7
  objDACL.AddAce objACE8

  '############################
  ' Set ACL
  '############################ 
  objSD.DiscretionaryAcl = objDACL
  objComputer.Put "nTSecurityDescriptor", objSD
  objComputer.SetInfo
  WScript.Echo "Successfully created " & strComputer & _
              
" and gave rights to " & strUser

Discussion

By default, members of the Authenticated Users group can join up to 10 computers to an Active Directory domain. If you’ve modified this default behavior or need to allow a user to add computers to the domain on a regular basis, you need to grant certain permissions so that the user has rights to modify the computer object. When you create a computer via the ADUC snap-in, you have the option to select a user or group to manage thecomputerobject and join a computer to the domain using that object. When you use that method, eight ACEs are added to the ACL of thecomputer object. They are:

  1. List Contents, Read All Properties, Delete, Delete Subtree, Read Permissions, All Extended Rights (i.e., Allowed to Authenticate, Change Password, Send As, Receive As, Reset Password)
  2. Write Property for description
  3. Write Property forsAMAccountName
  4. Write Property fordisplayName
  5. Write Property for Logon Information
  6. Write Property for Account Restrictions
  7. Validate write to DNS hostname
  8. Validate write for service principal name
Using a graphical user interface

If you want to modify the default permissions that are applied when you select a user or group through the GUI, double-click on the computer object after you’ve created it and go to the Security tab. For the Security tab to be visible, you have to select View -> Advanced Features.

Using a command-line interface

With the dsacls utility, you can specify either a UPN (user@domain ) or down-level style (DOMAIN\user) account name when applying permissions. Also, dsacls requires that the displayNameof the attribute, property set, or extended right you are setting the permission on be used instead of thelDAPDisplayName, as one might expect. That is why we had to use “Validated write to service principal name,” which is thedisplayNamefor theValidated-SPN controlAccessRightobject, with the ACE for the SPN-validated write. dsacls is also case sensitive, so be sure to specify the correct case for the words in thedisplayName.

Using VBScript

After creating the computer object, similar to Recipe 8.1, create an ACE object for each of the eight ACEs previously listed using the IADsAccessControlEntry interface.

To apply the ACEs, retrieve the current security descriptor for the computer object, which is stored in thenTSecurityDescriptorattribute, and then add the eight ACEs. Finally, callSetInfoto commit the change to Active Directory. For more information on setting ACEs and ACLs programmatically, see theIADsAccessControlEntrydocumentation in MSDN.

See Also

Recipe 8.1 for creating a computer account, MS KB 238793 (Enhanced Security Joining or Resetting Machine Account in Windows 2000 Domain), MS KB 283771 (How to Prestage Windows 2000 Computers in Active Directory), MS KB 320187 (How to Manage Computer Accounts in Active Directory in Windows 2000), MSDN: IADsAccessControlEntry, MSDN: ADS_ACETYPE_ENUM, and MSDN: ADS_RIGHTS_ENUM, MSDN: ADS_FLAGTYPE_ENUM

Joining a Computer to a Domain

Problem

You want to join a computer to a domain after the computer object has already been created in Active Directory.

Solution

Using a graphical user interface

  1. Log on to the computer you want to join to the domain and open the Control Panel.
  2. Open the System applet.
  3. Click the Computer Name tab.
  4. Click the Change button.
  5. Under “Member of,” select Domain.
  6. Enter the domain you want to join and click OK.
  7. You may be prompted to enter credentials that grant permission to join the computer.
  8. Reboot the computer.

    Note that the tabs in the System applet vary between Windows 2000, Windows XP, and Windows Server 2003.

Using a command-line interface

  > netdom join <ComputerName> /Domain <DomainName> /UserD <DomainUserUPN>   
  /PasswordD * /UserO <ComputerAdminUser>  /PasswordO * /Reboot  

Using VBScript

  ' This code joins a computer to a domain.
  ' ------ SCRIPT CONFIGURATION ------

  strComputer    = "<ComputerName>"   ' e.g. joe-xp
  strDomain      = "<DomainName>"     ' e.g. rallencorp.com
  strDomainUser  = "<DomainUserUPN>"  ' e.g.
administrator@rallencorp.com
   strDomainPasswd = "<DomainUserPasswd>" 
  strLocalUser    = "<ComputerAdminUser>"
' e.g. administrator
  strLocalPasswd  = "<ComputerUserPasswd>"
  ' ------ END CONFIGURATION ---------

  '########################
  ' Constants
  '########################
  Const JOIN_DOMAIN             = 1
  Const ACCT_CREATE             = 2
  Const ACCT_DELETE             = 4
  Const WIN9X_UPGRADE           = 16
  Const DOMAIN_JOIN_IF_JOINED   = 32
  Const JOIN_UNSECURE           = 64
  Const MACHINE_PASSWORD_PASSED = 128
  Const DEFERRED_SPN_SET        = 256
  Const INSTALL_INVOCATION      = 262144

  '###########################
  ' Connect to Computer 
  '###########################
  set objWMILocator = CreateObject("WbemScripting.SWbemLocator") 
 objWMILocator.Security_.AuthenticationLevel = 6
  set objWMIComputer = objWMILocator.ConnectServer(strComputer, _
                           "root\cimv2", _
                           strLocalUser, _ 
                           strLocalPasswd)
  set objWMIComputerSystem = objWMIComputer.Get( _
          "Win32_ComputerSystem.Name='" & _
          strComputer & "'")

  '###########################
  ' Join Computer 
  '###########################
  rc = objWMIComputerSystem.JoinDomainOrWorkGroup(strDomain, _ 
                 
strDomainPasswd, _
                  strDomainUser, _ 
                  vbNullString, _   
                  JOIN_DOMAIN)
  if rc <> 0 then
      WScript.Echo "Join failed with error: " & rc
  else
      WScript.Echo "Successfully joined " & strComputer & " to " & strDomain
  end if

Discussion

When trying to add a computer to Active Directory, you can either precreate the computer object as described in Recipes 8.1 and 8.2 before joining it to the domain, or you can perform both operations at the same time.

Using a graphical user interface

If you have the correct permissions in Active Directory, you can actually create a computer object at the same time as you join it to a domain via the instructions described in the GUI solution. Since the System applet doesn’t allow you to specify an OU for the computer object, if it needs to create a computerobject, it will do so in the defaultComputerscontainer. See Recipe 8.15 for more information on the default computers container and how to change it.

Using a command-line interface

The netdom command will attempt to create a computer object for the computer during a join if one does not already exist. An optional/OUswitch can be added to specify the OU in which to create thecomputerobject. To do so, you’ll need to have the necessary permissions to create and managecomputerobjects in the OU.

There are some restrictions on running thenetdom joincommand remotely. If a Windows XP machine has theForceGuestsecurity policy setting enabled, you cannot join it remotely. Running thenetdomcommand directly on the machine works regardless of theForceGuestsetting.

Using VBScript

In order for the Win32_ComputerSystem::JoinDomainOrWorkGroup method to work remotely, you have to use an AuthenticationLevel equal to 6 so that the traffic between the two machines (namely the passwords) is encrypted. You can also create computerobjects usingJoinDomainOrWorkGroupby using theACCT_CREATEflag in combination withJOIN_DOMAIN.

This function works only with Windows XP and Windows Server 2003 and is not available for Windows 2000 and earlier machines.

Just like with the netdom utility, you cannot run this script against a remote computer if that computer has theForceGuestsetting enabled.

See Also

More information on the ForceGuest setting can be found here: http://www.microsoft. com/resources/ documentation/Windows/XP/all/reskit/en-us/ prde_ffs_ypuh.asp, MS KB 238793 (Enhanced Security Joining or Resetting Machine Account in Windows 2000 Domain), MS KB 251335 (Domain Users Cannot Join Workstation or Server to a Domain), MS KB 290403 (How to Set Security in Windows XP Professional That Is Installed in a Workgroup), MSDN: Win32_ComputerSystem::JoinDomainOrWorkgroup, and MSDN: NetJoinDomain.

Please check back next week for the continuation of this article.

blog comments powered by Disqus
WINDOWS SCRIPTING ARTICLES

- More Windows Scripting Workarounds from Nilpo
- Overloading Methods and More in VBScript
- Improving MFC for Windows Vista
- Regular Expressions in VBScript
- Working with Dates in WMI
- Completing Calendars with VBScript Date Func...
- Building Calendars with VBScript Date Functi...
- Working With Dates and Times in VBScript
- Designing WCF DataContract Classes Using the...
- Understanding Dates and Times in VBScript
- Working With Arrays in VBScript
- Compressed Folders in WSH
- Using .NET Interops in VBScript
- Nilpo`s Scripting Secrets, Vol I
- Database operations using Silverlight 2.0 WC...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 6 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials