Grabbing Specific AD Groups that a User is a Member Of - powershell

Just can't for the life of me figure this out. What I am trying to do is get a list of all the groups that a user is a member of. Then I would like to pass those along and grab the specific groups that I am looking for.
Below is what I have so far:
(Get-ADUser $user -Properties MemberOf ).MemberOf | Where-Object {$_.Name -contains 'Part of Group Name'}
This returns nothing. I have a feeling that I am not referencing the right property in my Where-Object but I am having a hard time finding what that is. I know the results of (Get-ADUser $user -Properties MemberOf ).MemberOf are:
CN=App - dyn_readuser_prod_WeblogicApps_NS,OU=Groups,OU=USCC,DC=int,DC=usc,DC=local
CN=App - dyn_readuser_prod_osb_NS,OU=Groups,OU=USCC,DC=int,DC=usc,DC=local
CN=App - dyn_readuser_prod_openshift_NS,OU=Groups,OU=USCC,DC=int,DC=usc,DC=local
CN=App - dyn_readuser_nonprod_WeblogicApps_NS,OU=Groups,OU=USCC,DC=int,DC=usc,DC=local
CN=App - dyn_readuser_nonprod_osb_NS,OU=Groups,OU=USCC,DC=int,DC=usc,DC=local
CN=App - dyn_readuser_nonprod_openshift_NS,OU=Groups,OU=USCC,DC=int,DC=usc,DC=local
I just can't figure out how to reference "CN".

Try it this way:
(Get-ADUser $user -Properties memberOf).memberOf |
Where-Object { $_ -like 'CN=*Part of Group Name*,*' }
The (...).memberOf syntax in PowerShell v3 and later is functionally equivalent to piping to Select-Object -ExpandProperty memberOf, so you could also write it this way:
Get-ADUser $user -Properties memberOf |
Select-Object -ExpandProperty memberOf |
Where-Object { $_ -like 'CN=*part of group name*,*' }
(The second variation would be required in PowerShell v2 which doesn't support the (...).memberOf "syntactic sugar.")

There's a cmdlet that works well for grabbing the group membership of a user. Try the following:
Get-ADPrincipalGroupMembership -Identity $user | Select -ExpandProperty Name | Select-String -Pattern 'Part of Group Name'

Related

How to remove All Groups with Exceptions by using Powershell?

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

Am I doing something wrong with my PowerShell array?

I'm trying to prepend any groups the user is a member of with "MW-" (that is working). But when I try to do a loop to add another user to those group names with the "MW-" that I stored in $var I get an error
Cannot bind parameter 'Identity'. Cannot convert value "#{MW-" + $_.name=MW-DFS-share1}" to value of type "Selected.Microsoft.ActiveDirectory.Management.ADGroup"
$var = Get-ADUser -Identity TestUser -Properties memberof |
Select-Object -ExpandProperty memberof |
Where {$_ -match "CN=DFS*"} |
Get-ADGroup -Properties name |
Select-Object {"MW-"+ $_.name}
foreach ($group in $var) {
Add-ADGroupMember -Identity $group -Member TestUser
}
Note; When I run the Get-ADUser command it produces the output below:
"MW-"+ $_.name
--------------
MW-DFS-share1
MW-DFS-files
MW-DFS-archive
A calculated property is the easiest way to fix your issue. Then you need to either expand that property or access the property directly in your loop.
$var = Get-ADUser -Identity TestUser -Properties memberof |
Select-Object -ExpandProperty memberof |
Where {$_ -match "CN=DFS*"} |
Get-ADGroup -Properties name |
Select-Object #{Label='Name';Expression={"MW-"+ $_.name}}
foreach ($group in $var.Name) {
Add-ADGroupMember -Identity $group -Member TestUser
}
The issues with your attempt was that you never provided a property name but rather just did the calculation. In the loop, you needed to access just the calculated values rather than the object that contained a property with the values.
If the goal is to read a user list from a file and then update each user's membership, you may do the following:
foreach ($user in (Get-Content c:\userlist.txt)) {
$var = Get-ADUser -Identity $user -Properties memberof |
Select-Object -ExpandProperty memberof |
Where {$_ -match "CN=DFS*"} |
Get-ADGroup -Properties name |
Select-Object #{Label='Name';Expression={"MW-"+ $_.name}}
Add-ADPrincipalGroupMembership -Identity $user -MemberOf $var.Name
}
Using a foreach loop allows for assigning each user to a variable as you iterate through the list. That variable can then be referenced at any point within the loop.

Filtering group memberships to copy from one user to another

I currently have working code that copies all group memberships of one user to another, taken from here:
Copy group membership from one user to another in AD
Get-ADuser $user_to_copy -Properties MemberOf | Select-Object -ExpandProperty MemberOf | Add-ADGroupMember -Members $user_name
I would like to add a filter which prevents groups that start with a number from being added.
For example:
123_Group - Would not be added to the new user.
Group_123 - Would be added to the new user.
I've been playing around with Where-Object but can't get it to work how I would like.
| Where-Object {$_.MemberOf -Match '[a-z]*'}
The groups have "CN=... etc." at the start which I've tried to account for as well but to no avail (no output errors, just not the output I need/expect). I'm not sure if I'm just making a mistake or should be attempting this another way.
Any help/advice is greatly appreciated.
Thank you.
Use .NET's Char.IsDigit method to check if the first character of the name is a numerical digit:
Get-ADuser $user_to_copy -Properties MemberOf `
| Select-Object -ExpandProperty MemberOf `
| Where-Object { -not [System.Char]::IsDigit($_[3]) } `
| Add-ADGroupMember -Members $user_name
I use $_[3] (the fourth character) since the memberOf attribute is a list of distinguishedName, which will all start with CN= followed by the name of the group.
Update: If you want to filter out groups that start with a certain string, use something like this:
$badstring = "Computer"
Get-ADuser $user_to_copy -Properties MemberOf `
| Select-Object -ExpandProperty MemberOf `
| Where-Object { -not $_.Substring(3).StartsWith($badstring) } `
| Add-ADGroupMember -Members $user_name

powershell script to query all users that belong to a certain group name and its variants

i'm trying to find all users that belong to the group "Windows".
i want to display their id, last name, first name.
desired output format:
Windows Users,1234567,John,Doe
Windows Administators,7654321,Jane,Doe
this one-liner does do more less what i want but i need to modify the parameter identity everytime from "Windows Users" to "Windows PowerUsers" to "Windows Administrators" etc.
example:
Get-ADGroupMember -identity "Windows Users" -Recursive | Get-ADUser | select SamAccountName, Surname, GivenName
so i attempted to put it all together by but it's giving me errors.
$ADGroups = Get-ADGroup -Filter {name -like "Windows*"}
foreach ($ADGroup in $ADGroups) {
Get-ADGroup -filter {Name -eq $ADGroup.Name} | Get-ADGroupMember -identity
$ADGroup.Name -Recursive | Get-ADUser | select SamAccountName, Surname, GivenName
}
any ideas will be greatly appreciated. i can't figure out how to capture all users that belong to the group Windows* such as "Windows Users" to "Windows PowerUsers" to "Windows Administrators" etc
note: i looked into this but it's not quite what i'm looking for Powershell script to display all Users in a Group AD
thank you.
Your example is a good start.
Try this one. It should do the job:
Get-ADGroup -Filter {name -like "Windows*"} | foreach {
$currentGroup = $_.Name
$_ | Get-ADGroupMember | foreach {
$_ | Get-ADUser | select #{name="Group"; expression={ $currentGroup }}, SamAccountName, Surname, GivenName
}
}
I don't have my access to AD at the moment, but i would give this a try
get-aduser -filter {memberof -like "Windows*"} -property samaccountname,surname,givenname,memberof | select samaccountname,surname,givenname
OR you could try this inside your original foreach loop...
get-adgroup -filter {name -eq $adgroup.name} | select -expand members | get-aduser $_ | select samaccountname,surname,givenname
I can't remember what "members" produces, I believe it is samaccountname if not you could add an ldap filter to get-aduser -filter {whatever -eq $_}

How to get ALL AD user groups (recursively) with Powershell or other tools?

I'm trying to get ALL the groups a user is member, even the nested ones (recusively), in Powershell I'm using:
(Get-ADUser <username> -Properties MemberOf | Select-Object MemberOf).MemberOf
But it only returns the groups the user is a "direct" member, like you get when using the AD users console. I single list of ALL the groups is very helpful, like the output from "gpresult -r", where it shows ALL the groups the user is a member.
Is there a way to get it from any AD user? (Doesnt need to be exclusively in Powershell, maybe theres another tool that I dont know yet)
You can use the LDAP_MATCHING_RULE_IN_CHAIN:
Get-ADGroup -LDAPFilter "(member:1.2.840.113556.1.4.1941:=CN=User,CN=USers,DC=x)"
You can use it anywahere that you can use an LDAP filter.
Example:
$username = 'myUsername'
$dn = (Get-ADUser $username).DistinguishedName
Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) | select -expand Name | sort Name
Or, you can use the constructed attribute tokenGroups and a base-scoped query:
$tokenGroups = Get-ADUser -SearchScope Base -SearchBase '<account-distinguishedName>' `
-LDAPFilter '(objectClass=user)' -Properties tokenGroups | Select-Object `
-ExpandProperty tokenGroups | Select-Object -ExpandProperty Value
Expanding on user2871239 answer about using tokenGroups:
To get all AD object groups recursively:
((Get-ADUser username | Get-ADUser -Properties tokenGroups).tokenGroups | Get-ADGroup).Name
Or, if you don't need an ADGroup object, this returns a String instead, but is way faster:
(Get-ADUser username | Get-ADUser -Properties tokenGroups).tokenGroups.Translate([System.Security.Principal.NTAccount]).Value
It's almost instantaneous in our directory:
PS C:\windows\System32> (Get-ADUser -Filter *).Count
86816
PS C:\windows\System32> (Get-ADGroup -filter *).Count
1808
PS C:\windows\System32> (Get-ADComputer -filter *).Count
2666
Just for reference, here how much time it takes in this instance:
# this returns String objects
1..10 | % {
Measure-Command {
(Get-ADUser marcos | Get-ADUser -Properties tokenGroups).tokenGroups.Translate([System.Security.Principal.NTAccount]).Value
}
} | Measure-Object -Average TotalSeconds | select #{l="Type";e={"String"}},Average
# this returns ADGroup objects
1..10 | % {
Measure-Command {
((Get-ADUser marcossantos | Get-ADUser -Properties tokenGroups).tokenGroups | Get-ADGroup).Name
}
} | Measure-Object -Average TotalSeconds | select #{l="Type";e={"ADGroup"}},Average
Type Average
---- -------
String 0.01415692
ADGroup 0.25427236
This also returns nested membership of primaryGroup (usually Domain users), which most solutions does not account for.
One downside of this approach is that it does not retrieve distribution groups. If you need that, following query returns just distribution groups, using LDAP_MATCHING_RULE_IN_CHAIN (way faster than retrieving all groups, though):
Get-ADGroup -LDAPFilter "(&(groupType>=0)(member:1.2.840.113556.1.4.1941:=CN=myuser,OU=MyUsers,DC=example,DC=com))"
tokenGroups
LDAP_MATCHING_RULE_IN_CHAIN
Microsoft page about tokenGroups