I am trying to set the membership of a group using Set-ADGroup with the -Replace parameter. I tried with
$adUsers = #()
$adUsers += Get-ADUser -Server domain1.corp.com -Identity user1
$adUsers += Get-ADUser -Server domain2.corp.com -Identity user2
$adUsers = $adUsers | select-object -expandproperty distinguishedname
Set-ADGroup -Server domain3.corp.com -Identity mygroup -Replace #{Member=$adUsers}
but that fails with
The specified account does not exist.
If you looked at my previous attempt you might have noted that my user objects come from two different doamins while my group comes from a third one.
So to test my code, I simplified my setup and tried with users coming from the same domain as the one where the group was located in
$adUsers = #()
$adUsers += Get-ADUser -Server domain3.corp.com -Identity user4
$adUsers += Get-ADUser -Server domain3.corp.com -Identity user5
$adUsers = $adUsers | select-object -expandproperty distinguishedname
Set-ADGroup -Server domain3.corp.com -Identity mygroup -Replace #{Member=$adUsers}
This works.
So I figured the AD module might not be liking FSPs.
But then I ran the following code:
$adUsers = #()
$adUsers += Get-ADUser -Server domain1.corp.com -Identity user1
$adUsers += Get-ADUser -Server domain2.corp.com -Identity user2
Add-ADGroupMember -Server domain3.corp.com -Identity mygroup -Members $adUsers
And this works. So it seems working with FSPs is certainly possible in the AD module.
But why is it not working for Set-ADGroup?
Should I be using something different from the distinguished name? I tried with the string representation of the SID, but that seems to be even worse (An internal error occured).
I am aware that I could use a combination of Remove-ADGroupMember and Add-ADGroupMember to make my code work but that seems inefficient as I would have to figure out first which users to remove. Replacing the member list with the correct entries seems more performant.
Update After some more testing I discovered that using the FSP in combination with Set-ADGroup works. So I can use 'CN=S-1-5-21-xxx-yyy-zzz-rid,CN=ForeignSecurityPrincipals,DC=DOMAIN3,DC=CORP,DC=com'. Of course that implies the FSP object exists already in DOMAIN3. Because if it does not and I fake the distinguishedname, the method logically just returns
Set-ADGroup: An internal error occurred.
Now I am wondering if Set-ADGroup -replace method can only work with existing objects while Add-ADGroupMember can also create (FSP) objects.
The problem was with the way the data needs to be formatted. You can use a users SID but it needs to be in the format <SID=S-1-5-21-xxx-yyy-zzz-rid>. This way FSPs are also automatically created when necessary
So my code ended up being something like:
[string[]]$sids= #()
$sids+= Get-ADUser -Server domain1.corp.com -Identity user1 -Properties #('SID') | ForEach-Object { '<SID=' + $_.SID + '>'}
$sids+= Get-ADUser -Server domain2.corp.com -Identity user2 -Properties #('SID') | ForEach-Object { '<SID=' + $_.SID + '>'}
Set-ADGroup -Server domain3.corp.com -Identity mygroup -Replace #{Member=$sids}
Related
I've seen many examples of using PS to remove all memberships (including Primary). I have working code as follows:
get-aduser person -properties MemberOf | Select -Expand MemberOf | %{Remove-ADGroupMember $_ -member person -confirm:$false}
This is great for stripping everything out, excluding Domain Users. No problems so far.
The next challenge is leaving behind a specific group, such as licensing for O365.
I attempted to build an array with exclusions, and excluding those from the removal:
$user = person
$keep = #(
'CN=nametokeep,OU=group,DC=company,DC=com',
'CN=nametoalsokeep,OU=group,DC=company,DC=com')
$groups = get-aduser person -properties memberof | select -expand memberof
$groups | %{$keep -notcontains $_} | Remove-ADGroupMember -member $user
The idea here is to define the exceptions and remove everything else that doesn't match up.
When I do this, the code does execute but prompts for input:
Members[0]:
Doesn't matter what value I put in there, the code just prompts again with Members[1], Members[2] and so on.
What am I missing?
In order to remove "person" from all the groups not in the keep array, you will need to do a Foreach on each of the groups out of the $keep array so you iterate through them.
Also, Remove-ADGroupMember does not have a -Member parameter.
Parameter is -Members and that's what your powershell prompt is asking about when you run the cmdlet without it's mandatory parameter.
The following script should accomplish what you seek.
$user = 'Person'
$keep = #(
'CN=nametokeep,OU=group,DC=company,DC=com',
'CN=nametoalsokeep,OU=group,DC=company,DC=com'
)
$groups = get-aduser -Identity $user -properties memberof | select -expand memberof
$groups.Where({$_ -notin ($keep)}) |
% { Remove-ADGroupMember -Identity $_ -Members $user}
Reference
Remove-ADGroupMember
I am trying to get only AD Objects of type user and then iterate over all them and change AD user object name. So I have done below:
$Users = Get-ADObject -Filter {(ObjectClass -eq "user")} # OR Get-ADObject -Filter 'ObjectClass -eq "user"'
$Users | foreach
{
# Here code to create name based on conditions ($newUserObjectName)
Rename-ADObject -Identity $_ -NewName $newUserObjectName
}
The problem is that Get-ADObject is returning not only users but also computer objects.... I only want user object classes. Also I am not sure If below line of code is correct by setting identity to $_ in order to update the current user in the iteration:
Rename-ADObject -Identity $_ -NewName $newUserObjectName
Why not use Get-ADUser instead of Get-ADObject and just return the DistinguishedName? Obviously, DON'T just run this code :)
$users = (Get-ADUser -Filter *).DistinguishedName #This gets all the users in AD
Foreach($user in $users){
Rename-ADObject -Identity $user -NewName $newUserObjectName
}
The Computer objectClass is derived from the User objectClass. Hence, queries for user class will return both Computers and Users. If you want to filter for Users only, you have to specify ObjectCategory as Person
$Users = Get-ADObject -Filter {(Objectclass -eq "user") -and (objectCategory -eq "Person")}
Use that or you can use the goodole Get-ADuser
Use Get-ADUser and Set-ADUser:
$Users = Get-ADUser -Filter *
$Users | foreach {
# Naming code
Set-ADUser -Identity $_.SamAccountName -SamAccountName $newName
}
This replaces all user's identities to $newName.
Note you can replace -SamAccountName with any other property of an ADUser. for example if you want to replace the display name instead, you would use -Name $newName
I want to make a script that deletes bulk users, instead of using SAMACCOUNTNAME I want to use the first and last name, is that possible?
Import-Module ActiveDirectory
$ADusers = Import-csv C:\TEST\Delete.CSV
Foreach ($user in $ADusers) {
#Confirming the identity
$users = Get-ADUser -Identity $user -Properties | Select-Object Givenname, Surename
#Removing the user
Remove-ADUser -Identity $user.samAccountName -Confirm:$false
}
I like Ambiguous Name Resolution when searching for users in AD:
Get-ADUser -LDAPFilter "(anr=Jim Smith)"
This will search for all objects where any of the naming attributes (see link above for list) start with the string "jim smith", plus all objects where (givenName=jim*) and (sn=smith*), plus objects where (givenName=smith*) and (sn=jim*).
This is useful when 'Jims' account uses his fully name of 'Jimmy', this would be returned by ANR but not by a direct givenName/sn filter.
You can have multiple users with the same First/Last name, so you will need to deal with the situation of multiple users being returned.
SAMAccoutName, however is unique to a single account
EDIT:
If you've got a csv with the two columns GivenName & Surname:
foreach ($user in $ADusers) {
$firstname = $user.GivenName
$lastname = $user.Surname
Get-ADUser -LDAPFilter "(anr=$firstname $lastname)"
}
The above just lists the users returned from Get-ADUser, to remove them just pipe to Remove-ADUser. I'm using WhatIf to test, remove to actually delete the users:
Get-ADUser -LDAPFilter "(anr=$firstname $lastname)" | Remove-ADUser -WhatIf
Yes it is.
Get-ADUser -Filter {GivenName -eq "Max" -and sn -eq "Muller"} | Remove-ADUser
You need to alter your script accordingly.
We are looking to create a Powershell script that will automatically sort our user base by Country Code into two AD groups, one for English speakers, and one for French speakers. We are having challenges in getting this to work.
Each account should only be on one list, based on their country. The original source list of members for our list is Staff All, and we are looking into having two groups, one called Staff All EN, and the other called Staff All FR. It should also be able to exclude those in a Disabled OU for accounts that are no longer valid. (see below)
This is what we have so far:
$frenchCC = Get-Content .\CCFrench.txt
$staffAll = "CN=Staff-ALL,OU=Internal,OU=DistributionLists,OU=SFCG,DC=sfcg,DC=org"
$staffAllEn = "CN=Staff ALL EN,OU=Internal,OU=DistributionLists,OU=SFCG,DC=sfcg,DC=org"
$staffAllFr = "CN=Staff ALL FR,OU=Internal,OU=DistributionLists,OU=SFCG,DC=sfcg,DC=org"
$Target = Get-ADGroupMember -Identity $staffAll
We have tried several different approaches. The idea is to populate the French list from the AD based on the country code list. Populate the Staff-EN by copying the Staff-ALL list and then removing everyone in the French list.
And somewhere in the process, Remove everyone who is in HR-Disabled.
foreach ($Person in $Target) {
Add-ADGroupMember -Identity $staffAllEn -Members $Person.distinguishedname -confirm:$false
}
foreach ($Country in $frenchCC) {
Add-ADGroupMember -Identity $staffAllFr -Members (Get-ADUser -Filter '"$country"' -eq '") -confirm:$false
}
foreach ($Country in $frenchCC) {
Remove-ADGroupMember "Staff-ALL-EN" -Members (Get-ADUser -Filter $Country) -confirm:$false
}
$searchOU = Specify the OU where your groups are here (OU=Groups,DC=domain,DC=local)
Get-ADGroupMember Staff-ALL-EN -Properties Disabled | Remove-ADGroupMember Staff-ALL-EN
Get-ADGroupMember Staff-ALL-FR -Properties Disabled | Remove-ADGroupMember Staff-ALL-FR
In the source file for the country code, we have put the country codes in single quotes, double quotes and no quotes. with no difference.
This has really caught us in a pickle. Any suggestions would be appreciated.
I was able to work on the following for Brad, but I am not being able to make it run for each line in the text files (ex: multiple country codes). Anyone know what to change?
$frenchCC = Get-Content .\Countries.txt
$OUs = Get-Content .\OUs.txt
$userListFR = Get-ADUser -Filter {country -eq $frenchCC} -SearchBase $OUs -SearchScope OneLevel
$userListEN = Get-ADUser -Filter {country -ne $frenchCC} -SearchBase $OUs -SearchScope OneLevel
foreach($user in $userListFR) {add-adgroupmember "Staff-ALL-FR" -Members $user}
foreach($user in $userListEN) {add-adgroupmember "Staff-ALL-EN" -Members $user}
Import-Module ActiveDirectory
$users = Get-ADGroupMember -identity “GroupName” | select saMAccountName
foreach($user in $users)
{
}
How can I get 2 properties from here. I need the sAMAccountName and the Office
First, verify if you want to get the "Office" property, or "physicalDeliveryOfficeName"
foreach ($user in $users)
{
Get-ADUser $user -Properties Office | select SamAccountName,Office
}
Also, you don't need to select anything for your $users object to work
$users = Get-ADGroupMember -Identity GroupName
A great thing about working with Active Directory cmdlets is that you can usually throw the entire object at it, and it will work because of:
[parameter(ValueFromPipelineByPropertyName=$true)]
Adding an example that worked for exporting to CSV:
Get-ADUser $user -Properties Office | select SamAccountName,Office | Export-Csv -NoTypeInformation C:\PSResults\foo.csv