I want to compare all shared mailboxes in Exchange online with members in a Azure sec group and import the difference in the Azure sec group. I believe it fails somewhere in the last 3 rows. It is for a backup solution and I am not the creator of the code.
Get-EXORecipient -ResultSize unlimited -RecipientTypeDetails "SharedMailbox" | select PrimarySMTPAddress | Export-Csv "C:\Users\mnym\Downloads\Sharedmailboxes\sharedmailboxes.csv"
$GroupMembership = Get-AzureADGroupMember -ObjectId "group id" -top 10000 | Select-Object #{Name="PrimarySMTPAddress";Expression={$_.userprincipalname}} | Export-Csv "C:\Users\mnym\Downloads\Sharedmailboxes\Groupmembership.csv"
$File1 = Import-Csv -Path "C:\Users\mnym\Downloads\Sharedmailboxes\sharedmailboxes.csv"
$File2 = (Import-Csv -Path "C:\Users\mnym\Downloads\Sharedmailboxes\Groupmembership.csv").PrimarySMTPAddress
$File1 | where-object{$_.PrimarySMTPAddress -notin $File2} | Export-csv -path "C:\Users\mnym\Downloads\sharedmailboxes\difference.csv"
$Diff = Import-Csv -Path "C:\Users\mnym\Downloads\sharedmailboxes\difference.csv"
The file difference.csv is populated and formatted as
A
#TYPE Selected.System.Management.Automation.PSCustomObject
PrimarySmtpAddress
x#domain.com
$UserObjectId = Import-Csv -Path "C:\Users\mnym\Downloads\sharedmailboxes\difference.csv" | ForEach-Object {get-azureaduser -searchstring $_.PrimarySmtpAddress}
$Userobjectid | select objectid | export-csv -Path "C:\Users\mnym\Downloads\sharedmailboxes\userobjectid.csv"
The file userobjectid.csv is empty after above command :(
Import-Csv -Path "C:\Users\mnym\Downloads\sharedmailboxes\userobjectid.csv" | ForEach-Object {Add-AzureADGroupMember -ObjectId "group id" -Refobjectid $_.objectid}
I tried to import the difference.csv but I can't seam to get the Refobjectid to match the CSV, I get "Cannot bind argument to parameter 'RefObjectId' because it is null".
Don't use your file system as a variable registry - there's no need to write data to a CSV file only to read it straight back into memory :)
Your code could be as simple as:
# Define the target group id
$groupID = "group id"
# Start by creating a set of all email addresses that are already members of the security group
$securityGroupMembers = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
Get-AzureADGroupMember -ObjectId $groupID -Top 10000 |ForEach-Object {
[void]$securityGroupMembers.Add($_.PrimarySMTPAddress)
}
# Then fetch the shared mailbox and check if they're already members of the group
Get-EXORecipient -ResultSize unlimited -RecipientTypeDetails "SharedMailbox" |ForEach-Object {
if(-not $securityGroupMembers.Contains($_.PrimarySMTPAddress)){
# Add shared mailbox to group
Add-AzureADGroupMember -ObjectId $groupID -Refobjectid $_.ObjectId
}
}
Related
The end goal I'm after is I want to have a csv containing the owners of all AzureAD groups.
I'm not well versed in PS and I've been trying to crack it for a while now, with various different scripts each with their own method. Things that seem logical, and I think would work, don't.
Feel free to edit what I've got or write a new script entirely, but please explain what you have done so I can learn :)
The closest I've come to what I want is using the below. But the caveat is if there are multiple owners of the group, each owner is listed out on separate rows and so there is also duplicate group names. I would like to have the group name in one column then all the owners in the next, seperated by " ,".
I tried using -join on the final line but it returns blank results.
$array = #()
$Properties=#{}
$Properties.add("GroupDisplayName","1")
$Properties.add("OwnerDisplayName","2")
$groups = Get-AzureADGroup -All $true | Where-Object DisplayName -Like "*Guest*" | Sort-Object -Property DisplayName
Foreach($group in $groups){
$Owners = Get-AzureADGroupOwner -ObjectId $group.ObjectId -All $true
$Properties.GroupDisplayName=$group.DisplayName
if($Owners -ne $null){
# group has owner
Foreach($Owner in $Owners){
$Properties.OwnerDisplayName=$Owner.DisplayName
$obj=New-Object PSObject -Property $Properties
$array +=$obj
}
}
else{
#group has no owner
$Properties.OwnerDisplayName=$null
$obj=New-Object PSObject -Property $Properties
$array +=$obj
}
}
$array | export-csv -Path C:\Temp\test123.csv -NoTypeInformation -Encoding UTF8
Thanks in advance for your help, you will save me some hair...
EDIT
This is another route I've tried. It does return results I want if using one specific ObjectID but I can't get it to loop the bunch of ObjectIds from step 1 and run the command for each one.
#Connect to AzureAD
Connect-AzureAD
#Successfully returns groups with "Guest" in DisplayName
$GroupSearch = Get-AzureADGroup -All $true | Where-Object DisplayName -Like "*Guest*" | Select-Object ObjectId, DisplayName | Sort-Object -Property DisplayName
$groups = #($GroupSearch | Select-Object ObjectID)
#Now to loop ObjectIDs from STEP 1 to lookup command
$Result = foreach ($group in $groups){
Get-AzureADGroupOwner -ObjectId "$group" | Select-Object DisplayName
}
$Result | Export-Csv -Path "C:\Temp\AzureADgroupOwners.csv" -NoTypeInformation
#Disconnect from AzureAD
Disconnect-AzureAD
Figured it out with some help from other sources. Hopefully someone will find this helpful in future! This is how:
#Connect to AzureAD
Connect-AzureAD
$Properties=#{}
$matchingOwners=#()
$groups = Get-AzureADGroup -All $true | Where-Object DisplayName -Like "*Guest*"
Foreach($group in $groups) {
$Owners = Get-AzureADGroupOwner -ObjectId $group.ObjectId -All $true
$matchingGroup = $group.DisplayName
if ($null -ne $Owners) {
#group has owner
Foreach($Owner in $Owners) {
$matchingOwners+=$Owner.DisplayName
}
}
$joinedOwners = $matchingOwners -join ", "
$Properties.add($matchingGroup, $joinedOwners)
$joinedOwners=""
$matchingOwners=#()
}
$Properties.GetEnumerator() | Select-Object -Property Key,Value | Sort-Object -Property Key | export-csv -Path C:\Temp\test123.csv -NoTypeInformation -Encoding UTF8
#Disconnect from AzureAD
Disconnect-AzureAD
I tried to reproduce the same in my environment by using the below PowerShell script:
$array = #()
$Properties=#{}
$Properties.add("GroupDisplayName","1")
$Properties.add("OwnerObjectId","2")
$Properties.add("OwnerObjectType","3")
$Properties.add("OwnerUserType","4")
$Properties.add("OwnerUserPrincipalName","5")
$groups = Get-AzureADGroup -All $true
Foreach($group in $groups){
$Owners = Get-AzureADGroupOwner -ObjectId $group.ObjectId -All $true
ForEach ($Owner in $Owners){
$Properties.GroupDisplayName=$group.DisplayName
$Properties.OwnerObjectId=$Owner.ObjectId
$Properties.OwnerObjectType=$Owner.ObjectType
$Properties.OwnerUserType=$Owner.UserType
$Properties.OwnerUserPrincipalName=$Owner.UserPrincipalName
$obj=New-Object PSObject -Property $Properties
$array +=$obj
}
}
$array | export-csv -Path YourPath.csv -NoTypeInformation -Encoding UTF8
The above script got executed successfully as below:
The CSV file was exported with the Azure Ad Group and Group owner details like below:
Reference:
powershell - Export all Azure AD Groups and their owner to a csv file by Jim Xu
I want to create a powershell script that checks a users profile which security groups the user belongs to inside the active directory. Then I want to write it to a file.
I'm having trouble solving this problem.
Example of the expected output.
User1
Security Groups
Domain users
Domain admins...
User2
Security Groups
Domain users
Enterprise admins
New-Item "$home\Desktop\GroupsMembers-list $(get-date -f dd-MM-yyyy).txt"
$users = #("User1", "User2", "User3", "User4")
foreach ($user in $users){
Get-ADPrincipalGroupMembership $user | sort name | select name | Out-File "$home\Desktop\GroupsMembers-list $(get-date -f dd-MM-yyyy).txt"
}
I imagine you could get a bit more creative with it but this could definitely work for you:
$users = #("user1","user2")
foreach ($user in $users){
$groups = Get-ADPrincipalGroupMembership $user | Where-Object {$_.GroupCategory -eq "Security"} | Sort-Object Name | Select-Object -ExpandProperty Name
Add-Content -Path C:\path\to\file.txt -Value #"
$user
Security Groups
----------------------------
"#
foreach ($group in $groups){
Add-Content -Path C:\path\to\file.txt -Value $group
}
}
This is what the output looks like:
user1
Security Groups
----------------------------
Administrators
Domain Admins
user2
Security Groups
----------------------------
Administrators
Domain Admins
I think it will be something like this:
$users = #("User1", "User2", "User3", "User4")
$file= "$home\Desktop\GroupsMembers-list $(get-date -f dd-MM-yyyy).txt"
""| Out-File $file; #Clear content of file
foreach ($user in $users){ ""| Out-File -Append $file; #Add a new line
"$User is in Security groups:"| Out-File -Append $file; # making a Title
"---------------------------------"| Out-File -Append $file; # making a Title
Get-ADPrincipalGroupMembership $user | sort Name | ft -HideTableHeaders Name | Out-File -Append $file #Writing data
}
The txt file will be replaced each time, when running script.
I need to export the following to a csv or excel file
-Distribution Group (PrimarySmtpAddress)
-Distribution Group members and each primarysmtpaddress
I tried adding
Group email: $($group) | PrimarySmtpAddress
in the code below but it does not add it.
#This is what works but is missing
$groups = Get-DistributionGroup -ResultSize Unlimited | Select -ExpandProperty name
ForEach ($group in $groups)
{
"Group Name: $($group)`nGroup Members:`n"
Get-DistributionGroupMember $group |ft name,alias,primarysmtpaddress
}
I am missing the Distribution group primary smtp address?
As Lee_Daily commented, you are stripping out all properties except the Name by doing Select -ExpandProperty name. Next, if you want to export to a CSV file, DO NOT USE Format-Table (ft), because that is only to format the result to the console.
What you should do is create an array of objects and pipe that to the Export-Csv cmdlet, like in the below (untested) code:
$outputFile = '<PATH AND FILENAME FOR THE EXPORTED CSV FILE>'
Get-DistributionGroup -ResultSize Unlimited | ForEach-Object {
# The Identity parameter for Get-DistributionGroupMember specifies the distribution group
# or mail-enabled security group. You can use any value that uniquely identifies the group.
# The cmdlet also accepts the Identity parameter as pipeline input, so
# $_ | Get-DistributionGroupMember will also work.
$Members = Get-DistributionGroupMember -Identity $($_.PrimarySmtpAddress)
foreach ($member in $Members) {
[PSCustomObject]#{
GroupName = $_.DisplayName
GroupAlias = $_.Alias
GroupEmail = $_.PrimarySMTPAddress
MemberName = $member.DisplayName
MemberEmail = $member.PrimarySMTPAddress
# Maybe also add RecipientType to distinguish between users and groups?
# MemberType = $member.RecipientType
}
}
} | Export-Csv -Path $outputFile -NoTypeInformation
Hope that helps
I need help in the powershell script. I am looking to get Azure AD, group membership details for multiple groups which are in the CSV file.
The format, I am looking to get is:
Group Name :SG-Test-Users
Members: xyz, abc etc
Output needed in this format
Please help
I tried, below script but it is not giving an output in the format I am looking for.
Import-Csv -Path "C:\temp\testgroup.csv" | ForEach-Object {Get-AzureADGroupMember -ObjectId $_.name | select displayname,userprincipalname} | Export-Csv -Path "c:\temp\outputfile1.csv" -NoTypeInformation
Thanks,
Try the command below, it works fine on my side. Note it will append data to the file instead of overwriting.
$csv = Import-Csv "C:\Users\joyw\Desktop\testgroup.csv"
foreach ($line in $csv){
$groupname = $line.GroupName
$objectid = (Get-AzureADGroup | Where-Object {$_.DisplayName -eq $groupname}).ObjectId
Get-AzureADGroupMember -ObjectId $objectid | select DisplayName,UserPrincipalName | Export-Csv -Path "C:\Users\joyw\Desktop\outputfile1.csv" -NoTypeInformation -Append
}
My test file:
testgroup.csv
outputfile1.csv
I'm new to this, but here's my take
try below (modify output as required) and then save the console output to file and massage as required in excel
cheers
$gg=Get-AzureADGroup -top 200
ForEach ($g in $gg){
$a = Get-AzureADGroup -ObjectId $g.ObjectId
$b = Get-AzureADGroupMember -ObjectId $g.ObjectId -All $true
ForEach ($c in $b){
Write-host $a.DisplayName ";" $c.ObjectId ";" $c.ObjectType $c.UserType ";" $c.UserPrincipalName
}
}
$ResourceAuditArray = #()
ForEach ($g in Get-AzureADGroup -SearchString "<first word of groups e.g. DFC, ADF, DAS>"){
$ResourceAuditArray += Get-AzureADGroupMember -ObjectId $g.ObjectId -All $true | Select-Object ObjectId, ObjectType, UserType, UserPrincipalName, #{n="DisplayName"; e={$g.DisplayName}}
}
$ResourceAuditArray | Export-Csv "<AAD Users list>.Csv"
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.