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
Related
I am currently trying to automate the creation of new users on my Active Directory.
However when I run my powershell here is the error that presents itself to me :
New-ADUser: Unable to validate argument on "Path" parameter. The argument is null or empty. Provide an argument that is not null or empty and try again.
At character Line: 23:19
+ -Path $ OR `
+ ~~~
+ CategoryInfo: InvalidData: (:) [New-ADUser], ParameterBindingValidationException
+ FullyQualifiedErrorId: ParameterArgumentValidationError, Microsoft.ActiveDirectory.Management.Commands.NewADUser
What can i do ?
Thanks for your help !
This is my code
$ADUsers = Import-csv E:\SCRIPT\newusers.csv
foreach ($User in $ADUsers)
{
$Username = $User.username
$Password = $User.password
$Firstname = $User.firstname
$Lastname = $User.lastname
$Description = $User.description
$OU = $User.ou
New-ADUser `
-SamAccountName $Username `
-UserPrincipalName "$Lastname#domaine.fr" `
-Name "$Firstname $Lastname" `
-GivenName $Firstname `
-Surname $Lastname `
-Enabled $True `
-ChangePasswordAtLogon $False `
-DisplayName "$Lastname, $Firstname" `
-Description $Description `
-AccountPassword $Password `
-Path $OU `
}
Your comment indicates the CSV file uses the ; semi-colon as delimiter character, but you neglect to add that to the Import-Csv cmdlet. Now it is trying to parse the data using the default comma , and because of that none of the fields have a correct value.
Replace the first line with
$ADUsers = Import-csv -Path 'E:\SCRIPT\newusers.csv' -Delimiter ';'
Other than that, have a look at using splatting, so you don't need those awkward backticks.
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)"
}
}
This script currently creates new users after importing data from a CSV file
Import-Module ActiveDirectory
Import-Csv "C:\testcsv.csv" | ForEach-Object {
$userPrincinpal = $_."samAccountName" + "#NWTC.local"
New-ADUser -Name $_.Name `
-Path $_."ParentOU" `
-SamAccountName $_."samAccountName" `
-UserPrincipalName $userPrincinpal `
-AccountPassword (ConvertTo-SecureString "Password1" -AsPlainText -Force) `
-ChangePasswordAtLogon $false `
-Enabled $true
}
This is the csv file I am importing from:
Name,samAccountName,ParentOU,Group
Test Test1,TTest1,"OU=Business,DC=NWTC,DC=local",TestGroup
After a user is created, I want to add them to an already exisiting group. There will be different groups I want different users to be added to, but only 1 group per person.
I've been playing around with Add-AdGroupMember, but I'm not sure how to proceed. Something like this: Add-ADGroupMember -Members $_.Members. This is the first time I'm working with CSVs, so I'm in new territory
New-ADuser does not support this functionality so you will have to do that yourself after the fact. What you could do is have New-ADUser spit out the AD user object it creates and use that with Add-ADGroupMember.
$newUserProperties = #{
Name = $_.Name
Path = $_."ParentOU"
SamAccountName = $_."samAccountName"
UserPrincipalName = $_."samAccountName" + "#NWTC.local"
AccountPassword = (ConvertTo-SecureString "Password1" -AsPlainText -Force)
ChangePasswordAtLogon = $false
Enabled = $true
}
try{
$newADUser = New-ADUser #newUserProperties -PassThru
Add-ADGroupMember -Identity $_.Group -Members $newADUser.SamAccountName
} catch {
Write-Warning "Could not create $($newUserProperties.samaccountname)"
}
The error handling is crude but should exist in some form to account for failures in the source data or misconceptions of existing users. Basically just getting $newADUser and using it for Add-ADGroupMember
We use splatting of the parameters here. That way you don't have to worry about having nice formatted code by using backticks.
Add the Add-ADGroupMember in the ForEach-Object after the new user is created :
Import-Module ActiveDirectory
Import-Csv "C:\testcsv.csv" | ForEach-Object {
$userPrincinpal = $_."samAccountName" + "#NWTC.local"
New-ADUser -Name $_.Name `
-Path $_."ParentOU" `
-SamAccountName $_."samAccountName" `
-UserPrincipalName $userPrincinpal `
-AccountPassword (ConvertTo-SecureString "Password1" -AsPlainText -Force) `
-ChangePasswordAtLogon $false `
-Enabled $true
Add-ADGroupMember -Identity 'AD_GROUP_WHERE_YOU_ADD_MEMBERS' -Members $_.samAccountName
}
I have a script which i use to create bulk users from a csv file which works fine.
Import-Csv e:\temp\newemps.csv | %{
$ou = $_.ou
$firstname = $_.first
$lastName = $_.last
$accountName = $("{0}{1}" -f $firstname.Substring(0,1),$lastName).ToLower()
$description = $_.desc
$password = "Welcome1"
$name = "$firstName $lastName"
New-AdUser -SamAccountName $accountName -GivenName $firstName -UserPrincipalName "$accountName#ba.net" -Surname $lastName -DisplayName $name -Name $name -AccountPassword (ConvertTo-SecureString -AsPlainText $password -Force) -Enabled $true -Path $ou -Description $description -ChangePasswordAtLogon:$False
If ($_.Group -ne ""){
Add-adgroupmember -identity $_.group -members $accountName
}
If ($_.email -eq "y"){
Enable-Mailbox -Identity $accountName -Alias $accountName
Set-Mailbox $accountName -MaxSendSize 10mb -MaxReceiveSize 10mb
Get-CasMailbox $accountName -OwaEnabled:$false -ActiveSyncEnabled:$false
}
}
I was trying modify this script so that i could create some generic accounts that would not follow our typical convention. The input is a here-string as supposed to a csv as the only unique item is an Airport code. I have shortened the here-string for brevity.
$bases = #"
YAB
YEK
YYH
YHI
"#
$bases.Split("`n") | %{
$ou = "CN=Users,DC=BA,DC=NET"
$firstname = "$_".ToString()
$lastName = "Counter"
$accountName = "$_" + "Counter"
$description = "Base Front Counter"
$password = "Welcome1"
$name = "$firstName $lastName"
New-AdUser -SamAccountName $accountName -GivenName $firstName -UserPrincipalName "$accountName#ba.net" -Surname $lastName -DisplayName $name -Name $name -AccountPassword (ConvertTo-SecureString -AsPlainText $password -Force) -Enabled $true -Path $ou -Description $description -ChangePasswordAtLogon:$False
}
There is something about using a here-string that I am not accounting for. The only account it successfully creates is the one for YHI (The last one of the here-string). For all others it gives New-AdUser : The object name has bad syntax. Internet research shows many errors for csv-imports where the data has whitespace and other issues there but im not sure what the issue is here.
In the end I just made a csv file instead of using the here-string but I would like to know what i was doing wrong.
This worked for me. got rid of the null values and the new line values and just gave me each string value from each line. Seams there may have been some white space or some other characters that interfere if you just do split "`n"
$test = #"
user1
user2
user3
"#
$test.split(“`r`n”) | ForEach-Object {if($_){get-aduser $_}}
I have a fully functional script to import and create AD Users, but I would like to skip from attempting to create Users that are already in AD.
Import-Module ActiveDirectory
$CsvPath = "C:\Shares\Users.csv"
$CsvTest = Test-Path $CsvPath
Import-Csv $CsvPath | ForEach-Object {
Get-AdUser $_.sAMAccountName
}
Import-Csv $CsvPath | ForEach-Object {
New-ADUser -Name $_.Name -UserPrincipalName $_.userPrincipalName -SamAccountName $_.sAMAccountName -DisplayName $_.DisplayName -GivenName $_.GivenName -Surname $_.Surname -AccountPassword (ConvertTo-SecureString $_.Password -AsPlainText -force) -Enabled $true -ChangePasswordAtLogon $true
{
Catch [Microsoft.ActiveDirectory.Management.Commands.NewADUser]
}
$_."sAMAccountName"; "already exists"
}
Something like this without relying on exceptions would be better:
Import-Module ActiveDirectory
$csvPath = "C:\Shares\Users.csv"
if (Test-Path $csvPath)
{
$newUsers = Import-Csv $csvPath
$existingUsers = Get-ADGroupMember "Domain Users"
foreach ($newUser in $newUsers)
{
if (($existingUsers | Where-Object { $_.sAMAccountName -eq $newUser.sAMAccountName }) -eq $null)
{
$user = New-ADUser -Name $newUser.Name -UserPrincipalName $newUser.userPrincipalName -SamAccountName $newUser.sAMAccountName -DisplayName $newUser.DisplayName -GivenName $newUser.GivenName -Surname $newUser.Surname -AccountPassword (ConvertTo-SecureString $newUser.Password -AsPlainText -Force) -Enabled $true -ChangePasswordAtLogon $true
}
}
}
Personally I prefer to use the Quest AD Module for Powershell as it avoids exceptions by returning $null when an object doesn't exist.