Working with Active Directory via .NET has required using System.DirectoryServices which is a .NET wrapper for ADSI (used in VBScript) or System.DirectoryServices.ActiveDirectory which gives us access via .NET for administering Active Directory itself e.g. sites and subnets.
In PowerShell [ADSI] is a wrapper for System.DirectoryServices.DirectoryEntry – how you work with AD objects – and in PowerShell V2 [ADSISearcher] has been introduced as a wrapper for System.DirectoryServices.DirectorySearcher – how find things in AD. The use of [ADSI] has caused some confusion due to the need to use psbase to access the underlying object and the fact the VBScript methods have been implemented but aren’t visible to get-member. Some of these issues have been addressed in PowerShell V2.
When .NET 3.5 became available with Visual Studio 2008 we got access to another .NET namespace that can be used with AD – System.DirectoryServices.AccountManagement. This namespace is in effect a partial wrapper for System.DirectoryServices and gives us a number of options for working with user accounts.
System.DirectoryServices.AccountManagement is documented here – http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.aspx
The aim of this namespace is to simplify the management of user accounts in Active Directory. As well as AD these classes can be used against AD Lightweight Directory Services (ADAM) and the local SAM account database. Some actions such as enabling a user are much easier using this method.
The examples I will give in this and subsequent posts on this topic were all created on a Windows Server 2008 domain controller using PowerShell V2 CTP 2
Before we can do anything we need to create a user account. If you are doing this on a Vista or Windows Server 2008 with UAC enabled then you need to start PowerShell using the "Run as Administrator" option.
## add the assembly
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
## create a password
$password = Read-Host "Password" -AsSecureString
## create the context i.e. connect to the domain
$ctype = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, "manticore.org", "OU=AMTest,DC=Manticore,DC=org"
## create the user object
$usr = New-Object -TypeName System.DirectoryServices.AccountManagement.UserPrincipal -ArgumentList $context
## set the properties
$usr.Name = "AM Test1"
$usr.DisplayName = "AM Test1"
$usr.GivenName = "AM"
$usr.SurName = "Test1"
$usr.SamAccountName = "AMTest1"
$usr.UserPrincipalName = "firstname.lastname@example.org"
$usr.PasswordNotRequired = $false
$usr.Enabled = $true
## save the user
First action is to load the assembly containing the System.DirectoryServices.AccountManagement classes. This is necessary as its a .NET 3.5 assembly which isn’t loaded by default into PowerShell. I’ve used Add-Type (new to CTP2) for this. The same task could be done with Resolve-Assembly from the PowerShell Community Extensions or by the .NET [reflection.assembly]::LoadWithPartialName() method.
We will need to set a password for our new user so we use Read-Host to get the password as a secure string – all nice and encrypted.
Before we can actually create a user account we need to create a context – i.e. connect to the domain. The arguments tell the system that we are connecting to an AD domain, the name of the domain and in which OU in the domain we want to create the account. There is an assumption here that the current user credentials are sufficient to perform the creation. If they aren’t we can add a userid and password as further arguments.
Once we have the context we use System.DirectoryServices.AccountManagement.UserPrincipal with the context as an argument to create the account. It is a simple matter to then populate the properties of the account as shown. If you look at the documentation for this class at – http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.userprincipal.aspx – you will see that there are a very limited set of properties exposed for these objects. I do like the way we can just use $usr.Enabled = $true and avoid the useraccountcontrol flags entirely. Once the properties are set save() is used to write the account information into AD.
If you need to work with any of the properties not exposed through this class e.g. the address properties then
$u = $usr.GetUnderlyingObject()
will return a DirectoryEntry() object with which we can control everything.
This namespace isn’t a replacement for System.DirectoryServices but it does seem to have some very useful functionality that we will explore further in later posts.
|Share this post :|