Bulk import AD users from csv using powershell without user intervention - powershell

I'm trying to import users from a csv file using ADUser powershell cmdlet and here's the script
Import-Module ActiveDirectory
$csvcontent = Import-CSV -Path "C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell\import_create_ad_users_2a.csv"
foreach ($user in $csvcontent) {
$samAccountName = $user.GivenName.substring(0,1).ToLower()+$user.LastName.ToLower()
$userPrincinpal = $samAccountName+"#mmc.local"
New-ADUser
-AccountPassword (ConvertTo-SecureString -AsPlainText $user.Password -force)`
-ChangePasswordAtLogon $false`
-Company “mmc LLP.”`
-DisplayName ($user.GivenName+""+$user.Lastname)`
-userprincipalname $userPrincinpal`
-SamAccountName $samAccountName` -Name ($user.GivenName+""+$user.Lastname)`
-Path “CN=Users,DC=mmc,DC=local”`
-state $user.County`
-givenname $user.GivenName`
-surname $user.Lastname`
-description ($user.Description)`
-Enabled $true`
Add-ADGroupMember "mmc_Users" $samAccountName;
}
But when I run the command in powershell, I get a prompt as listed below and I would like to import all the users listed in the csv file without any user intervention.
cmdlet New-ADUser at command pipeline position 1
Supply values for the following parameters:
Name:
Please review the script and let me know how to fix this.
FYI - Powershell beginner
Thanks,
Karthik

Backticks are generally worth avoiding. They work by escaping the next character, which on the end of a line is the newline character so it allows the command to continue. However its too easy to end up with a space after the backtick that you can't see, which then ends up getting escaped and not the newline. That doesn't seem to be the case above, but as TessellatingHeckler pointed out you were missing one after New-ADUser.
A better solution (to keep the code from going too far horizontal) would be to use splatting like this:
Import-Module ActiveDirectory
$csvcontent = Import-CSV -Path "C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell\import_create_ad_users_2a.csv"
foreach ($user in $csvcontent) {
$samAccountName = $user.GivenName.substring(0,1).ToLower()+$user.LastName.ToLower()
$userPrincinpal = $samAccountName+"#mmc.local"
$NewUserParams = #{
AccountPassword = (ConvertTo-SecureString -AsPlainText $user.Password -Force)
ChangePasswordAtLogon = $false
Company = “mmc LLP.”
DisplayName = ($user.GivenName+""+$user.Lastname)
userprincipalname = $userPrincinpal
SamAccountName = $samAccountName
Name = ($user.GivenName+""+$user.Lastname)
Path = “CN=Users,DC=mmc,DC=local”
state = $user.County
givenname = $user.GivenName
surname = $user.Lastname
description = ($user.Description)
Enabled = $true
}
New-ADUser #NewUserParams
Add-ADGroupMember "mmc_Users" $samAccountName
}
This works by creating a hashtable #{ } with each of the parameters in it that you want to set and then sending that hashtable to the cmdlet with the special # character.

Few things that I think look wrong, but lets try to fix it. Changing the name is best done after the user has been created. This will limit the script from failing.
Backticks can be used for someone who is just learning how to code and it allows you to see the code in a more logical way. You could also create an array as suggested, but that can get complicated and not give correct results.
Lets break down the script below. First we call ActiveDirectory Module, then we call the CSV. That part works great.
We can test it by using the following code that was provided:
Import-Module ActiveDirectory
$csvcontent = Import-CSV -Path "C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell\import_create_ad_users_2a.csv"
$csvcontent | Out-GridView
This should display something with your raw data, but an example is:
GivenName | LastName | Password | Description | Country
Karthik | CSVScript | 79HKJ#p8 | UserTest | Norway
Once we can confirm that the columns are correct. We can run the script
When you use the Import-CSV it imports the columns that you defined as a pipline($_.GivenName). This allows us not to create another variable. Calling it from the Import-CSV cmdlet will only use the fields that you provide in the raw data(CSV file).
You can save the following as a PS_Script called something like NewUser_CSV.ps1
The script below will only look at what you put into the columns. If something is not correct, that means the data in the CSV is wrong. This is a basic add AD users using a CSV file with no major error handling.
We will use the Transcript cmdlet to gather a log
#RUN AS ADMIN!
Start-Transcript -Path "C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell\import_create_ad_users_2a.log"
Import-Module ActiveDirectory
$csvcontent = Import-CSV -Path "C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell\import_create_ad_users_2a.csv"
$csvcontent | ForEach-Object {
$sam = $_.GivenName.substring(0,1)+$_.Lastname
$setpass = ConvertTo-SecureString -AsPlainText $_.Password -force
Try
{
New-ADUser $samAccountName `
-Path "CN=_s,DC=mmc,DC=local" `
-GivenName $_.GivenName `
-Surname $_.LastName `
-UserPrincipalName ($samAccountName + "#mmc.local")`
-DisplayName ($_.GivenName + " " + $_.LastName) `
-Description $_.Description `
-Enabled $TRUE `
-Company "mmc LLP." `
-State $_.Country `
-AccountPassword $setpass `
-ChangePasswordAtLogon $False `
-AccountPassword $setpass
$newdn = (Get-ADUser $samAccountName).DistinguishedName
Rename-ADObject -Identity $newdn -NewName ($_.GivenName + " " + $_.LastName)
}
Catch
{
Write-Host "[ERROR]`t Oops, something went wrong: $($_.Exception.Message)`r`n"
}
}
Stop-Transcript
I really hope this helps you out and gets the task done for you. Good luck with learning PowerShell.

Related

Powershell issue with a defined variable

I am pretty new to powershell and have a code that I found. I had it working but now it is no longer working. I didn't change anything with the variable so I am not sure what is going on. Here is a link to a Screenshot of the code and error. Please let me know if you need any other information
https://imgur.com/a/ntEhdoV
Thank you!
Import-Module activedirectory
$ADUsers = Import-csv 'C:\Users\Desktop\Powershell files\EM-mis-new-AD.csv'
foreach ($User in $ADUsers)
{
$Username = $User.username
$Password = $User.password
$Firstname = $User.firstname
$Lastname = $User.lastname
$OU = $User.ou
$Password = $User.Password
if (Get-ADUser -F {SamAccountName -eq $Username})
{
Write-Warning "A user account with username $Username already exist in Active Directory."
}
else
{
New-ADUser `
-SamAccountName $Username `
-UserPrincipalName "$Username#Mydomain" `
-Name "$Firstname $Lastname" `
-GivenName $Firstname `
-Surname $Lastname `
-Enabled $True `
-DisplayName "$Firstname, $Lastname" `
-Path $OU `
-AccountPassword (convertto-securestring $Password -AsPlainText -Force) -ChangePasswordAtLogon $True
}
}
Error:
Get-ADUser : Variable: 'Username' found in expression: $Username is not defined.
At C:\Users\jcarnovale\Desktop\Testing if.ps1:22 char:6
if (Get-ADUser -F {SamAccountName -eq $Username})
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidArgument: (:) [Get-ADUser], ArgumentException
FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Commands.GetADUse
You probably want to check that you have a good username before proceeding in the script, like:
$Username = $User.username
...
if(!$Username) {
throw "Username was empty!"
}
Also, try changing the Get-ADUser filter to use a string:
if (Get-ADUser -F "SamAccountName -eq $Username")
{
}
You didn't show us anything of the imported CSV file itself and I think the main problem is in there.
Import-Csv by default expects the comma (,) to be used as delimiter character. If that is not the case in your file, you need to add parameter -Delimiter followed by the character that is used as separator in your file (like -Delimiter ';' if your file uses the semicolon).
Please check that first, so the Import-Csv cmdlet can parse the file correctly.
Next, it could be that there are empty values in the username column and if so, the code should skip these rows.
Also, as commented, the -Filter parameter needs a double-quoted string "Property -eq 'something'" in which a variable like $username is expanded, instead of a scriptblock {..}
Finally, I'd recommend using Splatting on cmdlets that take many properties instead of using backticks.
Try
Import-Module ActiveDirectory
# this defaults to csv fields delimited by a comma. If your CSV file uses a different
# character, then add parameter '-Delimiter' followed by the actual character
$ADUsers = Import-Csv -Path 'C:\Users\Desktop\Powershell files\EM-mis-new-AD.csv'
# the Where-Object clause is just a precaution to omit records that have no username value
$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 {
$Firstname = $_.firstname
$Lastname = $_.lastname
# use splatting on cmdlets that use a lot of parameters
$userParams = #{
SamAccountName = $Username
UserPrincipalName = "$Username#Mydomain.com"
Name = "$Firstname $Lastname"
GivenName = $Firstname
Surname = $Lastname
Enabled = $true
DisplayName = "$Firstname, $Lastname"
Path = $_.ou
AccountPassword = (ConvertTo-SecureString $_.Password -AsPlainText -Force)
ChangePasswordAtLogon = $true
}
# create the user and report back
New-ADUser #userParams
Write-Host "Created new user '$Username' with initial password: $($_.Password)"
}
}

can't create userS via powershell

I can't import users in powershell with a script via an csv file, but If I print the parameters on the screen,it shows them as it should.
what I am doing wrong? in my life plenty with that mustache, but plis focus on the script.
is running windows server 2016 on the powershell ise, on virtualbox
The Script:
If(-Not(Get-ADOrganizationalUnit -Filter {Name -eq "991-5D"}))
{New-ADOrganizationalUnit "991-5D" -Path (Get-ADDomain).DistinguishedName}
If(-Not(Get-ADOrganizationalUnit -Filter {Name -eq "911-5V"}))
{New-ADOrganizationalUnit "911-5V" -Path (Get-ADDomain).DistinguishedName}
$domain=(Get-ADDomain).DNSRoot
Import-Csv -Path "C:\Alumnos.csv" | foreach-object {
[int]$number= $_.X
If($number -ge 10 -and $number -le 26)
{
$UO="991-5D"
}
//there are many others O.U.
$ou= "UO="+$UO+","+$domain
$UPN = $_.LETRA+$_.PATERNO+$_.X+"#"+ "$domain"
$CUENTA= $_.LETRA+$_.PATERNO+$_.X
New-ADUser -SamAccountName $CUENTA -UserPrincipalName $CUENTA -Name $_.NOMBRE
-SurName $_.PATERNO -GivenName $_.NOMBRE -EmailAddress $UPN -AccountPassword
(ConvertTo-SecureString "Leica666" -AsPlainText -force) -Path $ou
-Enabled $true -ChangePasswordAtLogon $true -Verbose}
the data:
X,PATERNO,MATERNO,NOMBRE,SEGUNDO,LETRA
10,ARÉVALO,CORNEJO,NICOLÁS,ALEJANDRO,N
11,BARRIOS,MONTERO,BENJAMÍN,IGNACIO,B
12,BUSTAMANTE,LOYOLA,IGNACIO,HERNANDO,I
13,BUSTOS,GARRIDO,ARTURO,IGNACIO,A
this are the results on each line:
+ New-ADUser -SamAccountName $CUENTA -UserPrincipalName $CUENTA -Name $ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo:NotSpecified: (CN=IGNACIO,UO=9...da.com:String)
[New-ADUser], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8335,
Microsoft.ActiveDirectory.Management.Commands.NewADUser
the head:
X,PATERNO,MATERNO,NOMBRE,SEGUNDO,LETRA
echo:
#{X=42; PATERNO=PAYACÁN; MATERNO=ZAPATA; NOMBRE=NICOLÁS; SEGUNDO=N; LETRA=}.NOMBRE
I know that reads the file and instead of reading just the column reads all the line($_), and then prints whatever I wrote next to it(".name", ".section", etc).
I've made some variable and format changes to make this code more successful.
$domain=Get-ADDomain
Import-Csv -Path "C:\Alumnos.csv" |
Foreach-Object {
[int]$number= $_.X
If($number -ge 10 -and $number -le 26)
{
$UO="991-5D"
}
$ou = "OU={0},{1}" -f $UO,$domain.DistinguishedName
$UPN = "{0}{1}{2}#{3}" -f $_.LETRA,$_.PATERNO,$_.X,$domain.DNSRoot
$CUENTA= "{0}{1}{2}" -f $_.LETRA,$_.PATERNO,$_.X
New-ADUser -SamAccountName $CUENTA -UserPrincipalName $UPN -Name $_.NOMBRE `
-SurName $_.PATERNO -GivenName $_.NOMBRE -EmailAddress $UPN `
-AccountPassword (ConvertTo-SecureString "Leica666" -AsPlainText -force) -Path $ou `
-Enabled $true -ChangePasswordAtLogon $true -Verbose
}
Explanation:
$domain: I've made this an ADDomain object. This allows the DistinguishedName and DNSRoot properties to be accessed where appropriate.
-f operator: I used the format operator to make it easier to read the string concatenation attempts.
$ou: This is constructed using the DistinguishedName of the domain. This is the proper format for the OU path.
$UPN: This is constructed using the DNSRoot of the domain. It can obviously be different than your domain, but must be in an email address or FQDN format.
Additional Comments:
You are setting -Name to be $_.NOMBRE. This could be problematic because Name must be unique in each OU. Name is used to build the CN, which is where uniqueness is required. If you have NICOLAS in OU 991-5D, you are going to get an error if you try to create another NICOLAS in the same place. IMHO, I would do something different. You could also implement the use of splatting for building the properties of your New-ADUser command, but that is only for readability purposes. Below is an example of splatting:
$NewUserProperties = #{
SamAccountName = $CUENTA
UserPrincipalName = $UPN
Name = $_.NOMBRE
Surname = $_.PATERNO
GivenName = $_.NOMBRE
EmailAddress = $UPN
AccountPassword = (ConvertTo-SecureString "Leica666" -AsPlainText -force)
Path = $ou
Enabled = $true
ChangePasswordAtLogon = $true
}
New-ADUser #NewUserProperties -Verbose

Powershell Foreach usage and syntax

I'm attempting to script the creation of accounts in active directory using a csv file. Unfortunately I'm new to PowerShell and scripting in general and am facing difficulty managing a foreach() loop which is intended to handle each of the columns in the csv document I import.
I suspect that I cannot define my variables in one block after foreach() like I have, but am unsure and would appreciate some guidance. Specifically, the purpose of the code is read a csv document and assign each item to a variable that it then uses to create a service account with those values.
The Ideal situation is one where I can create a csv with several hundred rows, execute the script and end with several hundred matching service accounts.
$SVC = (import-csv C:\users\me\desktop\Test.csv -header("Name", "Pass", "WhatDo", "Location", "Domain")) `
foreach($variable in %SVC) {
$name = $SVC.Name
$Pass = $SVC.Pass
$WhatDo = $SVC.WhatDo
$Location = $SVC.Location
$Domain = $SVC.Domain
New-ADuser `
-Name $name `
-AccountPassword (Convertto-SecureString $Pass -AsPlainText -Force) `
-CannotChangePassword $true `
-Description $WhatDo `
-DisplayName $name `
-Enabled $true `
-GivenName $name `
-PasswordNeverExpires $True `
-Office $Location `
-Path "OU=Service-Accounts, Ou=Accunts, OU=_CORP, DC=$Domain, DC=net" `
-SamAccountName $name `
-UserPrincipleName $name + "#" + $domain + ".net" `
Start-Sleep -Seconds 15
Get-ADUser `
-Identity $name | Add-ADPrincipalGroupMembership `
-MemberOf "Group1","Group2","Group3"
}
There are quite a few things wrong in your code, not just the foreach.
But let's start with that: foreach ($variable in $SVC) means that $variable will have the the current item inside your loop, yet you are accessing $SVC in your loop which is still referring to the original collection. $variable is not a good name either, so you should change that to something more meaningful. Also, you wrote %SVC instead of $SVC.
You are also using backtick (`) a lot, sometimes incorrectly. You should only use it when your cmdlet invokation spans multiple lines. In the case of Import-Csv it's not, yet there's backtick at the end. There's also one on the last line of New-ADUser. Some prefer to use Parameter Splatting instead of backticks, but's thats a matter of taste.
Considering you are creating service accounts, I would write the first part like this:
$serviceAccounts = Import-Csv C:\users\me\desktop\Test.csv -Header Name,Pass,WhatDo,Location,Domain
foreach($serviceAccount in $serviceAccounts) {
Then inside your loop you can access the indivdual properties through $serviceAccount:
$name = $serviceAccount.Name
Also, PowerShell expands variables when using double quotes, so -UserPrincipleName can be written like this: -UserPrincipleName "$name#$domain.net"
I prefer using ForEach-Object rather than foreach.
It would be something like:
$SVC = (Import-CSV C:\users\me\desktop\Test.csv -header("Name", "Pass", "WhatDo", "Location", "Domain"))
$SVC | ForEach-Object {
New-ADuser `
-Name $_.Name `
-AccountPassword (Convertto-SecureString $_.Pass -AsPlainText -Force) `
-CannotChangePassword $true `
-Description $_.WhatDo `
-DisplayName $_.Name `
-Enabled $true `
-GivenName $_.Name `
-PasswordNeverExpires $True `
-Office $_.Location `
-Path "OU=Service-Accounts, Ou=Accunts, OU=_CORP, DC=$Domain, DC=net" `
-SamAccountName $_.Name `
-UserPrincipleName $_.Name + "#" + $_.Domain + ".net"
Start-Sleep -Seconds 15
Get-ADUser `
-Identity $_.Name | Add-ADPrincipalGroupMembership `
-MemberOf "Group1","Group2","Group3"
}
$_ represents the current item in the pipeline. ($SVC in your case, which was the wrong variable anyways.) It's less code and I think it's a cleaner way of doing things!
Rename $SVC to $SVCs then foreach ($SVC in $SVCs)
Here is an example how you can do it.(Don't forget the delimiter)
$csv = Import-Csv -Path C:\temp\csv.csv -Header "a","b","c" -Delimiter ";"
foreach($row in $csv){
$row.a
$row.b
$row.c
}
Here are some more examples how foreach works:
Take a look https://ss64.com/ps/foreach.html
Examples
Loop through an array of strings:
$trees = #("Alder","Ash","Birch","Cedar","Chestnut","Elm")
foreach ($tree in $trees) {
"$tree = " + $tree.length
}
Loop through a collection of the numbers, echo each number unless the number is 2:
foreach ($num in 1,2,3,4,5) {
if ($num -eq 2) { continue } ; $num
}
Loop through a collection of .txt files:
foreach ($file in get-ChildItem *.txt) {
Echo $file.name
}

Creating a Script to import users from a CSV to AD

I'm trying to build a script that will take a CSV with the fields
firstname, lastname, password
and create a user in AD in a specific OU with that info. I've done a bunch of googling, and this is what I've come up with (from this blog):
Import-Csv .\userImport.csv | ForEach-Object {
New-ADUser
-Name $_.DisplayName
-UserPrincipalName $_.UserPrincipalName
-SamAccountName $_.Username
-FirstName $_.FirstName
-DisplayName $_.DisplayName
-LastName $_.Lastname
-Path $_.Path
-AccountPassword (ConvertTo-SecureString $_.Password -AsPlainText -force)
-Enabled $True
-PasswordNeverExpires $True
-PassThru
}
I have a few questions:
I want to specify the OU in my command, instead of having it be in the CSV. Can I just change it to:
-Path OU=MyOU,DC=Domain,DC=Local
What is the -PassThru line for?
Is the -AccountPassword line correct? I got that from a blog that suggested this is the right way to take a password and set it as my AD user's password.
Do I need the PrincipalName, SamAccountName and DisplayName all as separate fields? This can be as minimal as possible, at least for now.
Any tips or changes you would make? This is my first time doing a script like this so I'm willing to learn.
Yes, you can specify parameters whichever way you like, they don't need to come from the input file.
-PassThru makes New-ADUser echo the created user object. By default the cmdlet doesn't return anything.
Yes, the -AccountPassword argument is correct, provided the password field from the CSV contains the plaintext password.
You don't necessarily have to have a separate CSV field for each parameter argument if you can construct an argument from existing field values. For instance, you most likely can create values like DisplayName or SamAccountName from first and last name, e.g. like this:
-SamAccountName ($_.firstname.Substring(0,1) + $_.lastname).ToLower()
-DisplayName ('{0} {1}' -f $_.firstname, $_.lastname)
You also don't need to specify every argument. For instance, the UPN (User Principal Name) will automatically be generated when omitted, and the display name will default to the name.
You can't wrap the lines like you have. PowerShell can't read your mind and won't know that you intend to continue the statement in the next line unless you tell it that or the statement is obviously incomplete. Use backticks to escape the linebreaks. Also, the parameters for first and last name are -GivenName and -Surname, not -FirstName and -LastName.
$csv = '.\userImport.csv'
$ou = 'OU=MyOU,DC=Domain,DC=Local'
Import-Csv $csv | ForEach-Object {
$name = '{0} {1}' -f $_.firstname, $_.lastname
$acct = ($_.firstname.Substring(0,1) + $_.lastname).ToLower()
$pw = ConvertTo-SecureString $_.password -AsPlainText -Force
New-ADUser -Name $name `
-SamAccountName $acct `
-GivenName $_.firstname `
-Surname $_.lastname `
-Path $ou `
-AccountPassword $pw `
-Enabled $true `
-PasswordNeverExpires $true `
-PassThru
}
OU - If you want them all in the same OU, you can hard code it (remember the quotes)
-Path "OU=MyOU,DC=Domain,DC=Local"
-PassThru
The -PassThru parameter lets you request output from cmdlets that return no output by default. (The PassThru Parameter: Gimme Output)
i.e. Instead of New-ADUser just executing and then returning you to the next line, it will actually print out the new user created info to the prompt.
Yes the -AccountPassword takes a SecureString as the argument. The command ConvertTo-SecureString converts a plain text string to a SecureString, which then can be passed to the -AccountPassword parameter
You don't need -UserPrincipalName. You do need -SamAccountName. -DisplayName can be changed to:
-DisplayName "$($_.FirstName) $($_.Lastname)"
This is a pretty standard script for mass producing accounts, so it is pretty good the way it is. The only change I would look at is -PasswordNeverExpires $True You typically only really set the Password Never Expires on Service accounts, so if you are creating plain old user accounts, you wouldn't need it.

Error when running powershell script to import users from csv using Import-Csv and New-QADUser into Active Directory

My script looks like this:
$Users = Import-Csv "C:\users.csv"
foreach ($User in $Users)
{
New-QADUser -Name $User.Name `
-ParentContainer $User.OU `
-FirstName $User.FirstName `
-LastName $User.LastName `
-UserPassword $User.userPassword `
-SamAccountName $User.sAMAccountName `
}
When I run it I get the following error:
DefaultNamingContext Type
-------------------- ----
DC=example,DC=domain,DC=org ActiveDirectory
The server is unwilling to process the request. (Exception from HRESULT: 0x80072035)
At :line:5 char:12
+ New-QADUser <<<< -Name $User.Name `
My CSV looks like this:
Name,FirstName,LastName,sAMAccountName,UserPassword,OU
Joe Bob,Joe,Bob,jb241277,4gh60b4,"OU=2010,OU=Sub,OU=Users,OU=MAIN,DC=example,DC=domain,DC=org"
Not sure what is going on, any help would be appreciated. This is a child domain in a forest on Win2K8 Ent.
It is possible that this action is being attempted against a Global Catalog for some reason. Your code works fine for me, but I get the error when I attempt to do it against a GC, which is expected. The connect-QADService cmdlet specifies where you want to connect. If you're setting this before your new-qaduser code, double-check to make sure that "-UseGlobalCatalog" is not in there.
As a troubleshooting step you can try to specify a specific Domain Controller to see if that changes your error.
$Users = Import-Csv "C:\users.csv"
foreach ($User in $Users)
{
New-QADUser -Name $User.Name `
-ParentContainer $User.OU `
-FirstName $User.FirstName `
-LastName $User.LastName `
-UserPassword $User.userPassword `
-SamAccountName $User.sAMAccountName `
-Service $DomainController `
}
That will tell it to perform the action against a specific domain controller and not a Global Catalog.