Creating new AD users and adding them to multiple groups from CSV - powershell

I have been given the task of creating a school's worth of users (UK Secondary). The PS to create the users from a CSV, what I need to do is add the newly created users to various groups at the same time.
The code I am using is as follows
$DCName = '<DC FQDN>'
Import-Csv -Path "D:\Import.csv" |
ForEach-Object {
$Displayname = $_.'FirstName' + " " + $_.'LastName'
$UPN = $_.'UPN'
$GroupName = $_.'GroupName'
$Prop = #{
Name = $Displayname
DisplayName = $_.'FirstName' + " " + $_.'LastName'
GivenName = $_.'FirstName'
Surname = $_.'LastName'
UserPrincipalName = $UPN
EmailAddress = $UPN
SamAccountName = $_.'SAM'
AccountPassword = (ConvertTo-SecureString $_.'Password' -AsPlainText -Force)
Enabled = $true
Path = $_.'OU'
ChangePasswordAtLogon = $false
Title = $_.'JobTitle'
StreetAddress = $_.'Street'
City = $_.'Town'
State = $_.'County'
PostalCode = $_.'PostCode'
OfficePhone = $_.'Telephone'
Company = $_.'Company'
Department = $_.'Department'
HomeDrive = $_.'HomeDrive'
HomeDirectory = $_.'Home-Directory'
OtherAttributes = #{
'extensionAttribute1'= $_.'ExtendedAttribute1';
'extensionAttribute2'= $_.'ExtendedAttribute2';
'extensionAttribute14'= $_.'ExtendedAttribute14';
'extensionAttribute15'= $_.'ExtendedAttribute15';
'proxyAddresses' = "SMTP:" + $UPN;}
Server = $DCName
}
New-ADUser #prop
Add-ADGroupMember -Identity $GroupName -Members $_.'SAM'
}
The user gets created with all properties correctly set. It fails with the following error
Add-ADGroupMember : Cannot find an object with identity: 'Test.User' under: 'DC=AD,DC=example,DC=uk'.
At C:\Scripts\NewUserFromCSV2.ps1:47 char:10
+ Add-ADGroupMember -Identity $GroupName -Members $_.'SAM'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Test.USer:ADPrincipal) [Add-ADGroupMember], ADIdentityNotFoundException
+ FullyQualifiedErrorId : SetADGroupMember.ValidateMembersParameter,Microsoft.ActiveDirectory.Management.Commands.AddADGroupMember
It looks like the Add-ADGroupMember command can't find the user that has just been created, however, if that is the case I don't understand why.
Also at the moment, my CSV has only one group in the 'GroupName', what would be the best way to add the user to multiple groups? e.g. School-All-Staff, Teaching-Staff, Science-Teachers etc.
Thanks in advance for any help received.

As it's a bulk operation, I would just split the user creation from the group membership.
Create all the users first, then add them to the groups:
$DCName = '<DC FQDN>'
$Users = Import-Csv -Path "D:\Import.csv"
$Users | ForEach-Object {
$Displayname = $_.'FirstName' + " " + $_.'LastName'
$UPN = $_.'UPN'
$Prop = #{
## properties as per original code ##
}
New-ADUser #prop
}
$Users | ForEach-Object {
$GroupName = $_.'GroupName'
Add-ADGroupMember -Identity $GroupName -Members $_.'SAM'
}
The to add the users to multiple groups:
If you've got a semicolon separated list of the groups in GroupName eg
School-All-Staff;Teaching-Staff;Science-Teachers
Split will convert this to an array then you can loop through them:
$_.'GroupName' -split ';' | ForEach-Object {
Add-ADGroupMember $_ –Member $user.'SAM'
}
(edit: updated to semicolon as you have a csv source)

I got it working as a combined script in the end and added in error checking for pre-existing users, existing staff often move to the new school that is being added to the Trust prior to its addition to our AD and get included in the list of users to create.
Also added log file creation to record newly created users and list those whose SAMAccount name already exists so we can check to see if the user does need creating or if they need moving from another School OU.
This is my final code:
#Get deafult variables to tidy up created variables at the end
$ExistingVariables = Get-Variable | Select-Object -ExpandProperty Name
#New User Code Starts Here>
#Variables not set by CSV
#Set DC name to update - prevents errors due to replication delay
$DCName = '<DC FQDN>'
#Create log files
"Users Exist in AD" | Out-File -FilePath "D:\Logs\ExistingUsers-$(get-date -f yyyyMMdd).txt" -Append
"New Users Created" | Out-File -FilePath "D:\Logs\NewUsers-$(get-date -f yyyyMMdd).txt" -Append
#Specify path and file to import
Import-Csv -Path "D:\Import.csv" |
#Iterate through each row in the CSV
ForEach-Object {
#Set per object variables from fields in the CSV
$DisplayName = $_.'FirstName' + " " + $_.'LastName'
$UPN = $_.'UPN'
$GroupName1 = $_.'GroupName1'
$GroupName2 = $_.'GroupName2'
$GroupName3 = $_.'GroupName3'
$GroupName4 = $_.'GroupName4'
$SAM = $_.'SAM'
$Password = $_.'Password'
$SAMTest = Get-ADUser -Filter {(sAMAccountName -eq $SAM)} -Server $DCName
#Splatting Hash Table holds all user attribute properties set in the CSV
$Prop = #{
Name = $DisplayName
DisplayName = $DisplayName
GivenName = $_.'FirstName'
Surname = $_.'LastName'
UserPrincipalName = $UPN
EmailAddress = $UPN
SamAccountName = $_.'SAM'
AccountPassword = (ConvertTo-SecureString $_.'Password' -AsPlainText -Force)
Enabled = $true
Path = $_.'OU'
ChangePasswordAtLogon = $false
Title = $_.'JobTitle'
StreetAddress = $_.'Street'
City = $_.'Town'
State = $_.'County'
PostalCode = $_.'PostCode'
OfficePhone = $_.'Telephone'
Company = $_.'Company'
Department = $_.'Department'
OtherAttributes = #{
'extensionAttribute1'= $_.'ExtendedAttribute1';
'extensionAttribute2'= $_.'ExtendedAttribute2';
'extensionAttribute14'= $_.'ExtendedAttribute14';
'extensionAttribute15'= $_.'ExtendedAttribute15';
'proxyAddresses' = "SMTP:" + $UPN;}
Server = $DCName
}
#Check if SAMAccount name exists in AD and skip existing users
if ($SAMTest -ne $Null)
{
#Get UPN property of the pre-existing user
$Exist = Get-ADUser -Filter {(sAMAccountName -eq $SAM)} -Properties 'userprincipalname'
#write UPN value to variable
$ExistUPN = $Exist.userprincipalname
#Update log of pre-existing users
"$DisplayName exists with email $ExistUPN" | Out-File -FilePath "D:\Logs\ExistingUsers-$(get-date -f yyyyMMdd).txt" -Append
#Write to screen
Write-Host "$DisplayName already exists in AD" -ForegroundColor Red
}
else
{
#Create new user with the attribute properties collected above
New-ADUser #prop
#Check if group fields in CSV were populated, if true add user to group, if false skip
if ($_.'GroupName1'){Add-ADGroupMember -Identity $_.'GroupName1' -Members $_.'SAM' -Server $DCName}
if ($_.'GroupName2'){Add-ADGroupMember -Identity $_.'GroupName2' -Members $_.'SAM' -Server $DCName}
if ($_.'GroupName3'){Add-ADGroupMember -Identity $_.'GroupName3' -Members $_.'SAM' -Server $DCName}
if ($_.'GroupName4'){Add-ADGroupMember -Identity $_.'GroupName4' -Members $_.'SAM' -Server $DCName}
#Update New user log
"$UPN" | Out-File -FilePath "D:\Logs\NewUsers-$(get-date -f yyyyMMdd).txt" -Append
#Write to screen
Write-Host "User $SAM created at $((Get-Date).ToString('hh:mm'))" -ForegroundColor Green
}
}
#End Of New User Code
#Remove variables set by script - keeps PS memory space tidy
$NewVariables = Get-Variable | Select-Object -ExpandProperty Name | Where-Object {$ExistingVariables -notcontains $_ -and $_ -ne "ExistingVariables"}
if ($NewVariables)
{
Write-Host "Removing the following variables:`n`n$NewVariables"
Remove-Variable $NewVariables
}
else
{
Write-Host "No new variables to remove!"
}
I used the bit about clearing up variables because the values seemed to persist if the PowerShell session remained open and it was causing odd things to happen. I also removed the home drive attributes because the file server specified hasn't been implemented yet but management still wants the users in AD now.
For reference my import.csv looks like this
FirstName,LastName,UPN,SAM,Password,OU,JobTitle,Street,Town,County,PostCode,Telephone,Company,Department,ExtendedAttribute1,ExtendedAttribute2,ExtendedAttribute14,ExtendedAttribute15,GroupName1,GroupName2,GroupName3,GroupName4
Test,User,Test.Users#domain.uk,Test.User,,"OU=Admin Staff,OU=User Resources,OU=School,OU=Trust Schools,DC=AD,DC=Trust,DC=org",,Street Name,TownName,County,AA11 1AA,116123,Name Of School,Name Of Trust,,Staff,,,AllStaffGroup,AdminStaffGroup,SpecialPermissionsGroup,Group4

Related

Adding users through PowerShell

I am trying to add users through my AC / DC with a powershell script then put those users in their assigned groups from a csv file. This is the code I have but when I put it into powershell and run it, it doesnt do anything. I waited about 30 min and nothing populated in for the users or groups. Does it usually take a while to add users and put them in groups or is there something I am missing?
$UserList = Import-Csv -Path 'C:\Users\Administrator\Desktop names.csv'
foreach ($User in $UserLis) {
$Attributes = #{
Enabled = $true
ChangePasswordAtLogon = $true
Path = "OU=balrok Users, DC=balrok, DC=edu"
Name = "$($User.First) $($User.Last)"
UserPrincipleName = "$($User.First) $($User.Last)#balrok.edu"
SamAccountName = "$($User.First) $($User.Last)"
EmailAddress = "$($User,First)#balrok.edu"
GivenName = $User.First
Surname = $User.Last
Description = $User.Age
Group = $User.Group
AccountPassword = "1234" | ConvertTo-SecureString -AsPlainText -Force
if (Add-ADGroupMember -Identity $Group -Members $SamAccountName){
Write-Host "Added" $SamAccountName to $Group" -ForeGroundColor Green
}
}
New-ADUser #Attributes
}

About importing manager attribute to AD from a CSV

I'm trying to import manager attribute to active directory for set of users using the following CSV file template
GivenName Surname DisplayName Department Title mail MobilePhone Manager SamAccountName
John Smith John Smith IT IT Manager john#example.com 1234 Mark Ebert JohnS
I used the below script and but it throws out an error.What i'm thinking it is due to manager attribute required to be in distinguished name format and **but i cannot change the csv manager column name as it comes from a different program.**The manager name in the CSV file shows in first name and last name format. What i need is to import the data on it to AD like the way it is.Any alternative methods available for this scenario.Here is the example script i used.
# Import AD Module
Import-Module ActiveDirectory strong text
$users = Import-Csv -Path C:\temp\MergedTo_AD.csv
foreach ($user in $users)
{Get-ADUser -Filter "SamAccountName -eq '$($user.samaccountname)'" | Set-ADUser -GivenName $($User.GivenName) -Surname $($User.Surname) -DisplayName $($User.DisplayName) -title $($User.title) -EmailAddress $($User.EmailAddress) -MobilePhone $($User.MobilePhone) $User -manager $ID }
If your CSV looks like this:
GivenName,Surname,DisplayName,Department,Title,mail,MobilePhone,Manager,SamAccountName
John,Smith,John Smith,IT,IT Manager,john#example.com,1234,Mark Ebert,JohnS
Joe,Bloggs,Joe Bloggs,Marketing,Administrative Assistant,joe#example.com,87954,,JoeB
Then you can see that in the second example the Manager property is empty.
To best deal with columns that could be empty, use Splatting for properties that are present in the CSV, while omitting empty fields:
Something like this:
$users = Import-Csv -Path C:\temp\MergedTo_AD.csv
foreach ($user in $users) {
# first try and find the user object in AD
$adUser = Get-ADUser -Filter "SamAccountName -eq '$($user.SamAccountName)'" -Properties Manager -ErrorAction SilentlyContinue
if ($adUser) {
# we have a valid user. create a splatting Hashtable to use with Set-ADUser
# Leave out the Manager for now, as we first need to make sure we can actually find a DN for this property.
$userProps = #{
# take out any properties you do not want to (re) set
GivenName = $user.GivenName
Surname = $user.Surname
DisplayName = $user.DisplayName
Title = $user.Title
EmailAddress = $user.mail
MobilePhone = $user.MobilePhone
}
# try and get the manager object from the $user.Manager column which may or may not have been set
if (![string]::IsNullOrWhiteSpace($user.Manager)) {
# try and find an AD user with the given DisplayName. You could also try with the `Name` property
$manager = Get-ADUser -Filter "DisplayName -eq '$($user.Manager)'" -ErrorAction SilentlyContinue
if ($manager) {
# add the 'Manager' entry to the Hashtable for properties to set
$userProps['Manager'] = $manager.DistinguishedName
}
else {
Write-Warning "Could not find '$($user.Manager)' in AD.."
}
}
else {
Write-Warning "Manager column for user '$($user.SamAccountName)' is empty.."
}
# here we set the properties to the user according to the CSV file
Write-Host "Updating user properties for '$($user.SamAccountName)'"
$adUser | Set-ADUser #userProps
}
else {
Write-Warning "User '$($user.SamAccountName)' could not be found.."
}
}
I'm not a scripting expert at all.I amended the script as below as per your suggestion.
# Import AD Module
Import-Module ActiveDirectory
$users = Import-Csv -Path C:\temp\MergedTo_AD.csv
{Get-ADUser -Filter "SamAccountName -eq '$($user.samaccountname)'" $FirstName,$LastName = (-split $User.Manager).Trim() $ID = (Get-ADUser -LDAPFilter "(&(GivenName=*$FirstName*)(SurName=*$LastName*))").SamAccountName (Get-ADUser -LDAPFilter "(&(GivenName=*$FirstName*)(SurName=*$LastName*))").SamAccountName| Set-ADUser -GivenName $($User.GivenName) -Surname $($User.Surname) -DisplayName $($User.DisplayName) -title $($User.title) -EmailAddress $($User.EmailAddress) -OfficePhone $($User.OfficePhone) -MobilePhone $($User.MobilePhone) -manager $($User.manager) }
I'm getting below error
Get-ADUser : The search filter cannot be recognized
At C:\Temp\PowershellScript-Users Import.ps1:5 char:128
+ ... im() $ID = (Get-ADUser -LDAPFilter "(&(GivenName=*$FirstName*)(SurNam ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-ADUser], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8254,Microsoft.ActiveDirectory.Management.Commands.GetADUser
I've reviewed the code and the reason it fails is because you cannot add the manager using the variable '$ID' is that it has no reference, nor does it resolve to the managers active directory user account. Your choices are either add the managers Distinguished Name to your csv file or stick it in your code to resolve the managers Distinguished Name.
#Import CSV File to set variable for the user’s logon name of whom manager’s field needs to be filled + delimiter
$users = Import-Csv -Delimiter ";" -Path "C:\temp\MergedTo_AD.csv"
foreach ($user in $users) {
#The Managers AD Sam Account Name
$ManagersaMACCount = "saMACcount"
#The Managers AD Distinguished Name
$ManagerID = (Get-ADUser -identity $ManagersaMACCount).DistinguishedName
#Example of Setting User's Manager Attribute -Example below
#Get-aduser -identity $user | Set-ADUser -Manager $ManagerID
#Using your code to filter AD Sam Accounts Based on column samaccountname in the csv file
Get-ADUser -Filter "SamAccountName -eq '$($user.samaccountname)'" `
#Pipe Set Users GivenName Based on column GivenName
| Set-ADUser -GivenName $($User.GivenName) `
#Set Users Surname Based on column Surname
-Surname $($User.Surname) `
#Set Users Display Name Based on column DisplayName
-DisplayName $($User.DisplayName) `
#Set Users Title Based on column Title
-title $($User.title) `
#Set Users Email Address Based on column EmailAddress
-EmailAddress $($User.EmailAddress) `
#Set Users Mobile Phone Based on column MobilePhone
-MobilePhone $($User.MobilePhone) `
#Set Users Manager Based on the Distinguished Name Attribute In Active Directory
-manager $ManagerID
}

Issue bulk creation of users in AD

I'm trying to create kind of a solution to create thousands of accounts in AD add them to specific group or for service accounts add them to specific OU. Keep a log of what was done and what the errors are.
The script ingest a csv file with the following headers.
SamAccountName,name,password,ou,domain,isAdded
$Domain = [system.directoryservices.activedirectory.domain]::GetCurrentDomain().Name
$NewUserADGroup = 'Print Operators'
$NewUsersList = Import-Csv .\bulk_user1.csv | Where-Object{$_.domain -like "$Domain"}
$NewUsersList | ForEach-Object{
$NewUserAttributes = #{
SamAccountName = $_.SamAccountName
name = $_.name
#path = $_.parentou
#UserPrincipalName = $_."samAccountName" + "#lovely.Local"
AccountPassword = (convertto-securestring "$NewUsersList.password" -AsPlainText -Force)
Enabled = $true
#Server = $dcname
#isAdded = $Issue
}
try{
#Create new User and add to specific group
New-ADUser $NewUserAttributes
Add-ADGroupMember -Identity $NewUserADGroup -Members $_.SamAccountName
#Delete Specific User
#Remove-ADUser -Identity $_.SamAccountName
}catch{
Write-Warning $_
$Issue = $_.ToString()
}
$count = $count + 1
Write-Host $_.SamAccountName " " $_.Name " " $_.SamAccountName.Enabled " Total:" $NewUsersList.Count + "Processed:" $count
$NewUserAttributes| Select-Object -Property SamAccountName,name,AccountPassword,Enabled,isAdded | Export-Csv ".\$Domain.NewAccountsCreatedStatus.csv"
}
I'm getting the following error:
WARNING: The name provided is not a properly formed account name
When I look at the variable
$NewUserAttributes
I do see the name and the value:
Name Value
---- -----
Enabled True
name bfmbsngfilexfer2
AccountPassword System.Security.SecureString
SamAccountName bfmbsngfilexfer2
As promised, below a rewrite of your code.
I have inserted comments to hopefully explain what the code does:
$Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name
$NewUserADGroup = 'Print Operators'
$successCount = 0
$NewUsersList = Import-Csv .\bulk_user1.csv | Where-Object { $_.domain -eq $Domain } | ForEach-Object {
# capture the human readable password for output use
$password = $_.password
$userParams = #{
SamAccountName = $_.SamAccountName
Name = $_.name
Path = $_.parentou
UserPrincipalName = '{0}#lovely.Local' -f $_.SamAccountName
AccountPassword = ConvertTo-SecureString $_.password -AsPlainText -Force
Enabled = $true
#Server = $dcname
}
try{
# Create new User and add to specific group
$user = New-ADUser #userParams -PassThru -ErrorAction Stop
Add-ADGroupMember -Identity $NewUserADGroup -Members $user -ErrorAction Stop
# add the 'isAdded' element to the $userParams hashtable
$userParams['isAdded'] = $true
$successCount++
}
catch{
Write-Warning $_.Exception.Message
$userParams['isAdded'] = $false
}
# output a PsCustomObject with values taken from the Hashtable
# AccountPassword is a SecureString, which will be of no use to you..
# Output the human readable password instead so you can inform the new users.
[PsCustomObject]$userParams | Select-Object SamAccountName, Name,
#{Name = 'Password'; Expression = {$password}},
Enabled, isAdded
}
# output
# use '#($NewUsersList)' to force it as array, so the Count property is accurate
if (#($NewUsersList).Count) {
Write-Host ('Processed: {0} Succeeded: {1}' -f $NewUsersList.Count, $successCount) -ForegroundColor Green
$NewUsersList | Export-Csv ".\$Domain.NewAccountsCreatedStatus.csv" -NoTypeInformation
}
else {
Write-Host 'No users successfully processed!' -ForegroundColor Red
}

Add users into AD group with correct CSV output

I am trying to add an AD group into user profiles based on an OU
I had a similar script working, so tried to modify it and failed. I am guessing it's the " -Identity $_" it maybe, but I am not good enough to debug.
#Create a new class to hold the info for our CSV entry
Class CSVEntry{
[String]$UserName
[String]$GroupName
[String]$TimeStamp
}
#Creating a list to hold the CSV entries
$Results = New-Object 'System.Collections.Generic.List[PSObject]'
#Defined the name of the group here
$GroupName = 'GROUPS NAME'
$ou = 'ou=XX,ou=XX,ou=XX,dc=XX,dc=local'
Get-ADUser -Filter * -SearchBase $ou | ForEach-Object{
#Add the user to the group here
Add-ADPrincipalGroupMembership -MemberOf $GroupName Identity $_
#Write-Host $_.Name - $groupName
#Build a custom CSVEntry object and add it to the list
$newRecord = [CSVEntry]::new()
$newRecord.UserName = $_.Name
$newRecord.GroupName = $groupName
$newRecord.TimeStamp = Get-Date
#Add the new record to the list
$Results.Add($newRecord)
}
#Export the list of CSV entries
$Results | Export-Csv C:\PS\AddADGroupToUsers.csv
errors:
Add-ADPrincipalGroupMembership : A positional parameter cannot be found that accepts argument 'CN=NAME,OU=XX,OU=XX,OU=XX,OU=XX,DC=XX,DC=LOCAL'.
At line:18 char:5
+ Add-ADPrincipalGroupMembership -MemberOf $GroupName Identity $_
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Add-ADPrincipalGroupMembership], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.ActiveDirectory.Management.Commands.AddADPrincipal
GroupMembership
EDIT:
So, the script doesn't actually do any changes, the group doesn't get added to the users. the output on screen is:
WARNING: User is already a member of group XYZ
WARNING: User is already a member of group XYZ
WARNING: User is already a member of group XYZ
UserName GroupName TimeStamp
-------- --------- ---------
shows ok XYZ 14/10/2019 14:50:23
shows ok XYZ 14/10/2019 14:50:23
shows ok XYZ 14/10/2019 14:50:23
All I have changed is the group name to XYZ and username shows ok in the second half. But, shows blank in the top, and I assure you that a) the user isn't already in the group and b) the script isn't adding them
Current tweaked code, warts and all but sanitised:
$groupName = 'GROUP'
$ou = 'setcorrectly'
$cred = Get-Credential -credential dom\usr
$results = Get-ADUser -Filter * -SearchBase $ou -Credential $cred | ForEach-Object {
#Add the user to the group here
try {
Add-ADGroupMember -Identity $groupName -Members $_.DistinguishedName -Credential $cred -ErrorAction Stop
}
catch {
Write-Warning "User $($_.Name) is already a member of group $groupName"
}
# output a PsCustomObject that gets collected in the $results variable
[PsCustomObject]#{
'UserName' = $_.Name
'GroupName' = $groupName
'TimeStamp' = Get-Date
}
}
# output on console
$results | Format-Table -AutoSize
# Export to CSV file
$results | Export-Csv C:\PS\AddADGroupToUsers.csv -NoTypeInformation
Read-Host -Prompt "Press Enter to exit"
CSV output shows the second half of the screen output only, and doesn't say anything is already a member
Below uses Add-ADGroupMember to add user(s) to 1 group instead of Add-ADPrincipalGroupMembership which is used to add 1 user to multiple groups.
It also uses [PsCustomObject]s to output the results, so you don't need to use the Class CSVEntry.
# Define the name of the group here.
# can be either:
# A distinguished name
# A GUID (objectGUID)
# A security identifier (objectSid)
# A Security Account Manager account name (sAMAccountName)
$groupName = '<NAME OF THE GROUP>'
$ou = 'ou=XX,ou=XX,ou=XX,dc=XX,dc=local'
$results = Get-ADUser -Filter * -SearchBase $ou | ForEach-Object {
#Add the user to the group here
$userName = $_.Name
try {
Add-ADGroupMember -Identity $groupName -Members $_.DistinghuishedName -ErrorAction Stop
# output a PsCustomObject that gets collected in the $results variable
[PsCustomObject]#{
'UserName' = $_.Name
'GroupName' = $groupName
'TimeStamp' = Get-Date
}
}
catch {
Write-Warning "User $userName is already a member of group $groupName"
}
}
# output on console
$results | Format-Table -AutoSize
# Export to CSV file
$results | Export-Csv C:\PS\AddADGroupToUsers.csv -NoTypeInformation
Edit
If you want the $results variable to ALSO contain users that are already a member of the group, you could simply move the creation of the [PsCustomObject] below the catch{..} block:
$results = Get-ADUser -Filter * -SearchBase $ou | ForEach-Object {
#Add the user to the group here
$userName = $_.Name
try {
Add-ADGroupMember -Identity $groupName -Members $_.DistinghuishedName -ErrorAction Stop
$status = "User added successfully"
}
catch {
Write-Warning "User $userName is already a member of group $groupName"
$status = "User is already a member"
}
# output a PsCustomObject that gets collected in the $results variable
[PsCustomObject]#{
'UserName' = $userName
'GroupName' = $groupName
'TimeStamp' = Get-Date
'Status' = $status
}
}
Hope that helps

what is the right syntax for Splatting on powershell?

OK guys, i've edited my script for user creation and now it's almost perfect except one thing that i cant figure out
how to make the hash table read the Variable for the "$GivenName $Surname"
and make the Name of the user, because now it's creating users without the Name parameter
or I need to creat a header for $GivenName and $surname in the csv file
cls
#get the csv file
$filepath = import-csv "C:\users.csv"
#set the variable for the uers
$newusers = $filepath
#set Passwords for new users
$securepassword = ConvertTo-SecureString "BlahBlah" -AsPlainText -Force
foreach ($user in $newusers) {
#get user information
$User_Creation_Settings = #{
Name = "$GivenName $Surnam"
GivenName = $user.GivenName
Surname = $user.Surnam
UserPrincipalName = $user.UserPrincipalName
SamAccountName = $user.SamAccountName
Path = $user.Path
ScriptPath = $user.ScriptPath
ChangePasswordAtLogon = $false
Department = $user.Department
DisplayName = $user.DisplayName
Description = $user.Description
Title = $user.'Job Title'
AccountPassword = $securepassword
Enabled = $true
}
New-ADUser #User_Creation_Settings
#Get Groups information
$group1 = $user.Group1
$group2 = $user.Group2
$group3 = $user.Group3
$group4 = $user.Group4
#Add the users in to Groups
Add-ADPrincipalGroupMembership -Identity $user.SamAccountName -MemberOf $user.group1
Add-ADPrincipalGroupMembership -Identity $user.SamAccountName -MemberOf $user.group2
Add-ADPrincipalGroupMembership -Identity $user.SamAccountName -MemberOf $user.group3
Add-ADPrincipalGroupMembership -Identity $user.SamAccountName -MemberOf $user.group4
Write-Host "`n"
Write-Host "The account for $GivenName $Surnam created in $OuPath successfully "
}
pause
so i've figured it out and i'm posting the solution
for the solution of the issue that i've described, i had to make Powershell think that "First name" and "Last Name" are one whole variable which is split in the middle, that's why i've used the parentheses with a "$" sign before them, Power Shell will think that you are using the $user from the loop, and will "Popup" the headers from the CSV file.
here is the whole script
cls
#get the csv file
$filepath = import-csv "C:\users.csv"
#set the variable for the uers
$newusers = $filepath
#set Passwords for new users
$securepassword = "BlahBlah"
foreach ($user in $newusers) {
#get user information
$User_Creation_Settings = #{
Name = "$($user.'First Name') $($user.Lastname)"
GivenName = $user.'First Name'
Surname = $user.Lastname
UserPrincipalName = $user.UserPrincipalName
SamAccountName = $user.SamAccountName
Path = $user.Path
ScriptPath = $user.ScriptPath
ChangePasswordAtLogon = $false
Department = $user.Department
DisplayName = $user.DisplayName
Description = $user.Description
Title = $user.'Job Title'
AccountPassword = ConvertTo-SecureString $securepassword -AsPlainText -Force
Enabled = $true
}
New-ADUser #User_Creation_Settings
#Get Groups information
$group1 = $user.Group1
$group2 = $user.Group2
$group3 = $user.Group3
$group4 = $user.Group4
#Add the users in to Groups
Add-ADPrincipalGroupMembership -Identity $user.SamAccountName -MemberOf $user.group1
Add-ADPrincipalGroupMembership -Identity $user.SamAccountName -MemberOf $user.group2
add-ADPrincipalGroupMembership -Identity $user.SamAccountName -MemberOf $user.group3
Add-ADPrincipalGroupMembership -Identity $user.SamAccountName -MemberOf $user.group4
Write-Host "`n"
Write-Host "The account for $($user.'First Name') $($user.Lastname) created in $($user.Path) successfully "
}
pause
So in that case:"$($user.'First Name') $($user.Lastname)"
powershell will behave like you entered one whole variable.
The short answer is that both are fine, because both are valid ways of creating hashtables in PowerShell. For more information, check out about_Splatting.
Personally, I use single quotes around strings across the board and leave variables alone so that PowerShell doesn't think I'm trying to call a function. As mentioned, this is not required here and frankly can make your code look messier than it needs to be.
A few things to watch out for:
Name = $firstname $lastname # invalid because of the space
'class' = win32_logicaldisk # invalid: PowerShell will look for the function win32_logicaldisk
GivenName = '$firstname' # because single quotes are used, PowerShell will not replace the variable; GivenName will literally be $firstname
Both the above splatting are fine and the reason for the color change is in the first Hashtable "$firstname $lastname" is a string as you have mentioned it in quotes, Editor represents Strings in Brown color and variables in black color.
In the second Hashtable you used single quotes for all the Keys and values and again those are understood and represented as Strings by the editor.
No harm either way.