Creating object
The key to effectively using PowerShell to create objects in Active Directory is using the Active Directory Service Interfaces (ADSI) accelerator. The target of the ADSI operation is called the ADsPath.
After you make your connection into Active Directory, you hold the system.DirectoryServices.
To create an object by using ADSI, perform the following steps:
1. Use the [ADSI] accelerator.
2. Use the appropriate ADSI provider.
3. Specify the path to the appropriate object in Active Directory.
4. Use the SetInfo() method to write the changes.
Creating an OU
The process of creating an OU in Active Directory provides the basis for creating other objects in Active Directory because the technique is basically the same.
CreateOU.ps1 $strCLass = "organizationalUnit" $StrOUName = "ou=MyTestOU" $objADSI = [ADSI]"LDAP://dc=nwtraders,dc=msft" $objOU = $objADSI.create($strCLass, $StrOUName) $objOU.setInfo()
- In this example, the variable $strClass is used to hold the class of object to create in Active Directory.Standard attribute types are expected by ADSI—such as ou for “organizational unit.”
- Domain name is nwtraders.msft.
- Because you will pass this variable directly to the Create method, it is important that you use the distinguished-name form, which is “ou=MytestOU”. The attribute that is used with the Create method to create an object in Active Directory is called the relative distinguished name (RDN).
- After getting connection into Active Directory, you can now use the create method to create your new object.
- The system.DirectoryServices.DirectoryEntry object that is returned is held in the $objOU variable. You use this object on the last line of the script to call the SetInfo() method to write the new object into the Active Directory database.
ADSI providers
The available ADSI providers:
Provider | Purpose |
WinNT | To communicate with Windows NT 4.0 primary domain controllers (PDCs) and backup domain controllers (BDCs), and with local account databases for Windows 2000 and newer workstations and servers |
LDAP | To communicate with LDAP servers, including Exchange 5.x directories and Windows 2000 Server or Windows Server 2003 Active Directory |
NDS | To communicate with Novell Directory Services servers |
NWCOMPAT | To communicate with Novell NetWare 3.x servers |
Note: The WinNT name is Pascal cased—that is, it is partially uppercase and partially lowercase. It cannot be typed using all lowercase letters or all uppercase letters.
All other provider names must be all uppercase letters.
ADSI Edit is included with the feature called AD DS and AD LDS Tools. To install these tools on Windows 8 Server, use the Add-WindowsFeature cmdlet from the ServerManager module.
To install the tools, pipeline the results from the Get-WindowsFeature cmdlet to Add-WindowsFeature.
PS C:\> Get-WindowsFeature rsat-ad-tools | Add-WindowsFeature
LDaP names
When specifying the OU and the domain name, you have to use the LDAP naming convention, in which the namespace is described as a series of naming parts called RDNs (Relative Distinguished Name). The RDN will always be a name part that assigns a value by using the equal sign (e.g. CN=computer, DC=test,DC=com).
Attribute | Description |
DC | Domain Component |
CN | Common Name |
OU | Organisational Unit |
O | Organisation name |
Street | Street Address |
C | Country Name |
UID | User ID |
Binding
Whenever you want to do anything with ADSI, you must connect to an object in Active Directory—a process also known as binding. Think of binding as being like tying a rope around an object to enable you to work with it. The binding string enables you to use various ADSI elements, including methods and properties.
A binding string consists of four parts.
Accelerator |
Variable |
Provider | ADsPath |
[ADSI] | $objDomain | LDAP:// | OU=hr, dc=a, dc=com |
Avoid a mistake I made early on: make sure that when you fnish connecting and creating, you actually commit your changes to Active Directory. Changes to Active Directory are transactional in nature, so your change will roll back if you don’t commit it. Committing the change requires you to use the SetInfo() method.
Work with users
To modify user properties in Active Directory, do the following:
1. Implement the appropriate protocol provider.
2. Perform binding to Active Directory.
3. Specify the appropriate ADsPath.
4. Use the Put method to write selected properties to users.
5. Use the SetInfo() method to commit changes to Active Directory.
The tabs used most often are General and Account tabs:
General user information
One of the more confusing issues when you use Windows PowerShell to modify information in
Active Directory is that the names displayed on the property page do not correspond with the ADSI nomenclature.
Name in ADUC | LDAP Attribute | Format | Attribute-ID |
First Name | givenName | Single | 2.5.4.42 |
Initials | initials | Single | 2.5.4.43 |
Last Name | sn | Single | 2.5.4.4 |
Display Name | displayName | Single | 1.2.840.113556.1.2.13 |
Description | description | Single* | 2.5.4.13 |
Office | physicalDeliveryOfficeName | Single | 2.5.4.19 |
Telephone Number | telephoneNumber | Single | 2.5.4.20 |
Single | 0.9.2342.19200300.100.1.3 | ||
Web Page | wWWHomepage | Single | 1.2.840.113556.1.2.464 |
Other… (behind Telephone number) | OtherTelephone | Array | |
Other… (behind Web page) | URL | Array |
Two of the attributes accept an array: OtherTelephone and url. The url attribute is particularly misleading— first because it is singular, and second because the othertelephone value uses the style otherTelephone. In addition, the primary webpage uses the name wwwHomePage. When supplying values for the OtherTelephone and url attributes, ensure the input value is accepted as an array by using the @() characters to cast the string into an array.
Account tab
Name in ADUC | LDAP Attribute | Format | Attribute-ID |
User Logon Name | userPrincipalName | Single | 1.2.840.113556.1.4.656 |
User Logon Name (pre-Windows 2000) | sAMAccountName | Single | 1.2.840.113556.1.2.256 |
Logon Hours | logonHours | Single | 1.2.840.113556.1.4.64 |
Log on To | userWorkstations | Single | 1.2.840.113556.1.4.86 |
User must change password at next logon | Pwd-Last-Set ** | Single | 1.2.840.113556.1.4.96 |
User cannot change password | see notes below | Permission | {AB721A53-1E2F-11D0-9819-00AA0040529B} |
Account Expires | accountExpires | qWord | 1.2.840.113556.1.4.159 |
Account Options | See notes below | Various | N/A |
Example: modify user info
In this example, we have a user named MyNewUser been already created, we will add more info on it
$objUser = [ADSI]"LDAP://cn=MyNewUser,ou=myTestOU,dc=iammred,dc=net" $objUser.put("SamaccountName", "myNewUser") $objUser.put("givenName", "My") $objUser.Put("initials", "N.") $objUser.Put("sn", "User") $objUser.Put("DisplayName", "My New User") $objUser.Put("description" , "simple new user") $objUser.Put("physicalDeliveryOfficeName", "RQ2") $objUser.Put("telephoneNumber", "999-222-1111") $objUser.Put("OtherTelephone",@("555-555-1212","555-555-1213")) $objUser.Put("mail", "[email protected]") $objUser.Put("wwwHomePage", "http://www.ScriptingGuys.com") $objUser.Put("url",@("http://www.ScriptingGuys.Com/blog","http://www.ScriptingGuys.com/ LearnPowerShell")) $objUser.setInfo()
Address tab
Name in ADUC | LDAP Attribute | Format | Attribute-ID |
Display | displayName | Single | 1.2.840.113556.1.2.13 |
Street | streetAddress | Single | 1.2.840.113556.1.2.256 |
P.O. Box | postOfficeBox | Multi | 2.5.4.18 |
City | L | Single | 2.5.4.7 |
State | st | Single | 2.5.4.8 |
Zip/Postal Code | postalCode | Single | 2.5.4.17 |
Country / Region | co | Single | 1.2.840.113556.1.2.131 |
Dail-in Tab
Note that the “doesn’t exist” option can be set by bellow command:
set-aduser username -clear msnpallowdialin
Which basically choose ” Control acces through NPS Network Policy”
For more attributes: http://www.selfadsi.org/user-attributes-w2k8.htm
Creating users
Steps to create users:
1. Use the appropriate provider for your network.
2. Connect to the container for your users.
3. Specify the domain.
4. Specify the User class of the object.
5. Bind to Active Directory.
6. Use the Create method to create the user.
7. Use the Put method to at least specify the sAMAccountName attribute.
8. Use SetInfo() to commit the user to Active Directory.
Example:
$strCLass = “User”
$StrName = “CN=MyNewUser”
$objADSI = [ADSI]”LDAP://ou=myTestOU,dc=nwtraders,dc=msft”
$objUser = $objADSI.create($strCLass, $StrName)
$objUser.Put(“sAMAccountName”, “MyNewUser”)
$objUser.setInfo()
Creating Group
1. Open the CreateUser.ps1 script in Notepad and save it as <yourname>CreateGroup.ps1.
2. Declare a variable called $intGroupType. This variable will be used to control the type of group to create. Assign the number 2 to the variable. When used as the group type, a type 2 group will be a distribution group. This line of code is shown here:
$intGroupType = 2
3. Change the value of $strClass from User to Group. This variable will be used to control the type of object that gets created in Active Directory. This is shown here:
$strGroup = “Group”
4. Change the name of the $objUser variable to $objGroup (it’s less confusing that way). This will need to be done in two places, as shown here:
$objGroup = $objADSI.create($strCLass, $StrName)
$objGroup.setInfo()
5. Above the $objGroup.setInfo() line, use the Put method to create a distribution group. The distribution group has a group type of 2, and you can use the value held in the $intGroupType variable. This line of code is shown here:
$ObjGroup.put(“GroupType”,$intGroupType)
6. Save and run the script. It should create a group called MyNewGroup in the MyTestOU in Active Directory. If the script does not perform as expected, compare your script with the CreateGroup.ps1 script.
Working with Users
To modify user properties in Active Directory, do the following:
1. Implement the appropriate protocol provider.
2. Perform binding to Active Directory.
3. Specify the appropriate ADsPath.
4. Use the Put method to write selected properties to users.
5. Use the SetInfo() method to commit changes to Active Directory
Two of the attributes accept an array:
OtherTelephone and url. The url attribute is particularly misleading—first because it is singular, and second because the othertelephone value uses the style otherTelephone. In addition, the primary webpage uses the name wwwHomePage. When supplying values for the OtherTelephone and url
attributes, ensure the input value is accepted as an array by using the @() characters to cast the string into an array. The use of all these values is illustrated in ModifyUserProperties.ps1, shown here:
ModifyUserProperties.ps1 $objUser = [ADSI]"LDAP://cn=MyNewUser,ou=myTestOU,dc=iammred,dc=net" $objUser.put("SamaccountName", "myNewUser") $objUser.put("givenName", "My") $objUser.Put("initials", "N.") $objUser.Put("sn", "User") $objUser.Put("DisplayName", "My New User") $objUser.Put("description" , "simple new user") $objUser.Put("physicalDeliveryOfficeName", "RQ2") $objUser.Put("telephoneNumber", "999-222-1111") $objUser.Put("OtherTelephone",@("555-555-1212","555-555-1213")) $objUser.Put("mail", "[email protected]") $objUser.Put("wwwHomePage", "http://www.ScriptingGuys.com") $objUser.Put("url",@("http://www.ScriptingGuys.Com/blog","http://www.ScriptingGuys.com/ LearnPowerShell")) $objUser.setInfo()
Creating the address page
Active Directory Users and Computers label | Active Directory attribute name |
Street | streetAddress |
P.O. Box | postOfficeBox |
City | l (Note that this is lowercase L.) |
State/province | st |
Zip/Postal Code | postalCode |
Country/region | C ,CO, CountryCode |
When working with address-type information in Windows PowerShell, the hard thing is keeping track of the country codes. You can either use C as Alpha-2 code, such as US, or co , such as United state, or countrycode, a numeric number, such as 840.
You can search these here https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes
E.g.
ModifySecondPage.ps1 $objUser = [ADSI]"LDAP://cn=MyNewUser,ou=myTestOU,dc=iammred,dc=net" $objUser.put("streetAddress", "123 main st") $objUser.put("postOfficeBox", "po box 12") $objUser.put("l", "Charlotte") $objUser.put("st", "SC") $objUser.put("postalCode" , "12345") $objUser.put("c", "US") $objUser.put("co", "United States") $objUser.put("countryCode", "840") $objUser.setInfo()
Caution: The three country fields are not linked in Active Directory. You could easily have a
C code value of US, a CO code value of Zimbabwe, and a CountryCode value of 470 (Malta).
This could occur if someone uses the Active Directory Users and Computers to make a
change to the country property. When this occurs, it updates all three fields. If someone
later runs a script to only update the CountryCode value or the CO code value, then
Active Directory Users and Computers will still reflect the translated value of the C code.
This could create havoc if your enterprise resource planning (ERP) application uses the CO
or CountryCode value and not the C attribute. Best practice is to update all three fields
through your script.
Modifying the user profile settings
Let’s recap the concept here:
- ProfilePath. This controls where the user’s profile will be stored. On my server, the location is \\London\Profiles in a folder named after the user, which in this case is myNewUser.
- ScriptPath. This controls which logon script will be run when the user logs on. Even though this attribute is called ScriptPath, it does not expect an actual path statement (it assumes the script is in the sysvol share); rather, it simply
needs the name of the logon script. On my server, I use a logon script called logon.vbs. Modify the second $objUser.put statement in your script to point to a logon script. The modified command is shown here:
$objUser.put(“scriptPath”, “logon.vbs”) - HomeDirectory, it is used to control where the user’s home directory will be stored. This attribute needs a Universal Naming Convention (UNC)–formatted path to a shared directory.
- The HomeDrive attribute in Active Directory is used to control the mapping of a drive letter to the user’s home directory. On my server, all users’ home drives are mapped to drive H (for home). Please note that Active Directory does not expect a trailing backslash for the HomeDirectory attribute. Modify the last $objUser.put command to map the user’s home drive to the appropriate drive letter for your environment. The modified command is shown here:
$objUser.put("homeDrive", "H:")
The most confusing part is the difference between Profile path and Home folder:
By default, they are same location, and you can verify by command ” set HOME” and “set userprofile”.
Profile path is where your environment is stored – background image, color preference, personalization, customizations, and other settings related to your userprofile.
Your profile can be stored within your home folder, but doesn’t have to be… And this is where the roaming profile path can be.
Your profile is located by default under C:\Documents and Settings in System Winxp or earlier, and c:\users\your_username in Windows 7 or later.
You can easily alter this in a domain environment.
Typically home folders point to a user name variable, instead of a specific location (else you’d have to ‘hard code’ every body’s home folder).
So homefolder could be \\server1\%username%, where a shared folder can be.
Reference
User tabs:
User account attributes: http://www.selfadsi.org/user-attributes-w2k8.htm