I'm trying to add multiple users to multiple groups from a csv file and have looked through every post about adding multiple users to multiple groups for the past weeks but due to the nature of csv file I am having trouble executing it correctly.
The data in the csv file looks like this
Username,FACULTY01,FACULTY02,FACULTY03,FACULTY04
"User1,group1,group2,group3"
"User2,group1,,group3,group4"
"User3,,group2,,group4"
There are 20+ groups, each member can be part of 1 to 4 groups found under the faculty headings
I have the following code
Import-Module ActiveDirectory
$csv = Import-csv C:\TestADGroupADD.csv -Header ('Username', 'FACULTY01', 'FACULTY02', 'FACULTY03', 'FACULTY04')
ForEach-Object {
$username = $_.Username
$Faculty = $_."Faculty01,FACULTY02,FACULTY03,FACULTY04"
}
Foreach($Faculty in $csv){
if ($Faculty -eq 'ADMINISTRATION') { Add-ADGroupMember -Identity $Faculty -Member $username }
if ($Faculty -eq 'Accounting') { Add-ADGroupMember -Identity $group -Member $username }
if ($Faculty -eq 'SCIENCE') { Add-ADGroupMember -Identity $group -Member $username }
if ($Faculty -eq 'SALES') { Add-ADGroupMember -Identity $groupe -Member $username }
if ($Faculty -eq 'DEANSFUND') { Add-ADGroupMember -Identity $group -Member $username }
}
I have a feeling I must use a different method to combine the faculties into one variable but I have tried with one and still fails - I am a beginner in PowerShell
Appreciate your help.
You could do something like this:
$faculties = #("FACULTY01", "FACULTY02", "FACULTY03", "FACULTY04")
$csv = Import-csv C:\temp\test.csv -Header (#("UserName") + $faculties)
foreach ($user in $csv | Select-Object -Skip 1)
{
foreach ($faculty in $faculties)
{
if ($user.$faculty)
{
Add-ADGroupMember -Identity $user.$faculty -Member $user.UserName
}
}
}
Related
When somebody leaves my organization, we remove all AD group memberships apart from the PrimaryGroup which is Domain Users. We often process these in batches, so pull the affected usernames from a CSV file.
I have the following code, and while it does the job of deleting all group memberships, I get an error for each user:
The user cannot be removed from a group because the group is currently the user's primary group
Whilst it does the job, how can I "clean up" the process to avoid this message each time? Is there a way to exclude Domain Users from the groups it removes the user from, or should I do this another way?
$users = Import-Csv "c:\temp\leavers.csv"
foreach ($user in $users) {
Get-ADPrincipalGroupMembership -identity $user.username | foreach {Remove-ADGroupMember $_ -Members $user.username -Confirm:$false}
}
You can use Where-Object for filtering those groups that are not in an array of groups to exclude. In case you only want to filter for 1 specific group, you would use -NE instead of -NotIn in below example.
$groupToExclude = 'Domain Users', 'someOtherGroup'
$users = Import-Csv "c:\temp\leavers.csv"
foreach ($user in $users) {
try {
Get-ADPrincipalGroupMembership -Identity $user.username |
Where-Object Name -NotIn $groupToExclude |
Remove-ADGroupMember -Members $user.username -Confirm:$false
}
catch {
Write-Warning $_.Exception.Message
}
}
If you get the ADUser object before the ADGroup memberships, you can get the PrimaryGroup of the user and ensure that the list of groups to remove from are not its PrimaryGroup:
$users = Import-Csv "c:\temp\leavers.csv"
foreach ($user in $users) {
$primaryGroup = ( Get-ADUser $user.UserName -Properties PrimaryGroup ).PrimaryGroup
Get-ADPrincipalGroupMembership -Identity $user.UserName | Where-Object {
$_ -ne $primaryGroup
} | ForEach-Object {
Remove-ADGroupMember $_ -Members $user.username -Confirm:$False -WhatIf
}
}
Since this has the potential to be a very destructive command, I have included a safeguard in the example above. Remove the -WhatIf parameter from Remove-ADGroupMember to actually perform the removal.
I'd propose a slightly different approach - just drop Get-ADPrincipalGroupMembership altogether. For example:
$users = Import-Csv -Path c:\temp\leavers.csv
foreach ($user in $users) {
# Assuming DN is not in the csv...
$distinguishedName = (Get-ADUser -Identity $user.UserName).DistinguishedName
Get-ADGroup -LdapFilter "(member=$distinguishedName)"
# Alternatively, just pipe memberOf property to Get-ADGroup...
(Get-ADUser -Identity $user.UserName -Property MemberOf).MemberOf |
Get-ADGroup
}
That way you don't have to filter out something you insisted on getting (by using above mentioned cmdlet).
I have a list of accounts (SAM account names) and a list of groups all the accounts need to be removed from. My problem is that I have to specify -server DC01 since the users are in a different domain. I can do that for removing 1 user at a time with:
$Groups = Get-Content C:\temp\groups.txt
$user = get-aduser <username> -Server "DC01.domain.com"
foreach ($Group in $Groups) {
Write-Host "Removing $user from $group" -Foreground Yellow
Remove-ADGroupMember -Identity $group -Members $user -Confirm:$false
}
But I have several long lists of users, and there's got to be a way to do this for all of them.
I tried adding the ** entries below, but no dice:
$Groups = Get-Content C:\temp\groups.txt
$user = Get-Content C:\temp\users0.txt **-Server "DC01.domain.com"**
foreach ($Group in $Groups) {
Write-Host "Removing $user from $group" -Foreground Yellow
Remove-ADGroupMember -Identity $group -Members $user **-searchbase = "DC=domain,DC=com"** -Confirm:$false
}
Thanks in advance for any suggestions!
I cannot test this right now, but I believe you can set the -Members parameter to an array of users.
Apparently, the Remove-ADGroupMember does not work if you supply an array of DistinguishedNames when the users are from another domain, so we need to use the full default (Microsoft.ActiveDirectory.Management.ADUser) objects as returned by the Get-ADUser cmdlet.
$DCGroups = (Get-ADDomain your.domainA.com).PDCEmulator # get a PDC emulator in domain A where the groups are
$DCUsers = (Get-ADDomain your.domainB.com).PDCEmulator # get a PDC emulator in domain B where the users are
$Groups = Get-Content 'C:\temp\groups.txt' # the groups are in domainA
# get an array users ADUser Objects from Domain B
$users = Get-Content 'C:\temp\users0.txt' | ForEach-Object {
$user = Get-ADUser -Filter "SamAccountName -eq '$_'" -Server $DCUsers -ErrorAction SilentlyContinue
if ($user) { $user }
}
# remove these users from the groups in Domain A
foreach ($Group in $Groups) {
Write-Host "Removing $($users.Count) users from $Group" -Foreground Yellow
Remove-ADGroupMember -Identity $Group -Members $users -Confirm:$false -Server $DCGroups
}
Edit
To overcome the exception being thrown when you try to remove a user that is not a member of the group, you need to add some extra code to make sure the -Members parameter of Remove-ADGroupMember contains only ADUser objects that currently are member of this group.
$DCGroups = (Get-ADDomain your.domainA.com).PDCEmulator # get a PDC emulator in domain A where the groups are
$DCUsers = (Get-ADDomain your.domainB.com).PDCEmulator # get a PDC emulator in domain B where the users are
$Groups = Get-Content 'C:\temp\groups.txt' # the groups are in domainA
# get an array users ADUser Objects from Domain B
$users = Get-Content 'C:\temp\users0.txt' | ForEach-Object {
$user = Get-ADUser -Filter "SamAccountName -eq '$_'" -Server $DCUsers -ErrorAction SilentlyContinue
if ($user) { $user }
}
# remove these users from the groups in Domain A
foreach ($Group in $Groups) {
# get a list of SamAccountNames of users that are currently a member of this group
$members = Get-ADGroupMember -Identity $Group | Where-Object {$_.objectClass -eq 'user'} | Select-Object -ExpandProperty SamAccountName
# create a subset of users that are indeed in the members list
$removeThese = #($users | Where-Object { $members -contains $_.SamAccountName })
if ($removeThese.Count) {
Write-Host "Removing $($removeThese.Count) users from $Group" -Foreground Yellow
Remove-ADGroupMember -Identity $Group -Members $removeThese -Confirm:$false -Server $DCGroups
}
else {
Write-Host "No users need to be removed from group '$Group' " -Foreground Green
}
}
I need to move ADUsers to each ADGroup they are listed under each column, the columns are the group names themselves so $_.groups since there are no headers.
You would need to loop through the column headers. You can obtain a list of these properties by using the Get-Member cmdlet.
$usersToAdd = Import-CSV users.csv
$groups = ($usersToAdd | Get-Member | Where-Object { $_.MemberType -eq "NoteProperty" }).Name
From here you could loop through the groups querying the members that fall under each group in the original csv.
foreach ($group in $groups) {
$users = $usersToAdd.$group
foreach ($user in $users) {
Add-ADGroupMember -Identity $group -Members $user -Confirm:$false
}
}
You may get some empty values if some columns have more users than others do, so perhaps you will want to check for that too.
foreach ($group in $groups) {
$users = $usersToAdd.$group
foreach ($user in $users) {
if (![string]::IsNullOrEmpty($user)) {
Add-ADGroupMember -Identity $group -Members $user -Confirm:$false
}
}
}
Thank you for your response Ash! I will try this shortly to confirm. I found this script online that worked rather well Though I am still breaking this down to fully understand it. Thank you again for your help!!::
> $rows = Import-Csv "C:\FILE.csv"
> $groups = #{}
> foreach ($header in $rows[0].PSObject.Properties.Name) { $groups[$header] = #() }
> foreach ($row in $rows)
> {
> [string[]]$keys = $groups.Keys
> foreach ($key in $keys)
> {
> if ($row.$key) { $groups[$key] += $row.$key }
> }
> }
>foreach ($key in $groups.Keys) { Add-ADGroupMember -Identity $key -Members $groups[$key] -Verbose }
I have a CSV file containing multiple values in one of its columns.
Basically it look like:
Name NewName Groups
UserA User01 IT Group;GroupB;Doc Users Group;GroupD
I need to know how to loop through the column to get all group names from it.
I used the following code but it doesn't work. I think the problem is there are spaces between words in group names and PowerShell treats the whole cell as one group name.
foreach ($user in (Import-Csv "$env:USERPROFILE\desktop\info.csv")) {
$oldusername = $user.name
$newusername = $user.NewName
$groups = $user.Groups -split ";"
foreach ($group in $groups) {
Remove-ADGroupMember $group -Members $oldusername -Confirm:$false -Verbose
Add-ADGroupMember $group -Members $newusername -Verbose
}
}
So I should get:
Remove-ADGroupMember IT Group
but I get:
Remove-ADGroupMember IT Group GroupB Doc Users Group GroupD
which obviously doesn't work.
I didn't copy/paste the csv file I just showed you the values in the file.
The proper csv content is:
"Name","NewName","Groups"
"UserA","User01","IT Group;GroupB;Doc Users Group;GroupD"
I think I solved the puzzle with the loop. The code which works is:
foreach ($user in (Import-Csv "$env:USERPROFILE\desktop\info.csv")) {
$oldusername = $user.name
$newusername = $user.NewName
$groups = $user.Groups
foreach ($group in $groups -split ";") {
Remove-ADGroupMember $group -Members $oldusername -Confirm:$false -Verbose
Add-ADGroupMember $group -Members $newusername -Verbose
} }
I have a .csv file with the group names and the SAM of the users I want to delete from the 10 groups.
How does this work? I am a PowerShell beginner.
Save the user list as csv and use something like
$users = import-csv C:\csvpath\users.csv
Foreach ($user in $users){
Remove-adgroupmember -identity "groupname1" -members $user.username -Confirm:$false
Remove-adgroupmember -identity "groupname2" -members $user.username -Confirm:$false
}
You could of course also get the groupnames from another csv to get a cleaner code
$users = import-csv C:\csvpath\users.csv
$groups = import-csv C:\csvpath\groups.csv
Foreach ($user in $users){
Foreach ($group in $groups) {
Remove-adgroupmember -identity $group.name -members $user.username -Confirm:$false
}
}