[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