RSS All Posts

RSS PowerShell Posts

Tags

2142 Active Directory Administrativia Announcements Battlefield Blogging Cricket Deployment Deployment4 Get-PSUGUK Group Policy HowTo Linux MDT MDT 2010 Microsoft Deployment Toolkit MSDN Music Permissions Personal PowerGui Power Lines PowerShell PowerShell Groups PowerShell Support PowerShell Tools PowerShell V2 Presentations PSUGAU Quick Tips Scripting SDDL Security Tech Talk Ubuntu User Groups Virtualisation VMware Infrastructure Client WAIK Weekly Poll Windows 7 Windows Automation Installation Kit Windows Server 2003 Windows Server 2008 XML

Archives

Meta


« | Main | »

Creating a User Account in Active Directory with PowerShell

By Adam Bell | February 14, 2007

There are a lot of attributes that can set when creating a User in AD. I’m not going to display them all here, but if you’re interested in what can be set (on any AD object) I recommend using ADSIedit which is included with the Windows Support Tools shipped on the Windows Server disc.

It’s worth mentioning here that this is a very powerful tool. It doesn’t wrap you in wool while you’re wandering around your Active Directory. You can really screw it up if you’re not careful. I would therefore strongly advise that you use this tool on a development environment where a mistake is less likely to get you fired ;)

Microsoft have an overview of ADSIedit here.

Below is the function to create an account, and then we’ll step through some points of interest.
new-account.ps1


# Constants from: http://msdn2.microsoft.com/en-us/library/aa772300.aspx
Set-Variable -Name ADS_UF_ACCOUNT_DISABLE      -value 0x2  -option constant
Set-Variable -Name ADS_UF_DONT_EXPIRE_PASSWORD    -value 0x10000  -option constant
Set-Variable -Name ADS_UF_PASSWORD_EXPIRED      -value 0x800000  -option constant
 
$rootdn = ([adsi]"").distinguishedName
 
# ---------------------------------------------------------------------------------------------------
function Convert-DNtoFQDN
# ---------------------------------------------------------------------------------------------------
{
Param (
  $DNname
  )
  $FQDN = $null
  $bits = $DNname.split(",")
  # Put each section back together again with the period in place.
  foreach ($part in $bits)
  {
    $a = $part.split("=")
    $FQDN = $FQDN+$a[1]+"."  
  }
  # Need to drop the trailing dot from the end.
  $FQDN = $FQDN.substring(0,$FQDN.length -1)
  return $FQDN
}
 
# ---------------------------------------------------------------------------------------------------
function create-account
# ---------------------------------------------------------------------------------------------------
{
# Depends on Convert-DNtoFQDN function
Param (
  $Location,
  $User,
  $Desc = $null,
  $Password = $null
  )
  # If a password isn't provided use this one.
  $DefaultPass = "LetM3In"
  
  $ou = [adsi]("LDAP://"+$Location+","+$rootdn)
  $newuser = $ou.create("user", "cn="+$User)
  $newuser.Put("sAMAccountName", $User)
 
  if ($Desc -ne $null) { $newuser.Put("Description", $desc) }
 
  # Build the UPN based on the $rootdn value.
  $newuser.Put("userPrincipalName", $User+"@"+(Convert-DNtoFQDN $rootDn.ToString()))
  $newuser.SetInfo()
    
  If ($Password -ne $null)
  {
    $newuser.psbase.invoke("setpassword", $Password)
  }
  else
  {
    $newuser.psbase.invoke("setpassword", $DefaultPass)
  }
  $newuser.SetInfo()
  
  # Enable the account
  $newuser.psbase.invokeset('accountdisabled', $false)
  
  # a value of 0 effectively ticks the "User must change password at next logon"
  # box. A value of -1 clears this tick.
  $newuser.PwdLastSet = 0
  $newuser.Setinfo()
  
  # When manipulating UAC bits, you need to OR them to the existing UAC flag to enable them
  # and AND (NOT) them to remove them. Or you can just write the bitwise number to the attribute...
  $uacFlag = $newuser.userAccountControl
  $newflag = $uacFlag[0] -bor $ADS_UF_DONT_EXPIRE_PASSWORD
  $newuser.userAccountControl = $newflag
  $newuser.setinfo()  
}

This function can be called in several ways. Due to defining default values for two of the variables we can call it with:


create-account "ou=Test OU" "BellA" "Adam's Test Account" "Password12"

Or we could just use:


create-account "ou=Test OU" "BellA"

And the default password will be used.

The caveat here is that the password must conform to the password requirements for the domain!. Otherwise the function will be successful, however the password will not work when you try and logon.

The last thing to note is that the last two code blocks actually conflict with each other. You cannot set the account to require a password change on next logon, and set the password doesn’t expire bit. If you attempt this through Active Directory Users and Computers, the following dialog is displayed:

AD User Account Conflict Error

With the code blocks above the PwdLastSet attribute is set, however it’s overwritten by the UAC flag setting.

This is quite a simple example of creating an account. We have only set some of the mandatory attributes. There is no first (givenName) and surname (sn) defined. I’ll show you in another post how to retrieve the attributes from the User class. In the mean time ADSIedit provides a simple interface for browsing what’s available.

Topics: Active Directory, PowerShell | 5 Comments »

5 Responses to “Creating a User Account in Active Directory with PowerShell”

  1. Peter {faa780ce-0f0a-4c28-81d2-3667b71287fd} Says:
    February 16th, 2007 at 19:03

    I’ve built a similar script to create user accounts. My big question is: have you attempted to tackle setting up home folders? As far as I can tell, doing that in PowerShell is uncharted territory. Anyway, your user creation script is way nicer than mine :)

  2. Peter {faa780ce-0f0a-4c28-81d2-3667b71287fd} Says:
    February 16th, 2007 at 21:41

    Nevermind, I found the solution in pure C# and adapted it for my full-user-setup script. Feel free to do…whatever…with it.

    1. Link/citing source: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1204480&SiteID=1

    2. Calling lines of code:

    #—————-
    CreateHomeDirectory $username
    $u.put(“homeDirectory”, $homeDirectory)
    $u.put(“homeDrive”, $homeDrive)
    $u.setInfo()
    #——————–

    3. Function:

    #———————
    function CreateHomeDirectory
    {
    param([string]$username)

    trap
    {
    write-host “ERROR on account: $username”
    write-host “ID: ” $_.ErrorID
    write-host “Message: “$_.Exception.Message

    break
    }

    $folderpath = “{0}{1}” -f $USER_ROOT_UNC, $username
    $folder = get-item $folderpath -ErrorAction SilentlyContinue
    if (-not $folder)
    {
    #see http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1204480&SiteID=1
    #this explains why you need to set three rules for one user.

    $folder = new-item $folderpath -itemtype directory -ErrorAction Stop
    #InheritanceFlags.ObjectInherit = 2
    #PropogationFlags.InheritOnly = 2
    $ar1 = new-object System.Security.AccessControl.FileSystemAccessRule($username,”FullControl”,2,2,”Allow”)

    #InheritanceFlags.ContainerInherit = 1
    #PropogationFlags.InheritOnly = 2
    $ar2 = new-object System.Security.AccessControl.FileSystemAccessRule($username,”FullControl”,1,2,”Allow”)

    $ar3 = new-object System.Security.AccessControl.FileSystemAccessRule($username,”FullControl”,”Allow”)

    $acl = get-acl $folder
    $acl.AddAccessRule($ar1)
    $acl.AddAccessRule($ar2)
    $acl.AddAccessRule($ar3)
    set-acl $folder $acl -ErrorAction Stop
    }
    else
    {
    #ERROR.
    #home directory shouldn’t already exist for a brand new user.
    #this is a potential collision – need to manually resolve.
    throw “user: $username – already has home directory of the same name.”
    }
    }

  3. Peter {faa780ce-0f0a-4c28-81d2-3667b71287fd} Says:
    March 12th, 2007 at 18:41

    Yeargh, my above function is giving me problems today, I’d like to retract this from the internet in general until I figure it out :)

  4. Briano Says:
    July 17th, 2007 at 13:11

    I used the following code to convert DN to FQDN:

    #get the DN
    $rootDSE = [ADSI]“LDAP://RootDSE”
    $domainDN = $rootDSE.Get(“DefaultNamingContext”)

    #convert the DN to FQDN
    $domainFQDN = $domainDN -replace(“,dc=”,”.”) -replace(“dc=”,”")

  5. AdamBell Says:
    July 17th, 2007 at 13:17

    Hi Briano,

    Nice way of doing it. I wrote a function (see sample code page) that does the same thing, but isn’t as elegant.

    It was something I wrote early on playing with PoSH, and so is VBScript centric. I like your PoSH way much better.

    Time to ferret out the library file and update it ;)

    Thanks for the comment.

    Cheers

    Adam

Comments