Create ad user from CSV

HI my name is Gianluca and I’m a Newbie in powershell scripting.
I managed to create almost all the automations I need, but unfortunately I am stuck in some steps that I can’t solve, can you help me. I try to explain:
Here you will find the script and the CSV file

what I’m not capable of:

Row 58: set the manager field in AD and handle if the field is null, the data is not mandatory
Row 59: set the Primary group ID in AD user
Row 60: set the AccountExpirationDate in AD and handle if the field is null, the data is not mandatory
Row 61: Set the MemberOf field in AD with the CN delimitet by “,”
Row 71: the pager field is populated intermittently, I don’t understand if the syntax is correct

thanks to anyone who can help me
Gianluca

Gianluca,
Welcome to the forum. :wave:t4:

Row 58 and 60:

That’s simple. First create the hashtable without the optional attributes. And add them only when the according variables are filled.

$userParams = @{
    SamAccountName    = $Username
    UserPrincipalName = "$Username@reggiocity.it"
    Name              = $Username
}
if ($Manager) {
    $userParams.Manager = $Manager
}
if ($AccountExpirationDate) {
    $userParams.AccountExpirationDate = $AccountExpirationDate
}

Row 59:
That’s actually not necessary in the vast majority of the cases I know of. The default primary group is the DomainUsers. If you really need to set it you can output the newly created user account with providing the parameter -PassThru for the New-ADUser cmdlet and use

Set-ADUser -Replace @{PrimaryGroupID="513"}

to set the PrimaryGroupID attribute for the newly created user.

Row 61:
I’d recommend to use

It is made for adding a user to one or more groups with one command.

Row 71:
I never used this attribute so I don’t know either. Does it work the way you do? :wink:

BTW:
You code line 14 to 32 are unnecessary. You can use pipeline variable type ( $_.Something) directly for your splatting hashtable. :wink:

Hi Olaf, thanx for your help but i can’t get it to work.
Many of the csv field must be compiled, so I can’t understand what i’ve to do.

Row 58 and 60
I entered the code you indicated at the end of the script but I get an error

Row 59
I don’t understand what -Passwtru mean and where the csv field for the primaryGroupID is, ad es :
Set-ADUser -Replace @{PrimaryGroupID=’$PrimaryGroupID’}

Row 71
No, id doesn’t work as i expected, also in this case I need the “pager” field indicated in the csv to be inserted in the new AD user

BTW
Mi dispiace ma non ho capito :frowning:
I was thinking of mapping the csv fields before doing anything in order to have the variables always available
I usually do scripts in VBScript, but in this case powershell seemed like the best choice. Unfortunately, I am struggling with my poor preparation on this subject. Please forgive me for the questions I ask. Thanks

Actually this should be all you need:

$ADUsers = Import-Csv -Path 'Y:\GAS\newusers.csv' -Delimiter ';'

$ADUsers | 
ForEach-Object {
    if (Get-ADUser -Identity $($_.username) -ErrorAction SilentlyContinue) {
        Write-Warning "A user account with SamAccountName '$($_.username)' already exist in Active Directory."
    }
    else {
        $userParams = @{
            SamAccountName        = $_.username
            UserPrincipalName     = "$($_.username)@reggiocity.it"
            Name                  = $_.username
            GivenName             = $_.givenName
            Surname               = $_.sn
            Enabled               = $true
            DisplayName           = $_.username
            Path                  = $_.path
            AccountPassword       = (ConvertTo-SecureString $_.Password -AsPlainText -Force)
            ChangePasswordAtLogon = $true
            description           = $_.description
            OfficePhone           = $_.telephoneNumber
            EmailAddress          = $_.mail
            POBox                 = $_.postOfficeBox
            ScriptPath            = $_.scriptPath
            HomeDirectory         = $_.homeDirectory
            HomeDrive             = $_.homeDrive
            MobilePhone           = $_.mobile
            HomePhone             = $_.HomePhone
            Title                 = $_.Title
            Department            = $_.department
            Company               = $_.company
        }
        if ($_.manager) {
            $userParams.Manager = $_.manager
        }
        if ($_.accountExpires) {
            $userParams.AccountExpirationDate = $_.accountExpires
        }
        New-ADUser @userParams -PassThru | 
            Set-ADUser -Replace @{pager = $($_.pager); PrimaryGroupID = $($_.primaryGroupID) } -Verbose

        Write-Host "Created new user '$Username' with initial password: $($_.Password)"
    }
}

… untested … so test with a lab environment please. :wink:

1 Like

HI Olaf…thanx thanx thanx for your help.
I changed the first few lines because a “user not found” error was generated, and the primary groupID must be 513 (domain users) when creating the user. Now I try to convert the member of field into array and pass the variables to the script using Add-ADPrincipalGroupMembership and see if I can. In the meantime, thanks again

$ADUsers = Import-Csv -Path ‘Y:\GAS\newusers.csv’ -Delimiter ‘;’

$ADUsers | Where-Object { $.username -match ‘\S’} | ForEach-Object {
$Username = $
.username
if (Get-ADUser -Filter “SamAccountName -eq ‘$Username’” -ErrorAction SilentlyContinue) {
Write-Warning “A user account with SamAccountName ‘$Username’ already exist in Active Directory.”
}
else {
$userParams = @{

AFAIK is this the default and you don’t need to do this explicitly.

Yes, that’s actually expected behaviour. You may read about error handling …

Depending on the structure and the size of your AD it might be faster and less stress for the AD when you provide a -SearchBase for your query or even better when you query the relevant objects from the AD in advance, save the result to a variable and use this at runtime of your script. This way you wouldn’t query your AD again and again and again for each single element of your CSV input file.

If you save this information already in the proper format in your CSV you don’t need to convert it afterwards. :wink:

The CSV is generated by a webservice, one row, one user comma separeted
The memberOf field for every users,is populated like this: group1, group2, group, … etc
So i need to create ad array with:
group1
group2
group3

and for each group put the user in.
at the end i will set the primary group id.
or at least I try hahahahahahahahahahahah :smiley:
Thanx Olaf for your preciuos help

If you have a delimitted string you can use the -split operator.

"group1, group2, group" -split ','

To remove unwanted space charachters at the end or at the beginning you can use the .trim() method.

("group1, group2, group" -split ',').trim()

Did I mention that you probably don’t need to do that?

Here I am, this is the final version of the script and seems to be working:


$ADUsers = Import-Csv -Path 'Y:\GAS\newusers.csv' -Delimiter ';'

$ADUsers | Where-Object { $_.username -match '\S'} | ForEach-Object {
    $Username = $_.username
    if (Get-ADUser -Filter "SamAccountName -eq '$Username'" -ErrorAction SilentlyContinue) {
        Write-Warning "A user account with SamAccountName '$Username' already exist in Active Directory."
    }
    else {
        $userParams = @{
            SamAccountName        = $_.username
            UserPrincipalName     = "$($_.username)@reggiocity.it"
            Name                  = $_.username
            GivenName             = $_.givenName
            Surname               = $_.sn
            Enabled               = $true
            DisplayName           = $_.username
            Path                  = $_.path
            AccountPassword       = (ConvertTo-SecureString $_.Password -AsPlainText -Force)
            ChangePasswordAtLogon = $true
            description           = $_.description
            OfficePhone           = $_.telephoneNumber
            EmailAddress          = $_.mail
            POBox                 = $_.postOfficeBox
            ScriptPath            = $_.scriptPath
            HomeDirectory         = $_.homeDirectory
            HomeDrive             = $_.homeDrive
            MobilePhone           = $_.mobile
            HomePhone             = $_.HomePhone
            Title                 = $_.Title
            Department            = $_.department
            Company               = $_.company
        }
        if ($_.manager) {
            $userParams.Manager = $_.manager
        }
        if ($_.accountExpires) {
            $userParams.AccountExpirationDate = $_.accountExpires
        }
        New-ADUser @userParams -PassThru | 
            Set-ADUser -Replace @{pager = $($_.pager)}
            
            $Inputstring = $($_.MemberOf)
            $CharArray =$Inputstring.Split(",")
            $CharArray

            ForEach ($Items in $Username)

                {
                Add-ADPrincipalGroupMembership -Identity $Username -MemberOf $CharArray
                Get-ADuser "$Username" |Set-ADuser -Replace @{PrimaryGroupID = $($_.PrimaryGroupID)}
                }                     

        Write-Host "Created new user '$Username' with initial password: $($_.Password)"
        Write-Host "gruppi a cui appartiene= $($_.MemberOf)"
    }

   
}

Did I mention that you probably don’t need to do that?
Each user belonging to a service has a different primarygroupID, so I have to set it every time.

Is there anything I can optimize or further checks I can do in your opinion?

Thanx

seems to be working”?? You should be able to see if it’s working or not, don’t you? :wink: :smiley:

There’s always something you can improve. Actually I already mentioned some possible improvements in my earlier answer. :wink:
For now, if you’re satisfied and the script is running without errors and doing what you want - it’s fine.
I think with time when your PowerShell knowledge eveolves you will see by yourself where you can tweak your old scripts when you review them from time to time.

hahahah…yes IT’S WORKING :smiley:
G

Hi Olaf I’ve a strange problem , maybe you can help me.
During the user creation I’m using this set of istruction to se the ACL on the homefolder of the user:

#Modifica ACL per cartella W:
                    $PathSRC="\\reggiocity.it\fs\Utenti\Default"
                    $PathTRG= $_.homeDirectory
                    Get-acl $PathSRC | Set-Acl $PathTRG
                    $acl = Get-Acl $PathTRG
                    $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($Username,'FullControl',('ContainerInherit,ObjectInherit'),'None','Allow')
                    $acl.SetAccessRuleProtection($true,$true)
                    $acl.SetAccessRule($AccessRule)
                    $acl | Set-Acl $PathTRG

The $PathSRC is the source folder from which I copy the default ACL
the $PathTRG is the homefolder written in the csv file that corrispond the USERNAME ad es:
\reggiocity.it\fs\utenti\calogp.
The acl is not set correctly, there is only the SID, which has a different value from that of the user

.
I hope you can help me as you have done up to now and for which I am grateful
Thanks