[update august 23th, 2010] This is a new version (1.10) that allows you put an ‘#’ in the ‘password’ field to be able to update properties of an existing user without modifying his password.
# # .SYNOPSIS # Create users in Active Directory from a CVS file (';' delimited). # # .DESCRIPTION # The CSV file used to create the users must have a special format. # The first line of the CVS file must contain columns names. # Each column name must correspond exactly to an attribute name of # a user object in the Active Directory. # All Active Directory attributes containing a text value can be used. # # The following columns (attributes) are mandatory : # # Name If this field contain a '#', the line will # ingnored (commented). # OU # Password If this filed contain # '#', the password # will not be set. Of course the user must # already exist. # # The follwing attributes (columns) cannot be used, they are automatically # generated by the script : # # sAMAccountName # userPrincipalName # # The following special columns (attributes) are handle by the script : # # OU Organizational Unit containing the user to be created. # The distingushedName of the domain will be appended. # sAMAccountName Automicically set to the value of the Name column # userPrincipalName Automicically set to the value of the Name column # plus the canonicl name of the domain # (ex: user1@domain.com) # MemberOf List of group names separeted by a comma (,) do not # specified the full distingushedName or the group # only the name, the script will do the rest. # AccountExpires Set the expiration date of the new account # # If an attribute of the new user cannot be set, the new user account will # be left disabled. # # If the user account already exists, the script will not end and will # try to set the attributes of the accounts. # # Here's a sample CSV file : # Name;OU;Password;displayName;mail;description;AccountExpires;memberOf # PdelphiC1;ou=UtilisateursExternes;!42mj428;My First Poweshell User;chico@hotmail.com ;This is a test;2010-09-15;group 1,group 2 # PdelphiC2;ou=UtilisateursExternes;$93me934;My second PowerShell User;binou@hotmail.com ;This is a test;2010-09-15;group 3 # # This is a sample input file for Import-Users.ps1 # # Author : Jean-Pierre.Paradis@fsa.ulval.ca # Date : august 23, 2010 # Version : 1.10 # Language : PowerShell 2.0 # # .PARAMETER CSVInputFile # Input file name. # # .EXAMPLE # C:\PS> .\Import-users.ps1 -CSVInputFile "users.cvs" # # .LINK # Inspire by Don Jones and Jeffrey Hicks in 'Windows powershell 2.0 TFM' from Sapien Press # #REQUIRES -version 2.0 param ( [parameter( Mandatory=$true)] [String[]]$CSVInputFile ) Set-StrictMode -Version 2.0 # Script parameters # $CSVInputFile="newusers.csv" $Delimiter=";" $DirectoryServicesCOMException_ENTRY_EXISTS=-2147019886 function get-scriptdirectory { # .SYNOPSIS # Return the current script directory path, compatible with PrimalScript 2009 # Equivalent to VBscript fso.GetParentFolderName(WScript.ScriptFullName) # Requires PowerShell 2.0 # # .DESCRIPTION # Author : Jean-Pierre.Paradis@fsa.ulaval.ca # Date : March 31, 2010 # Version : 1.01 # # .LINK # http://blog.sapien.com/index.php/2009/09/02/powershell-hosting-and-myinvocation/ if (Test-Path variable:\hostinvocation) {$FullPath=$hostinvocation.MyCommand.Path} Else { $FullPath=(get-variable myinvocation -scope script).value.Mycommand.Definition } if (Test-Path $FullPath) { return (Split-Path $FullPath) } Else { $FullPath=(Get-Location).path Write-Warning ("Get-ScriptDirectory: Powershell Host <" + $Host.name + "> may not be compatible with this function, the current directory <" + $FullPath + "> will be used.") return $FullPath } } function get-GroupDN { # .SYNOPSIS # Return an Active Directory group distinguished name param ( [parameter( Mandatory=$true)] [String[]]$GroupShortName ) $AdSearch = [ADSISearcher] "" $AdSearch.Filter = "(&(objectCategory=group)(cn=$($GroupShortName)))" $AdResult = $ADSearch.FindOne() if ($AdResult -ne $null) { return $AdResult.properties.distinguishedname } Else { Write-Warning ("get-GroupDN: Can't find group named <$($GroupShortName)>") return $null } } function add-UserToGroups { # .SYNOPSIS # Add a user to an array of groups param ( [parameter( Mandatory=$true)] [String]$UserDistinguishedName, [parameter( Mandatory=$True)] [System.Array]$Groups ) Foreach ($GroupName in $Groups) { $GroupDN = get-GroupDN($GroupName) if ($GroupDN -ne $null) { Write-host " Adding to group '$($groupname)' ..." $GroupObj=[adsi]("LDAP://"+$GroupDN) $GroupObj.member.add($UserDistinguishedName) >$null Try { $GroupObj.SetInfo() } Catch [System.DirectoryServices.DirectoryServicesCOMException] { If ($_.exception.ErrorCode -eq $DirectoryServicesCOMException_ENTRY_EXISTS) { Write-Warning "The user is already a member." } else { Throw $_ } } } } } # Read the data file and filter any commented line $CSVInputFileFullPath = (get-scriptdirectory($CSVInputFile)) + "\" + $CSVInputFile $imported=Import-Csv $CSVInputFileFullPath -Delimiter $Delimiter | where {$_.name -notlike '#*'} # retrieve list of csv column headings # Each column heading should correspond to an ADSI user property name $properties=$imported | Get-Member -type noteproperty | ` where {$_.name -ne "OU" -and $_.name -ne "Password" ` -and $_.name -ne "Name" -and $_.name -ne "sAMAccountName" ` -and $_.name -ne "userPrincipalName"} # Get the domain canonicalName (mydomain.com) & distinguishedname $rootDomain=[ADSI]"" $rootDomain.RefreshCache(@("canonicalName")) $rootDomainCanonicalName=($rootDomain.get("canonicalName") -replace "/","") $rootDomainDistinguishedName=$rootDomain.distinguishedName # Loop throuth the data foreach ($user in $imported) { # Create the account $UserAlreadyExist=$false $OUDistinguishedName = $user.OU+","+$rootDomainDistinguishedName Write-Host "Creating User '$($user.Name)' in '$($OUDistinguishedName)' ..." [ADSI]$OU="LDAP://"+$OUDistinguishedName $newUser=$OU.Create("user","CN="+$user.Name) $newUser.Put("sAMAccountName",$user.Name) # Get the domain canonicalName (mydomain.com) $rootDomain=[ADSI]"" $rootDomain.RefreshCache(@("canonicalName")) # Set userPrincipalName $newUserPrincipalName=$user.Name + "@" + $rootDomainCanonicalName $newUser.Put("userPrincipalName",$newUserPrincipalName) # commit creation to Active Directory Try { $newUser.SetInfo() } Catch [System.DirectoryServices.DirectoryServicesCOMException] { If ($_.exception.ErrorCode -eq $DirectoryServicesCOMException_ENTRY_EXISTS) { Write-Warning "The object already exist, will try to reset properties." $newUser=[adsi]("LDAP://"+"CN="+$user.Name+","+$OUDistinguishedName) $UserAlreadyExist=$true } else { Throw $_ } } # set a password If ($user.password -notlike '#*') { Write-Host (" Setting password") $newUser.SetPassword($user.Password) $newUser.SetInfo() } # set additional properties foreach ($prop in $properties) { $value=$user.($prop.name) if (($value -ne $Null) -and ($value.length -gt 0)) { Switch ($prop.name ) { "MemberOf" { # Write-Host (" Adding to groups $($Value)") add-UserToGroups $newUser.distinguishedname @($value -split ",") } "AccountExpires" { $newAccountExpires = ($value -as [datetime]) if ($newAccountExpires -ne $null) { Write-Host (" Setting '$($prop.name)' to $($newAccountExpires)") $newUser.InvokeSet("AccountExpirationDate",$newAccountExpires) } Else { Write-Warning " Can't convert '$($value)' to acceptable format for AccountExpires" } } default { #only set properties that have values Write-Host (" Setting '$($prop.name)' to '$($value)'") $newUser.put($prop.name,$value) } } } } $newUser.SetInfo() # Activate the account If ($UserAlreadyExist -ne $True) { Write-Host (" Enabling account") $newUser.Invokeset("AccountDisabled", "False") $newUser.SetInfo() } }
No comments:
Post a Comment