
close
close
Chance to win $250 in Petri 2023 Audience Survey
I hope you have been enjoying our exploration of PowerShell Active Directory alternatives. Certainly, the Active Directory module from RSAT is the way to go but sometimes you may want a bit more control. You also may have a need to roll your own tools. Today, I want to give you some ideas on how to create user accounts using LDAP and ADSI. If you are just jumping in, I recommend you take a few minutes to get caught up with the previous articles:
The first thing you will need is an ADSI reference to the organizational unit or container.
[ADSI]$OU = "LDAP://OU=IT,OU=Departments,OU=Employees,DC=Globomantics,DC=Local"
I want to create a user account for a new hire, Ginger Snaps. I will do this with the Create() method on the OU object. This method needs an object type and a canonical name. Be sure to save the results to a variable because you will need it.
$new = $OU.Create("user","CN=Ginger Snaps")
Right now, this account only exists locally. The first property to set is the account name. This is a new object, which means we need to use the Put() method.
$new.put("samaccountname","gsnaps")
You can also use the InvokeSet() method.
$new.InvokeSet("samaccountname","gsnaps")
Even though I will be setting additional properties, I need to commit the account to Active Directory before going any further.
$new.setinfo()
Don’t worry. The account is disabled by default and does not have a password. So let’s set those things now.
$new.put("userAccountControl",544)
If you want to disable the account, do not set it to this or 546. You can define a new password and configure the account. The user will have to change the password at next login.
#set initial password $new.setpassword("P@ssw0rd") #force change at next logon $new.Put("pwdLastSet",0)
All of these changes are with the local cached copy of the user account. While I am at it, I might as well set some additional user properties.
$new.put("UserPrincipalName","gsnaps@globomantics.local") $new.put("DisplayName","Ginger Snaps") $new.Put("Department","IT") $new.put("Title","PowerShell Specialist") $new.put("GivenName","Ginger") $new.put("sn","Snaps") $new.put("company","Globomantics") $new.put("description","PowerShell/DevOps Team")
The tricky part is figuring out the LDAP property name. Some of them are not obvious. One thing you can do is use the AttributeEditor on a user account in Active Directory Users and Computers. I started a disabled dummy account and filled out all of the fields. Next, I used the Attribute Editor tab.
User Attribute Editor (Image Credit: Jeff Hicks)
$new.setinfo()
As soon as replication converges, I can see the new account.
Verify the New Account (Image Credit: Jeff Hicks)
$OU.Delete("user","CN=Ginger Snaps")
Be careful. The deletion is immediate and there is no -WhatIf support.
Of course, this would be much easier with some sort of tooling like a function. You could write a version of New-ADUser customized to your environment with different parameters for the different user properties. I wrote something a bit more flexible.
Function New-LDAPUser { [cmdletbinding()] Param( [parameter(Position = 0, Mandatory)] [ValidatePattern("^\w+\s\w+$")] [string]$Name, [string]$DefaultPassword = "P@ssw0rd", [string]$OU = "OU=Employees,DC=Globomantics,DC=Local", [hashtable]$Properties, [switch]$Disable, [switch]$Passthru ) #try to get the OU [ADSI]$Parent = "LDAP://$OU" #verify the OU exists if (-Not $parent.distinguishedname) { Write-Warning "Can't find OU $OU" #bail out Return } #split name into two variables $firstname,$lastname = $name.split() #define samaccountname $sam = "{0}{1}" -f $firstname[0],$lastname Write-Verbose "Testing if $sam already exists in the domain" #test if name already exists in the domain [ADSI]$Test = "WinNT://$($env:userdomain)/$sam,user" If ($test.ADSPath) { Write-Warning "A user with the account name of $sam already exists" #bail out Return } Write-Verbose "Creating new user $Name in $OU" $new = $parent.Create("user","CN=$Name") $new.put("samaccountname",$sam) $new.setinfo() Write-Verbose "Setting name properties" $new.put("givenname",$firstname) $new.put("sn",$lastname) $new.put("userprincipalname","$sam@globomantics.local") $new.put("Displayname",$name) if ($hash) { Write-Verbose "Setting additional properties" foreach ($key in $hash.keys) { Write-Verbose "...$key" #verify property is valid Try { $new.invokeGet($key) $new.put($key,$hash.item($key)) } Catch { Write-Warning "$key is not a valid property name" } } } Write-Verbose "set initial password" $new.setpassword("P@ssw0rd") Write-Verbose "force change at next logon" $new.Put("pwdLastSet",0) if ($Disable) { Write-Verbose "Disabling the account" $new.put("userAccountControl",546) } else { $new.put("userAccountControl",544) } Write-Verbose "committing changes" $new.setinfo() if ($Passthru) { $new.refreshcache() $new } } #end function
This version does not include support for WhatIf but you could add it. The function needs the distinguishedname for the parent container and the user’s name. I am using simple names such as John Deere. The samAccountname is derived from the first initial of both the first and last name. I have a code that creates it from the username, which I have split.
#split name into two variables $firstname,$lastname = $name.split() #define samaccountname $sam = "{0}{1}" -f $firstname[0],$lastname
Of course, you would need to define your own standard code. I have included some validation to ensure a valid OU without a naming conflict. This version simply reports any of these problems and bails out.
Otherwise, the function uses the steps I outlined above to create and define a user account.
Creating a New User (Image Credit: Jeff Hicks)
The New Account (Image Credit: Jeff Hicks)
$hash=@{ Company = "globomantics" Department = "IT" Title = "DevOps Engineer" Description = "Project Phoenix" PhysicalDeliveryOfficeName = "QK-456" phone = "x8732" }
The function processes this hashtable and sets the value for each entry, assuming it is valid. I use the InvokeGet() method, which will throw an error with an invalid property. I can create a richer user account.
New-LDAPUser -Name "Ken Dew" -OU "OU=IT,OU=Departments,OU=Employees,DC=Globomantics,DC=local" -Properties $hash -Passthru -Verbose
Creating a Rich User Object (Image Credit: Jeff Hicks)
More in PowerShell
Most popular on petri