Take two variables and put them on the same line - powershell

I have a script (thanks in largely to this site) that takes names of people from a text file and splits them into FullName, FirstName, LastName and FirstLetter.
I now plan on importing these into AD and largely, I know what I am doing.
However, I am struggling with the following section
New-ADUser -Name
I would like to do something like this
$result.ForEach({
New-ADUser -Name $_.FirstName + $_.LastName -GivenName $_.FirstName -Surname
$_.LastName -AccountPassword
(ConvertTo-SecureString -AsPlainText "APassword!" -Force)
-PasswordNeverExpires $True -UserPrincipalName
"$_.FirstLetter+$_.LastName#vennershipley.co.uk"
-SamAccountName "$_.FirstLetter $_.LastName"
-Path 'OU=Users,OU=London,OU=Sites,DC=MyCompany,DC=local'
})
This returns a error stating 'The name provided is not a properly formed account name'. Now I presume this is because, if I do this
$result.FirstName + $result.LastName
It returns the 3 first names and the 3 last names on seperate lines, so I would presume it is trying to name each person with a name on two seperate lines like
FirstName
LastName
So how would I make the result display on one line, presuming this is the issue?
Also, if there are better ways of doing the AD Creation then please advise, I am still learning!

Enclose the two variables in parentheses to get the results of the addition just like you did in the ConvertTo-SecureString part:
$result.ForEach({
New-ADUser -Name ($_.FirstName + "" + $_.LastName) -GivenName $_.FirstName -Surname
$_.LastName -AccountPassword
(ConvertTo-SecureString -AsPlainText "APassword!" -Force)
-PasswordNeverExpires $True -UserPrincipalName
"$_.FirstLetter+$_.LastName#vennershipley.co.uk"
-SamAccountName "$_.FirstLetter $_.LastName"
-Path 'OU=Users,OU=London,OU=Sites,DC=MyCompany,DC=local'
})
Now, as you asked for better ways, see few possibilities including Splatting parameters and string.format (-f) Also notice the differents between the string formatting in the Name and SamAccountName Parameters:
foreach ($user in $result)
{
$Params = #{
Name = "$($user.FirstName) $($user.LastName)"
GivenName = $user.FirstName
Surname = $user.LastName
AccountPassword = (ConvertTo-SecureString -AsPlainText "APassword!" -Force)
PasswordNeverExpires = $true
UserPrincipalName = "{0}{1}#vennershipley.co.uk" -f $user.FirstName.Chars(0),$_.Lastname
SamAccountName = "{0}{1}" -f $user.FirstName.Chars(0),$_.Lastname
Path = 'OU=Users,OU=London,OU=Sites,DC=MyCompany,DC=local'
}
New-ADUser #Params
}
One more thing: to check everything is good just before executing this in production, i suggest you to add the -WhatIf parameter to the New-ADUser cmdlet, it will demonstrate the operation but will not run it

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)"
}
}

Powershell New-ADUser Password Complexity Exception

I'm trying to mass import AD users from a CSV file. But I keep getting the following error:
The password does not meet the length, complexity, or history requirement of the domain
But the password that's created with $InitialPassword has uppercase, lowercase, numbers and special characters so I don't get what it's not meeting.
ForEach($user in $CSV){
$FirstName = $user.Voornaam
$LastName = $user.Familienaam
$DayOfBirth = $user.geboortedatum
$Enrollment = $user.inschrijvingsjaar
$Classroom = $user.Klas
$PhoneNumber = $user.contactnummer
# create and sanatize username
$UserName = "$($FirstName.ToLower()).$($LastName.ToLower())"
$Username = $UserName.Replace(" ", "")
# generate password
$InitialPassword = (ConvertTo-SecureString "$($FirstName[0])$($LastName.ToLower())$($Enrollment)!" -AsPlainText -Force)
New-ADUser -Name "$FirstName $LastName" `
-GivenName "$FirstName" `
-Surname "$LastName" `
-UserPrincipalName ("{0}#{1}" -f $UserName, "arrow.local") `
-SamAccountName $UserName `
-Initials "$($FirstName[0])$($LastName[0])" `
-DisplayName "$FirstName $LastName" `
-HomePhone $PhoneNumber `
-Description $Classroom `
-Office $Enrollment `
-AccountPassword $InitialPassword `
-Enabled $true
Write-Host "$UserName"
Write-Host "$InitialPassword"
}
The default password complexity rules disallow the account's name or username in the password - so when you compose the password of strings that also go into the Display Name, you're in violation of the complexity requirement!
If you're also seeing errors due to invalid user names, be aware that sAMAccountName attributes must be:
Unique at the forest-level
No more than 20 characters long

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

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.

New-Aduser : The object name has bad syntax

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 $_}}