Solved

New-ADUser with Import-CSV & AccountPassword

Posted on 2011-03-23
17
4,154 Views
Last Modified: 2012-08-13
I want to create many AD users from a CSV file.

The CSV file has the following columns:
GivenName;Surname;SamAccountName;Name;DisplayName;UserPrincipalName;AccountPassword;OfficePhone;StreetAddress;PostalCode;City;Company;State;Country;EmailAddress;Path

Open in new window

--> Important: In the CSV are passwords defined.

After spending hours in testing various combinations of these CMDlets I've got this one working, but only with one entity.

$csv = Import-Csv -Delimiter ";" -Path "C:\import.csv"
$csv | New-ADUser -Enabled $true -ChangePasswordAtLogon $true -AccountPassword (ConvertTo-SecureString $csv.AccountPassword -AsPlainText -Force)

Open in new window


When I add a second entity, I get this error:
ConvertTo-SecureString : The argument can not be bound to the parameter "string" because it is NULL.
When I delete the column "AccountPassword" it's also working with multiple entities.
So the problem is just the function with SecureString.

I've already found this:
http://www.experts-exchange.com/Software/Server_Software/File_Servers/Active_Directory/Q_26333527.html?sfQueryTermInfo=1+10+30+adus+new
This methode with foreach is working, but I really don't like it because of so much variables...


I just can't believe there is no method which is working with setting passwords on multiple entities!
0
Comment
Question by:eSourceONE
  • 7
  • 6
  • 4
17 Comments
 
LVL 12

Expert Comment

by:FDiskWizard
ID: 35198019
Did you try something like this:
$csv = Import-Csv -Delimiter ";" -Path "C:\import.csv"
$csv | Foreach-object {New-ADUser -Enabled $true -ChangePasswordAtLogon $true -AccountPassword}
 
And you may also want to check out the Quest cmdlets. They provide a lot of AD commands.
0
 
LVL 12

Expert Comment

by:FDiskWizard
ID: 35198049
From Quest new user cmdlet help:

 -------------------------- EXAMPLE 3 --------------------------

 C:\PS>$pw = read-host "Enter password" -AsSecureString

 C:\PS>connect-qadService -service 'localhost' -proxy -ConnectionAccount 'company\administrator' -ConnectionPassword $pw

 C:\PS>import-csv C:\temp\data.csv | %{new-qadUser -ParentContainer 'OU=companyOU,DC=company,DC=com' -name $_.'user name'}

 C:\PS>disconnect-qadService
___________________________________________________

I think the CONNECT line is only needed if you need to supply an alternate login.
0
 

Author Comment

by:eSourceONE
ID: 35198160
When I use the Foreach-Object it seems that I can't access the pipelined data.
So I have to define every variables first before going on (described in the link in my question)
And that's exactly what I don't want to.

The thing is: every user in the CSV gets another password.
If everybody would get the same, it would be easy because I don't have to pipe the passwords.

Perhaps I can add the Set-ADAccountPassword CMDlet to get this working, but I don't know the solution yet.
0
 
LVL 12

Expert Comment

by:FDiskWizard
ID: 35198327
Maybe you have something going on with powershell?

Try this to test the Foreach-object:

$csv = Import-Csv -Delimiter ";" -Path "C:\import.csv"
$csv | Foreach-object {$_}

That should echo the contents.
0
 
LVL 12

Expert Comment

by:FDiskWizard
ID: 35198396
Also, I did find a nice article on user imports using NEW-ADUSER:
http://technet.microsoft.com/en-us/magazine/ff394367.aspx
It gives some good info, in the case of having column names something other than the expected.

And I really do recommend Quest's cmdlets..
http://www.quest.com/powershell/activeroles-server.aspx
0
 

Author Comment

by:eSourceONE
ID: 35198642
Ok, I get the correct data back, even from the foreach-object ($csv | Foreach-object {$_})

But the problem is:
With the ForEach-Object it seems PowerShell don't know where to put the pipelined data.

With this...
$csv | ForEach-Object {new-aduser}
...I get a prompt to type in a Name --> the normal wizard, that doesn't help.
0
 
LVL 13

Expert Comment

by:soostibi
ID: 35199127
Try this:


$csv = Import-Csv -Delimiter ";" -Path "C:\import.csv"  
$csv | % -Begin  {$h=@{}} -Process {
    $o=$_
    $o | gm -MemberType noteproperty | %{
        if($_.name -eq "accountpassword"){$h.($_.name) = ConvertTo-SecureString $o.($_.name) -AsPlainText -Force} 
        else{$h.($_.name) = $o.($_.name)}
    }
    $h.enabled = $true
    $h.ChangePasswordAtLogon = $true
    New-ADUser @h
}

Open in new window

0
 
LVL 13

Expert Comment

by:soostibi
ID: 35199134
Sorry, this one:
$csv = Import-Csv -Delimiter ";" -Path "C:\import.csv"    
$csv | % {
    $h=@{}
    $o=$_
    $o | gm -MemberType noteproperty | %{
        if($_.name -eq "accountpassword"){$h.($_.name) = ConvertTo-SecureString $o.($_.name) -AsPlainText -Force} 
        else{$h.($_.name) = $o.($_.name)}
    }
    $h.enabled = $true
    $h.ChangePasswordAtLogon = $true
    New-ADUser @h -WhatIf
}

Open in new window

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 13

Expert Comment

by:soostibi
ID: 35199159
Both are OK, except in the second one there is an unnecessary -whatif in line 11.
0
 

Assisted Solution

by:eSourceONE
eSourceONE earned 0 total points
ID: 35205709
It's possible, that your script is working. But I thought it must be easier with PowerShell than with Batchl!

And after 2 other hours I got this solution, which is really nice and simple (in my opinion) - here the complete script:
Import-Module ActiveDirectory

$source = "C:\import.csv"

$csv = Import-Csv -UseCulture -Path $source
$csv | New-ADUser

$csv | ForEach-Object {
$Identity = $_.SamAccountName
$Password = $_.AccountPassword

Set-ADAccountPassword $Identity -Reset -NewPassword (ConvertTo-SecureString $Password -AsPlainText -Force)
Set-ADUser $Identity -Enabled $true -ChangePasswordAtLogon $true
}

Open in new window


First I import the CSV in the variable $csv and add the users from it.
In the next step I set the password using a ForEach-Object and enable the accounts.


It would be very nice, if I can get a log with results and errors.
Has anyone an idea?
0
 
LVL 13

Expert Comment

by:soostibi
ID: 35205956
None of the examples are Batch, all are PowerShell.
0
 
LVL 13

Expert Comment

by:soostibi
ID: 35205979
Your script is simple, understandable, but not efficient.

You can create the new user ENABLED and WITH the password at once (see my solution), this way you save network bandwith and/or extra domain controller processing. You actually access the domain database 3 times: 1-create diasabled user, 2-set the password, 3-enable user. It is a waste of resources.
0
 

Author Comment

by:eSourceONE
ID: 35206339
I know it's not Batch, but it looks complicated like in a Batch-File (to me).

Your point with efficiency is interesting, perhaps I can reduce it to 2 commands using -PassThru or something else.
But the resources are used just one time - it's no constant usage, so in my case it's no problem.
0
 

Author Comment

by:eSourceONE
ID: 35206447
Is it possible to log this commands to see if they were successful?
0
 
LVL 13

Accepted Solution

by:
soostibi earned 350 total points
ID: 35206450
I explain my code to you.

Read all CSV recors and foreach do the following: $csv | % {  
Initialite a hashtable:    $h=@{}  
Put the actual object into $o:     $o=$_  
Examine the properties of $o, these are the columns in the CSV, and for each property:    $o | gm -MemberType noteproperty | %{
check if it is the problematic password, if so, put as the 'accountpassword' property of $h the converted password:         if($_.name -eq "accountpassword"){$h.($_.name) = ConvertTo-SecureString $o.($_.name) -AsPlainText -Force}  
else put simply the value from the CSV into $h.property:        else{$h.($_.name) = $o.($_.name)}
    }  
Put an additional property 'enabled' with $true into $h:    $h.enabled = $true
and an additional 'changepassword' property into $h:    $h.ChangePasswordAtLogon = $true
We are now filled in every property into $h with the correct values, now I give all properties as parameters to the New-ADUser at once, with these values:   New-ADUser @h  
}

We are ready!!!! Finally we had to use new-aduser once for each user, no additional set-aduser was needed. My code will also work without modification, if you add some more columns to the CSV (with the proper column names)!
0
 
LVL 13

Assisted Solution

by:soostibi
soostibi earned 350 total points
ID: 35206473
As far as the logging is concerned, you'll see any errors on screen, and you can redirect the error stream to file if you put a

2> c:\errors.txt

structure at the very end of the expression, just after the last '}'
0
 

Author Closing Comment

by:eSourceONE
ID: 35239040
Not exactly what I was hoping for but a bood solution & nice explanation!
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Utilizing an array to gracefully append to a list of EmailAddresses
In this previous article (https://oddytee.wordpress.com/2016/05/05/provision-new-office-365-user-and-mailbox-from-exchange-hybrid-via-powershell/), we made basic license assignments to users in O365. When I say basic, the method is the simplest way …
This tutorial will walk an individual through the steps necessary to join and promote the first Windows Server 2012 domain controller into an Active Directory environment running on Windows Server 2008. Determine the location of the FSMO roles by lo…
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles to another domain controller. Log onto the new domain controller with a user account t…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now