The following PowerShell script generates a CSV file with three columns (Group, User, SAMAccountName) that associates each instance of a given distribution group with a respective member:
$dist = ForEach ($group in (Get-DistributionGroup -Filter {name -like "*"})) { Get-DistributionGroupMember $group | Select #{Label="Group";Expression={$Group.Name}},#{Label="User";Expression={$_.Name}},SamAccountName} $dist | Sort Group,User | Export-CSV c:\scripts\file.csv -NoTypeInformation
It affords the user a convenient way to filter the groups and display group members. My question: Is there a quick way to modify this script so that it adds a fourth column that displays a property of the groups (specifically, the "HiddenFromAddressListsEnabled" property)?
Just add it to the Select-Object portion
$dist = ForEach ($group in (Get-DistributionGroup -Filter {name -like "*"})) { Get-DistributionGroupMember $group | Select #{Label="Group";Expression={$Group.Name}},#{Label="User";Expression={$_.Name}},SamAccountName,HiddenFromAddressListsEnabled} $dist | Sort Group,User | Export-CSV c:\scripts\file.csv -NoTypeInformation
See it after the SamAccountName
To Get the HiddenFromAddressListsEnabled for the Groups:
$dist = ForEach ($group in (Get-DistributionGroup -Filter {name -like "*"})) { Get-DistributionGroupMember $group | Select #{Label="Group";Expression={$Group.Name}},#{Label="User";Expression={$_.Name}},SamAccountName,{$Group.HiddenFromAddressListsEnabled}} $dist | Sort Group,User #| Export-CSV c:\scripts\file.csv -NoTypeInformation
However, There's another way to do it, and easier to read and manipulate:
$Array = #()
$Groups = Get-DistributionGroup
Foreach ($Group in $Groups)
{
$DGMembers = Get-DistributionGroupMember $Group
Foreach ($Member in $DGMembers)
{
$Result = "" | Select GroupName,Member,SamAccountName,HiddenFromAddressListsEnabled
$Result.GroupName = $Group.Name
$Result.Member = $Member.Name
$Result.SamAccountName = $Member.SamAccountName
$Result.HiddenFromAddressListsEnabled = $Group.HiddenFromAddressListsEnabled
$Array += $Result
}
}
$Array | Export-CSV c:\scripts\file.csv -NoTypeInformation
Related
Is it possible to change the PS script below in two ways:
The group members are now exported horizontally but I want all the users in 1 cell in the column beside the group name. We have a lot of groups and it is not readable this way.
The path to the folders in the description field of the AD groups are not exported. I would like to have the content of the description field also exported in the column beside the group.
I would like to see this result, see the photo below please:
cls
$Groups = "Group1", "Group2", "Group3"
$results = foreach ($Group in $Groups) {
Get-ADGroupMember -Server contoso.com $group |
select SamAccountName, #{n='GroupName';e={$group}}, #{n='Description';e={(Get-ADGroup $group -Properties description).description}}
}
$results
$results | Export-csv C:\TEMP\GroupMemberShip.CSV -NoTypeInformation
With some minor changes to your original code, you could first gather the wanted info per group and before exporting to CSV, use Group-Object to merge the details.
Something like:
$Groups = "Group1", "Group2", "Group3"
$results = foreach ($Group in $Groups) {
$adGroup = Get-ADGroup $group -Properties Description -ErrorAction SilentlyContinue
if ($adGroup) {
$adGroup | Get-ADGroupMember -Server 'contoso.com' |
Select-Object SamAccountName,
#{Name = 'GroupName'; Expression = {$adGroup.Name}},
#{Name = 'Description'; Expression = {$adGroup.Description}}
}
else {
Write-Warning "Group '$group' could not be found.."
}
}
# now group the results on the GroupName property and
# return objects with joined SamAccountNames and Descriptions
$results | Group-Object GroupName | ForEach-Object {
[PsCustomObject]#{
SamAccountName = ($_.Group.SamAccountName | Sort-Object -Unique) -join ', '
GroupName = $_.Name
Description = ($_.Group.Description | Sort-Object -Unique) -join ', '
}
} | Export-Csv -Path 'C:\TEMP\GroupMemberShip.CSV' -NoTypeInformation
Although I don't understand why you would like to have duplicate items in your output, you can do this like below
$Groups = "Group1", "Group2", "Group3", "Group2", "Group3"
$results = foreach ($Group in $Groups) {
$adGroup = Get-ADGroup $group -Properties Description -ErrorAction SilentlyContinue
if ($adGroup) {
$adGroup | Get-ADGroupMember -Server 'contoso.com' |
Select-Object #{Name = 'SamAccountName'; Expression = {($_.SamAccountName | Sort-Object -Unique) -join ', '}},
#{Name = 'GroupName'; Expression = {$adGroup.Name}},
#{Name = 'Description'; Expression = {$adGroup.Description}} -ExcludeProperty SamAccountName
}
else {
Write-Warning "Group '$group' could not be found.."
}
}
$results | Sort-Object GroupName | Export-Csv -Path 'C:\TEMP\GroupMemberShip.CSV' -NoTypeInformation
I have some code so far, but would like it to result in a table with multiple lines for users per group.
Currently, it creates a table like this:
Group
Users
abcgroup1
Alice
abcgroup1
Bob
abcgroup2
Bob
abcgroup2
Jason
abcgroup3
Eve
I would like it to instead create a table like this:
Group
Users
abcgroup1
AliceBob
abcgroup2
BobJason
abcgroup3
Eve
$Groups = get-adgroup -Filter 'name -like "*abc*"'
$Results = foreach( $Group in $Groups ){
Get-ADGroupMember -Identity $Group | foreach {
[pscustomobject]#{
Group = $Group.Name
Users = $_.Name
}
}
}
$Results
$Results | Export-Csv C:\abc_search.txt -NoTypeInformation
You can use -join operator concatenating by CRLF `r`n. This will result in a multiline string:
$Groups = Get-ADGroup -Filter "name -like '*abc*'"
$Results = foreach($Group in $Groups)
{
[pscustomobject]#{
Group = $Group.Name
Members = (Get-ADGroupMember -Identity $Group).Name -join "`r`n"
}
}
$Results | Format-Table -Wrap -Autosize
$Results | Export-Csv C:\abc_search.csv -NoTypeInformation
Note that I'm using -Wrap on Format-Table, needed to correctly display multiline strings on the console.
The other option you could use is Out-String thought that would also require the use of .TrimEnd() method to get rid of the trailing new line:
Members = ((Get-ADGroupMember -Identity $Group).Name | Out-String).TrimEnd()
So im trying to return a report that will list each user and each group they are in using -Filter "name-like 'BLAH'"
the user may be apart multiple "BLAH" groups but no more than 3. How can i get an output like?
Member | Group1 | Group2 | Group3
I tried the below but not quite what i need
$adgroups = Get-ADGroup -Filter "name -like '*BLAH*'" | sort name
$data = foreach ($adgroup in $adgroups) {
$members = $adgroup | get-adgroupmember |select name| sort name
foreach ($member in $members) {
[PSCustomObject]#{
Members = $member
Group = $adgroup.name
}
}
}
This is what i get when using #Adam Luniewski solution
Try this:
$adgroups = Get-ADGroup -Filter "name -like '*BLAH*'" | Sort-Object Name
$data = ForEach ($adgroup in $adgroups){
$adgroup | get-adgroupmember | Select-Object #{n='Members';e={$_}},#{n='Group';e={(Get-ADUser $_.SamAccountName -Properties MemberOf).MemberOf}}
}
Here Get-ADUser is used to retrieve user group memberships (first said #Olaf) then I used calculated properties to format the output.
This should work. Just watch out if you have StrictMode set in your script, it might throw an error if $usrgrp count is less than 3, then you'd have to modify this part.
# get a list of all users and groups in two columns
$dat = #(Get-ADGroup -Filter "name -like '*BLAH*'" -PipelineVariable group | Get-ADGroupMember | select #{n='UserName';e={$_.name}},#{n='GroupName';e={$group.name}})
# for each user in a list add group fields
$dat | select UserName -Unique | ForEach-Object {
$usrgrp = #($dat | where username -eq $_.UserName | sort GroupName);
[pscustomobject]#{
UserName=$_.Username;
Group1=$usrgrp[0].GroupName;
Group2=$usrgrp[1].GroupName;
Group3=$usrgrp[2].GroupName;
};
}
I want 1 list with all users there are member of 2 (both) identity.
I have used this, but it returns first all users in the first identity and then the next identity.
$groups = "SMSxxx", "Personalxxxx"
$results = foreach ($group in $groups) {
Get-ADGroupMember $group | select samaccountname, name, #{n='GroupName';e={$group}}, #{n='Description';e={(Get-ADGroup $group -Properties description).description}}
}
$results
$results | Export-csv C:\Temp\GroupMemberShip.txt -NoTypeInformation
Best regards,
Peter
You can continue with your current logic and use Group-Object to find users that exist in all groups.
$groups = "SMSxxx", "Personalxxxx"
$results = foreach ($group in $groups) {
$description = (Get-ADGroup $group -Properties description).description
Get-ADGroupMember $group | select SamAccountName,Name,#{n='GroupName';e={$group}}, #{n='Description';e={$description}}
}
$results | Group-Object SamAccountName |
Where Count -eq $groups.Count | Select -Expand Group |
Export-csv C:\Temp\GroupMemberShip.csv -NoTypeInformation
The code below is supposed to count and compare user and output the total count, but somehow the result is empty. What do I need to do to fix it?
$groups = $A_group, $B_Group
$gm = #()
foreach ($group in $groups) {
$gm += Get-ADGroupMember $group -Recursive |
`where {$_.objectclass -eq 'user'} |`
' select SamAccountName'
}
($gm.samaccountname | Select -Unique).Count
Write-Output total: ($gm.samaccountname | Select -Unique).Count
You can do this in a much more powershell-esque way.
$groups = $A_group, $B_Group
$uniqueMemberCount = $groups |
Get-ADGroupMember -Recursive |
Where-Object {$_.objectClass -ieq "user"} |
Select-Object -Unique |
Measure-Object |
Select-Object -ExpandProperty Count
Write-Output "Total: $uniqueMemberCount"
I think you want to count of the unique members of two groups:
$aGroup = #('a','b','c')
$bGroup = #('b','c','e','f')
(Compare-Object $aGroup $bGroup -IncludeEqual).count