We have Group A and B and nested group in Group B.
John is member to Group A and is in Australia 1 OU.
Chris is member to Group B and is in Australia 2 OU.
May is member to Group A and B and is in Australia 1 OU.
Ken is member of Group A and is in China OU.
Australia 1 and Australia 2 are a subOU of Australia.
I need to find the unique user in both A and B group and need PowerShell to shown result as below.
OU User Count in A and B Group
Australia 1 2
Australia 2 1
Other 1
I am trying to export the COUNT but somehow the sum isn't correct. What should be change to get it right?
$Group2 = $groupA, $GroupB
$Group2 |
ForEach-Object { $gm += Get-ADGroupMember -Identity "$_" -Recursive } |
Where-Object { $_.objectClass -ieq "User" } |
Select-Object -Unique |
Get-ADUser -Properties canonicalName |
Select-Object #{Name='container';Expression={$_.canonicalname | Split-Path -Parent}} |
Group-Object container |
Select Count |
Format-Table -Auto
$gm.Count + "," | Out-File $log -Append
The code you posted can't possibly work, because your ForEach-Object loop appends to a variable without writing anything to the pipeline, so the entire pipeline after that initial loop doesn't do anything. At all.
Also, $gm.Count + "," should produce an error, because PowerShell would try to convert the string "," to an integer to match the type of the first operand. And fail. You'd need to cast the first operand to a string to make + work as a concatenation operator. But even then you wouldn't get the desired result, because $gm contains all group members irrespective of their OU.
To make your code work remove the ForEach-Object loop and the $gm =, and select both the name and the count of the grouped container names.
$Group2 |
ForEach-Object { $gm += Get-ADGroupMember -Identity "$_" -Recursive } |
Where-Object { $_.objectClass -ieq "User" } |
Select-Object -Unique |
Get-ADUser -Properties canonicalName |
Select-Object #{Name='container';Expression={$_.canonicalname | Split-Path -Parent}} |
Group-Object container |
Select Name, Count |
Format-Table -Auto
If you want just the trailing part of the container name change the expression
$_.canonicalname | Split-Path -Parent
to
$_.canonicalname | Split-Path -Parent | Split-Path -Leaf
If you want the tabular output written to a file add
| Out-String | Out-File $log
after the Format-Table statement, or replace Format-Table -Auto with Export-Csv $log -NoType if you want the result as a CSV.
Here is what I have come up with. Hopefully this gets you to the answer. I have used some extra variables to break up your piping.
I have also added in the PowerShell I used to setup the OU, User and Group structure. I used Group1 and Group2 instead of GroupA and GroupB. That was an error on my part.
I created my users as inetOrgPerson so in where-object, I'm using that for -ieq. You will need to change that to User.
#Environment setup
New-ADOrganizationalUnit -Name Country -Path "DC=TIMHAINTZ,DC=COM"
New-ADOrganizationalUnit -Name Australia -Path "OU=Country,DC=TIMHAINTZ,DC=COM"
New-ADOrganizationalUnit -Name Australia1 -Path "OU=Australia,OU=Country,DC=TIMHAINTZ,DC=COM"
New-ADOrganizationalUnit -Name Australia2 -Path "OU=Australia,OU=Country,DC=TIMHAINTZ,DC=COM"
New-ADOrganizationalUnit -Name China -Path "OU=Country,DC=TIMHAINTZ,DC=COM"
New-ADUser John -Type iNetOrgPerson -Path "OU=Australia1,OU=Australia,OU=Country,DC=timhaintz,DC=com"
New-ADUser Chris -Type iNetOrgPerson -Path "OU=Australia2,OU=Australia,OU=Country,DC=timhaintz,DC=com"
New-ADUser May -Type iNetOrgPerson -Path "OU=Australia1,OU=Australia,OU=Country,DC=timhaintz,DC=com"
New-ADUser Ken -Type iNetOrgPerson -Path "OU=China,OU=Country,DC=timhaintz,DC=com"
New-ADOrganizationalUnit -Name Groups -Path "DC=TIMHAINTZ,DC=COM"
New-ADGroup -Name "Group1" -SamAccountName Group1 -GroupCategory Security -GroupScope Global -DisplayName "Group1" -Path "OU=Groups,DC=TimHaintz,DC=com"
New-ADGroup -Name "Group2" -SamAccountName Group2 -GroupCategory Security -GroupScope Global -DisplayName "Group2" -Path "OU=Groups,DC=TimHaintz,DC=com"
Add-ADGroupMember Group1 John
Add-ADGroupMember Group2 Chris
Add-ADGroupMember Group1 May
Add-ADGroupMember Group2 May
Add-ADGroupMember Group1 Ken
#Iteration through groups
$group2 = 'CN=Group1,OU=Groups,DC=timhaintz,DC=com','CN=Group2,OU=Groups,DC=timhaintz,DC=com'
$users = foreach($group in $group2)
{
Get-ADGroupMember -Identity $group -Recursive | Where-Object {$_.objectClass -ieq "inetOrgPerson"}
}
$uniqueusers = $Users | Select-Object -Unique
From here, you have all $users and $uniqueusers. If you do:
$users.count
$uniqueusers.count
You will see they have a different number.
You can then use the rest of your logic to get the counts and output as you would like.
For example:
$uniqueusers | `
get-aduser -Properties canonicalname | `
Select-Object #{Name='container';Expression={$_.canonicalname | split-path -parent}} | `
Group-Object container | `
Select-Object #{Name='OU';Expression={($_.name).Split("\")[-1]}},Count | `
Format-Table -AutoSize
Outputs the below:
OU Count
-- -----
Australia1 2
China 1
Australia2 1
You can use $users and pipe that into get-aduser etc. also.
Hope this helps.
Thanks, Tim.
Related
i need a script please to export users in office 365 and the groups they are part of and not the other way around. can anyone help please. all answers i found were to export distribution groups and their members.
i tried using the below but i dont know how to select group names.
get-mailbox | ? {$_.PrimarySMTPAddress -like "*domain.com"} | Select DisplayName,Alias,PrimarySMTPAddress'
and i tried this too
get-mailbox | ? {$_.PrimarySMTPAddress -like "*domain.com"} | Sort Name | % { $MbxDirData = $_ ; Get-MailboxStatistics $_ } | Select DisplayName, #{E={ $MbxDirData.Alias };L='Alias'}, #{E={ $MbxDirData.PrimarySMTPAddress };L='PrimarySMTPAddress'}, #{E={ $_.TotalItemSize.Value + $_.TotalDeletedItemSize.Value };L="TotalMailboxSize"}
any help is appreciated.
This is untested, but I think you can use cmdlets Get-User and then Get-Group to retrieve the groups a user is a member of like this:
Get-Mailbox | Where-Object {$_.PrimarySMTPAddress -like "*domain.com"} | ForEach-Object {
$user = Get-User -Identity $_.DistinguishedName
$groups = Get-Group | Where-Object {$_.Members -contains $User}
$_ | Select-Object DisplayName, Alias, PrimarySMTPAddress,
#{Name = 'Groups' ; Expression = {$groups.Name -join '; '}}
} | Export-Csv -Path 'X:\O365UserGroups.csv' -NoTypeInformation
The above concatenates the groups with a semi-colon in one single field of the CSV, but if you would rather have output where there is one line for each group, you can do:
Get-Mailbox | Where-Object {$_.PrimarySMTPAddress -like "*domain.com"} | ForEach-Object {
$user = Get-User -Identity $_.DistinguishedName
$groups = Get-Group | Where-Object {$_.Members -contains $User}
# output a data row for each group in the collection
foreach ($group in $groups) {
$_ | Select-Object DisplayName, Alias, PrimarySMTPAddress,
#{Name = 'Groups' ; Expression = {$group.Name}}
}
} | Export-Csv -Path 'X:\O365UserGroups.csv' -NoTypeInformation
We can list all the office 365 groups by using the PowerShell cmdlet Get-UnifiedGroup and its group members by Get-UnifiedGroupLinks cmdlet .
You can use the below PowerShell script ,which will Export All Office 365 Group Members to csv. We have tested this in our local environment which is working fine.
$Groups = Get-UnifiedGroup -ResultSize Unlimited
$Groups | ForEach-Object {
$group = $_
Get-UnifiedGroupLinks -Identity $group.Name -LinkType Members -ResultSize Unlimited | ForEach-Object {
New-Object -TypeName PSObject -Property #{
Group = $group.DisplayName
Member = $_.Name
EmailAddress = $_.PrimarySMTPAddress
RecipientType= $_.RecipientType
}}} | Export-CSV "C:\Office365GroupMembers.csv" -NoTypeInformation -Encoding UTF8
Here is the sample output screenshot for reference :
Note:
Get-UnifiedGroup cmdlet is available only in the cloud-based service.
For more Information you refer this blog post & also if you faces any issues while executing Get-unifiedGroup cmdlet you refer this .
I'm trying to export AD user list along with the group they are member of, exported csv format should be like
Group A User1_name
Group A User2_name
Group B User3_name
Group C User4_name
Group C User5_name
I have tried
$ErrorActionPreference = "SilentlyContinue"
Get-Content R:\PHRBI-R\ADGroup_list.csv | Where{$_ -ne $null -and $_.trim() -ne ""} |
foreach{
$Group = $_
Write-Host "$Group"
Get-ADGroup -Identity $Group -Properties members |
Select-Object -ExpandProperty members |
Get-ADUser -Properties samaccountname, enabled |
Select samaccountname, name, Enabled
}
But it doesn't gave the template I'm looking for and also new group keep adding so can't list groups manually in any file and export the required details.
The below should get you going, I tried to make it logical to follow. This can, of course, be cleaned up and optimized.
# Create csv
New-Item "Some\Path\To\CSV" -ItemType File -force
# Add header row
Add-Content -Path "Some\Path\To\CSV" -Value 'Group Name, NUID, Name, Enabled'
# Loop through each AD group
Get-ADGroup -Filter {Name -like 'ABC*'} | Foreach-Object {
# Keep the group object so we can use it later
$Group = $_
# loop through each group member
$Group.members | Foreach-Object {
$User = Get-ADUser -identity $_ -Properties samaccountname, name, enabled
Add-Content -Path "Some\Path\To\CSV" -Value "$($Group.Name),$($User.samaccountname),$($User.name),$($User.Enabled)"
}
}
Note that If there are nested groups (i.e. groups within groups) then the Get-AdUser cmdlet will error.
Import-Module ActiveDirectory
New-Item R:\PHRBI-R\Nishant\AD_List\user_list.csv -ItemType File -force
Add-Content -Path R:\PHRBI-R\Nishant\AD_List\user_list.csv -Value 'Group Name, NUID, Name,Enabled'
$Groups=Get-ADGroup -Filter {Name -like 'ABC*'}
foreach($Group in $Groups)
{
$Details=Get-ADGroup -Identity $Group.Name -Properties members |
Select-Object -ExpandProperty members |
Get-ADUser -Properties samaccountname, enabled, name | Select samaccountname, name, Enabled
foreach($Detail in $Details)
{
Add-Content -Path R:\PHRBI-R\Nishant\AD_List\user_list.csv -Value "$($Group.Name),$($Detail.samaccountname),$($Detail.name),$($Detail.Enabled)"
}}
Is there any way I can import a list of users, get their groups in AD and export the list?
Import-Csv C:\Users.csv |
% {Get-AdUser -filter "displayname -eq '$($_.username)'"} |
Get-ADprincipalGroupMembership |
Select samaccountname, name |
Export-csv -path C:\UserPermiss.csv -NoTypeInformation
File example:
username
Jon Jo
Steve Price
Alan Partridge
Cheers.
In PSv4+ you can leverage the -PipelineVariable / -pv common parameter to make the output of an earlier pipeline stage available to script blocks used in later pipeline stages:
Import-Csv C:\Users.csv |
ForEach-Object -pv user { Get-AdUser -filter "displayname -eq '$($_.username)'"} |
Get-ADprincipalGroupMembership |
Select-Object #{ n = 'samaccountname'; e = { $user.samaccountname } }, name |
Export-csv -path C:\UserPermiss.csv -NoTypeInformation
Using -pv user makes the AD user output by Get-AdUser available as variable $user in the Select-Object stage, where it is referenced in the script block of calculated property samaccountname, pairing the name of the AD user at hand with the name of each AD group they are a member of.
The resulting CSV file would look something like this:
"samaccountname","name"
"jjo","group1"
"jjo","group2"
"sprice","group1"
"sprice","group3"
"sprice","group4"
# ...
You could use the memberof property and then join the array of groups inside a calculated property.
Import-Csv C:\Users.csv |
ForEach-Object{
Get-AdUser -Filter "displayname -eq '$($_.username)'" -Properties memberof
} |
Select-Object samaccountname, name, #{n='memberof';e={$_.memberof -join ';'}} |
Export-Csv -Path C:\UserPermiss.csv -NoTypeInformation
I am trying to output all AD users calendar and contact permissions. I have tried adding an -or operator but as per the error screenshot it does not work. I am not sure if Get-MailboxFolderPermission can take more than one parameter.
This script does not run
$OU = OrganizationalUnit "OU=users,OU=test.com,OU=PIPE,OU=Hosting,DC=options,DC=com"
Get-Mailbox -OrganizationalUnit $OU -Filter * |
select -Expand alias |
Where-Object {Get-MailboxFolderPermission -Identity $($_ + ':\Calendar') -or $($_ + ':\Contacts')} |
select Identity, FolderName, User, #{name="AccessRights";expression={[string]::Join(",",#($_.accessrights))}}, IsValid |
Sort-Object Identity |
Export-Csv C:\temp\calendarpemstest2.csv
This script runs fine just getting calendar permissions
$OU = OrganizationalUnit "OU=users,OU=test.com,OU=PIPE,OU=Hosting,DC=options,DC=com"
Get-Mailbox -OrganizationalUnit $OU -Filter *Â |
select -Expand alias |
ForEach-Object {Get-MailboxFolderPermission -Identity $($_ + ':\Calendar')} |
select Identity, FolderName, User, #{name="AccessRights";expression={[string]::Join(",",#($_.accessrights)) }}, IsValid |
Sort-Object Identity |
Export-Csv C:\temp\calendarpemstest2.csv
Powershell tries to parse the -or parameter for Get-MailboxFolderPermission, but Get-MailboxFolderPermission does not have an -or parameter.
One way to work around this problem is to pipe the same aliases object twice (once for Calendar and once for Contacts).
$OU=OrganizationalUnit "OU=users,OU=test.com,OU=PIPE,OU=Hosting,DC=options,DC=com"
$aliases = Get-Mailbox -OrganizationalUnit $OU -filter * | select -expand alias
$calendarPermissions = $aliases | ForEach-Object { Get-MailboxFolderPermission -identity $($_ + ':\Calendar' ) }
$contactsPermissions = $aliases | ForEach-Object { Get-MailboxFolderPermission -identity $($_ + ':\Contacts' ) }
# now merge both permissions and pipe to the rest of the code
$calendarPermissions + $contactsPermissions |
Select Identity, FolderName, User, #{name="AccessRights";expression={ [string]::join(",",#($_.accessrights)) }}, IsValid |
Sort-Object identity |
Export-Csv C:\temp\calendarpemstest2.csv
I am trying to create a powershell to audit new created accounts & groups and who created them. The objects are created by account operators, but they are not domain admins.
I think something like this:
$Last = (Get-Date).AddDays(-1);
Get-Acl | Get-ADUser -Filter {WhenCreated -ge $Last} | FL DistinguishedName, Path,owner
But this doesn't work yet.
This one liner will let you know about the changes after a certain date. There is a whenchanged property with which you can filter down the objects.
Get-ADObject -Filter 'whenchanged -gt $dte' | Group-Object objectclass
then you can use :
get-adgroup -filter * | sort name | select Name
Get-adgroupmember "Name"
or
Get-ADGroup -filter "GroupCategory -eq 'Security'" –properties Member |
Select Name,#{Name="Members";
Expression={($_.member | Measure-Object).count}},
GroupCategory,GroupScope,Distinguishedname |
Out-GridView -Title "Select one or more groups to export" -OutputMode Multiple |
foreach {
Write-Host "Exporting $($_.name)" -ForegroundColor cyan
#replace spaces in name with a dash
$name = $_.name -replace " ","-"
$file = Join-Path -path "C:\work" -ChildPath "$name.csv"
Get-ADGroupMember -identity $_.distinguishedname -Recursive |
Get-ADUser -Properties Title,Department |
Select Name,Title,Department,SamAccountName,DistinguishedName |
Export-CSV -Path $file -NoTypeInformation
Get-Item -Path $file
}