Export AD users with list of specific groups - powershell

I've been trying to get an extract of AD users and select mail, name, memberof. I then need to list only specific groups from the memberof output so I end up with a list for each user than contains their name, email address and specific groups that match a certain name and not all of the groups they are a member of.
Get-ADUser username -Properties memberof | Select-Object memberof
I can't seem to find a way of doing this as I end up with either noteproperty above or an empty pipeline. Is there a way to achieve what I am trying to do?

The memberOf attribute contains a list of distinguishedName (DN) values, each corresponding to a group.
Retrieve the groups you are interested in, before you run Get-ADUser, that way you can compare the Group DN to the entry in memberOf:
$GroupDNs = Get-ADGroup -Filter {Name -like "*finance*" -or Name -like "*creditcontrol*"} | Select-Object -ExpandProperty DistinguishedName
Now, you can use those DN's to filter the group memberships with a calculated property, like so:
$UserInfo = foreach($username in #("bob","alice","joe")){
$User = Get-ADUser -Identity $username -Properties mail,memberOf |Select Name,mail,memberof
$User | Select-Object Name,mail,#{Label="GroupDNs";Expr = {$_.memberof | Where-Object {$Groups -contains $_}}}
}
without doing a new Get-ADGroup query for each memberof entry.
If you want a string of group names, rather than a NoteProperty containing an array of strings, you could fill the Groups into a hashtable and use that to "look up" the memberof entries using the ContainsKey() method:
$Groups = #{}
Get-ADGroup -Filter {Name -like "*finance*" -or Name -like "*creditcontrol*"} | ForEach-Object {
$Groups[$_.DistinguishedName] = $_
}
$UserInfo = foreach($username in #("bob","alice","joe")){
$User = Get-ADUser -Identity $username -Properties mail,memberOf |Select Name,mail,memberof
$User | Select-Object Name,mail,#{Label="Groups";Expr = { ($_.memberof | Where-Object {$Groups.ContainsKey($_)} | ForEach-Object { $Groups[$_].Name}) -join ";" }}
}
$UserInfo | Export-Csv C:\aduserinfo.csv -NoTypeInformation

Related

Get Specific AD Users from AD Group

I need to get specific users from specific Groups in Active Directory.
So far I have this:
$Groupnames = get-adgroup -Filter "name -like '$Groupfilter'" -Properties * -SearchBase $Grouppath |
Select-Object Name, #{
Name='Username';
Expression={
Get-ADGroupMember -identity $($_.Name) -Recursive |
Get-ADUser -Property SamAccountName |
Select -ExpandProperty SamAccountName
}
}
This works to get the Groups with their names. Now I want to get all users from these groups. what works but the formating is completly off. I want this:
Name Username
---- --------
Group1 user1adm
Group2 {user1adm, user1, user2, user2adm...}
Group3 {user1adm, user3, user2adm, user6...}
But I get this:
{user1adm, user1, user2, user2adm...}
With that formatting I can't see all users.
My goal at the end is also to exclude users who end with adm, but I don't know how to do that.
Can you help me?
Get-ADGroupMember can return objects of type 'user', 'group' or 'computer', so piping the returned objects straight through to Get-ADUser could get you into trouble if one of the objects is not a user.
Having said that, the objects returned from Get-ADGroupMember already contain the SamAccountName property you are after, so you can eliminate Get-ADUser from the code.
$Groupnames = Get-ADGroup -Filter "name -like '$Groupfilter'" -SearchBase $Grouppath |
Select-Object Name,
#{Name = 'Username'; Expression = {
($_ | Get-ADGroupMember -Recursive |
Select-Object -ExpandProperty SamAccountName |
Where-Object { $_ -notmatch 'adm$' }
) -join ', '
}
}
# output the result on screen
$Groupnames | Format-Table -AutoSize
# output to CSV file
$Groupnames | Export-Csv -Path 'Path\To\The\GroupMembers.csv' -NoTypeInformation

How to get all groups that a user is a member of, based on group extensionattribute

I'm tryng to get all the groups the users of a domain are member of, but filtering only the groups with a given extensionattribute.
I set the extensionattribute12 of all the domain groups to better filter some queries (i.e. Infrastructure - security - elearning). My query should get only the user(s) groups with
extensionattribute12=security
(for example).
I use something like:
get-aduser -filter -Properties memberof | select name, #{ l="GroupMembership"; e={$_.memberof -join ";" } }
and I get all the groups of the users. How can I filter by group extensionattribute?
You could use the inverse relationship (member on the group object) to query all the groups a user is a member of, just 1 query per user. Here using an LDAP filter:
$groupLabel = "Security"
Get-ADUser -Filter * |ForEach-Object {
$groups = Get-ADGroup -LDAPFilter "(&(extensionattribute12=$groupLabel)(member=$($_.DistinguishedName)))"
[pscustomobject]#{
User = $_.SamAccountName
GroupMembership = $groups.DistinguishedName -join ';'
}
}
If you have to process a large number of users or group memberships, you may find it faster to retrieve all the groups satisfying the extensionAttribute12 criteria up front and use that list to filter the memberOf attribute on the users:
$groupLabel = "Security"
# Create a hash set and populate it with the distinguished
# names of all the groups we're looking for
$groupDNs = [System.Collections.Generic.HashSet[string]]::new(#(
Get-ADGroup -Filter "extensionAttribute12 -eq '$groupLabel'" |Select -Expand DistinguishedName
))
Get-ADUser -Filter * -Properties memberOf |ForEach-Object {
# Retrieve memberOf values and filter against the hash set
$groups = $_.memberOf |Where-Object { $groupDNs.Contains($_) }
[pscustomobject]#{
User = $_.SamAccountName
GroupMembership = $groups -join ';'
}
}
Make it with N+1 queries
$groups = #( Get-ADGroup -Filter '(extensionattribute12 -eq "security")' )
$users = #( $groups |
ForEach-Object { Get-ADGroupMember -Identity $_ -Recursive } |
Sort-Object -Unique )
$users # All users of all groups that have EA12 = security
Get-ADUser -filter {...} -Properties memberof | select name, #{ l="GroupMembership"; e={( $_.memberof | Get-ADGroup |?{ $_.extensionattribute12 -eq 'security' }) -join ";" }} |?{ $_.GroupMembership }

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.

Export CSV of AD SamAccountNames and Groups for every user in specific OU

I found a similar question here, but it doesn't quite fit my need and I am having trouble tweaking it to do so.
I need to create a .csv file of all users in a specific OU along with what their AD group membership is in the following format:
User, Group (This is a Header)
User1, Group1
User1, Group2
User1, Group3
User2, Group1
User3, Group1
User4, Group1
User4, Group2
I think this script gets me most of the way there:
$Users = Get-ADGroup -SearchBase "OU=OrgUnit1,OU=OrgUnit2,OU=OrgUnit3,DC=XXX,DC=LOCAL" -Filter * `
| Get-ADGroupMember -Recursive `
| ForEach-Object { Get-ADUser $_ –Properties MemberOf | Select SamAccountName, MemberOf; } `
| Sort-Object SamAccountName
| export-csv C:\Messaging\PowerShell\ADUsers\Test1.csv
The problem with this is two fold.
I want to search on OU=OrgUnit1 without having to search on the full distinguished name, because the sub OU's aren't always the same.
The .csv output has the full distinguished name of the AD Group and I need just the Name of the group with no qualifiers
Use Get-ADOrganizationalUnit to get the OU you want to search:
$ou = Get-ADOrganizationalUnit -Filter "Name -eq 'OrgUnit1'"
Get-ADGroup -Filter * -SearchBase $ou | ...
The memberOf property is a list of groups (or rather their distinguished names). To get the output you want you need to unroll and resolve the group names and create new custom objects with the desired properties:
... | ForEach-Object {
$account = $_.SamAccountName
$_.MemberOf | Get-ADGroup | ForEach-Object {
New-Object -Type PSCustomObject -Property #{
SamAccountName = $account
Group = $_.Name
}
}
} | ...
Also, there's no point in assigning pipeline output to a variable ($Users) if at the end of that pipeline you export the output to a file.
Modified code:
$ou = Get-ADOrganizationalUnit -Filter "Name -eq 'OrgUnit1'"
Get-ADGroup -Filter * -SearchBase $ou |
Get-ADGroupMember -Recursive |
ForEach-Object { Get-ADUser $_ -Properties MemberOf; } |
Sort-Object SamAccountName |
ForEach-Object {
$account = $_.SamAccountName
$_.MemberOf | Get-ADGroup | ForEach-Object {
New-Object -Type PSCustomObject -Property #{
SamAccountName = $account
Group = $_.Name
}
}
} | Export-Csv 'C:\Messaging\PowerShell\ADUsers\Test1.csv'
You don't need this much of code to write. User below code in PowerShell to export all AD user.
Something like this:
Import-Module ActiveDirectory
Get-ADUser -Filter * -Properties * | export-csv c:\ADusers.csv
If you have a big AD, that might take a while though.

How to get multiple users membership groups from AD using Powershell script?

I got a list of 150+ users and I want to know which group they have membership for?
I just started using PS. I can query for 1 user, but not for a list of users. Would like
to know exact command??? I got :
(get-aduser -identity "username" -properties memberof |select-object memberof).memberof > c:\temp\ss.csv
Read your user list into an array and check if your AD users are contained in that array:
$userlist = Get-Content 'C:\your\userlist.txt'
Get-ADUser -Filter '*' -Properties memberof | Where-Object {
$userlist -contains $_.SamAccountName
} | ForEach-Object {
$username = $_
$groups = $_ | Select-Object -Expand memberof |
ForEach-Object { (Get-ADGroup $_).Name }
"{0}: {1}" -f $username, ($groups -join ', ')
} | Out-File 'c:\temp\ss.csv'
Replace SamAccountName as appropriate if the user list doesn't contain the account names of the users.