Export azure ad groups membership via powershell - powershell

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"

Related

Import difference in CSV to Azure sec group

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
}
}

Can't get multiple results

I have the following PowerShell code that should run and fetch the last login for the list of UPNs:
$UPNList = get-content c:\temp\users.txt
foreach ($User in $UPNList)
{
Start-Sleep -Milliseconds 1000
$result = Get-AzureADAuditSignInLogs -Filter "UserPrincipalName eq '$User'" -Top 1 | Select-Object CreatedDateTime, UserPrincipalName, IsInteractive, AppDisplayName, IpAddress, TokenIssuerType, #{Name = 'DeviceOS'; Expression = {$_.DeviceDetail.OperatingSystem}}
$result | Export-Csv -Path 'c:\temp\results.txt' -NoTypeInformation -Append
}
However, the "results.txt" file is empty when there is more than one (1) user in the input file.
If there's a single user, results are correctly returned.
How can I ensure the results are provided for all users?
Also, if the user did not log in at all, for example completely new account, how do I ensure that the UPN is still populated in the "results" file, but the rest of the details are empty?
Thank you.
Try not to write out to the output file in every iteration, but have PowerShell collect the objects you output inside the loop and then create the csv file:
# get the list of UPN's and skip empty lines
$UPNList = Get-Content -Path 'c:\test\users.txt' | Where-Object { $_ -match '\S' }
# loop through the list and collect the data in variable $result
$result = foreach ($User in $UPNList) {
# output the wanted data
Get-AzureADAuditSignInLogs -Filter "UserPrincipalName eq '$User'" -Top 1 |
Select-Object CreatedDateTime, UserPrincipalName, IsInteractive, AppDisplayName, IpAddress,
TokenIssuerType, #{Name = 'DeviceOS'; Expression = {$_.DeviceDetail.OperatingSystem}}
}
# now write the collected data to CSV file in one go
$result | Export-Csv -Path 'c:\test\results.csv' -NoTypeInformation
You may also try to do the filtering afterwards like below (could be slower than above code though)
# get the list of UPN's and skip empty lines
$UPNList = Get-Content -Path 'c:\test\users.txt' | Where-Object { $_ -match '\S' }
# filter with Where-Object afterwards and pipe through to the Export-Csv cmdlet
Get-AzureADAuditSignInLogs -All $true | Where-Object { $UPNList -contains $_.UserPrincipalName } |
Select-Object CreatedDateTime, UserPrincipalName, IsInteractive, AppDisplayName, IpAddress,
TokenIssuerType, #{Name = 'DeviceOS'; Expression = {$_.DeviceDetail.OperatingSystem}} |
Export-Csv -Path 'c:\test\results.csv' -NoTypeInformation
I tried to reproduce the same in my environment and got below results:
Initially, I checked with one user in users.txt file like this:
I ran the same script as you and got the response like below:
$UPNList = get-content c:\test\users.txt
foreach ($User in $UPNList)
{
Start-Sleep -Milliseconds 1000
$result = Get-AzureADAuditSignInLogs -Filter "UserPrincipalName eq '$User'" -Top 1 | Select-Object CreatedDateTime, UserPrincipalName, IsInteractive, AppDisplayName, IpAddress, TokenIssuerType, #{Name = 'DeviceOS'; Expression = {$_.DeviceDetail.OperatingSystem}}
$result | Export-Csv -Path 'c:\test\results.txt' -NoTypeInformation -Append
}
Output:
In results.txt file, I got the details of that user successfully like below:
Now I tried including more UPNs in users.txt file like below:
When I ran the same script, the results.txt file is empty as below:
Please note that, the response in results.txt file differs based on how you are giving input in users.txt file.
I tried changing the format of giving input in users.txt file like below:
Now, when I ran the script again, I got the details of those users successfully like below:
So, make sure to give input for users.txt file in correct format.
If the user did not log in at all, it's not possible to get their details using Get-AzureADAuditSignInLogs command.
Normally, you can make use of Get-AzureADUser command to get any user details.

Export AzureAD group owners to CSV

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

Importing CSV splits certain lines

I have a fairly simple script that needs to check around 20,000 AD Groups for their membership count. That all works fine, I can take the list of groups run it through the script and for the most entries it works fine. However I was getting some errors that I couldn't figure out and hopefully someone here can point me in the right direction.
I am using the DN of the object to query AD and for around 10% it fails, but when I copy the DN from the file, paste it into a command window and run the command manually it works fine. Some more checking and it seems that when I read an offending line into my variable there is a line break in the middle for some reason.
When looking at the value of the variable I get the following:
Working Example - "CN=ABC, OU=Location, OU=Distribution Lists, DC=Domain, DC=COM"
Error Example - "CN=ABC, OU=Location, OU=Distribution
Lists, DC=Domain, DC=COM"
It seems to insert a return in-between Distribution and Lists on certain entries in the file. I have tried deleting the character in-between and replacing it with a space but I get the same result.
Could it be the length? I am still looking for a common factor but any suggestions would be great.
Thanks
Updated with requested content.
$Groups = Import-Csv C:\Temp\DLName.csv
write-host ($Groups).Count
$i=1
foreach ($Group in $Groups)
{
$GroupInfo = Get-ADGroupMembersRecursive -Groups $Group.Name
$MembersCount = ($GroupInfo | Measure-Object).Count
$MembersList = $GroupInfo | Select Name -ExcludeProperty Name
$FriendlyName = Get-ADGroup -Identity $Group.Name
$Export = $FriendlyName.Name + ", " + $MembersCount
$Export | Out-File C:\Temp\DLMembers.csv -Append
Write-host $FriendlyName "," $MembersCount
$i
$i++
}
Entry 1 and 3 work 2 doesn't, but the formatting here seems to have wrapped the entries.
Name
"CN=Company - DL Name1,OU=Country1 Distribution Lists,OU=Europe,OU=Acc,DC=Domain,DC=Domain,DC=com"
"CN=Company - DL Name2,OU=Country2 Distribution Lists,OU=Europe,OU=Acc,DC=Domain,DC=Domain,DC=com"
"CN=Company - DL Name3,OU=Country3 Distribution Lists,OU=America,OU=Acc,DC=Domain,DC=Domain,DC=com"
Top pic is the failure second pic works.
List Creation:
$SearchScope = "OU=OUName,DC=Domain,DC=Domain,DC=com"
$SearchFilter = {GroupCategory -eq 'Distribution'}
$Groups = Get-ADGroup -SearchBase $SearchScope -Filter
$SearchFilter | Sort-Object Name
foreach ($Group in $Groups)
{
$Group.DistinguishedName | Select Name -ExpandProperty Name
$Group.DistinguishedName | Out-File C:\Temp\DLName.csv -Append
}
Do not use a self-combined comma separated string and Out-File to create CSV files, because that will get you into trouble when fields happen to contain the delimiter character like in this case the comma (which will lead to mis-aligned data).
Your List Creation code should be like this:
$SearchBase = "OU=OUName,DC=Domain,DC=Domain,DC=com"
$SearchFilter = "GroupCategory -eq 'Distribution'"
Get-ADGroup -SearchBase $SearchBase -Filter $SearchFilter |
Sort-Object Name | Select-Object Name, DistinguishedName |
Export-Csv -Path 'C:\Temp\DLName.csv' -NoTypeInformation
Then you can use that csv later to do:
$Groups = Import-Csv -Path 'C:\Temp\DLName.csv'
Write-Host $Groups.Count
$result = foreach ($Group in $Groups) {
$GroupInfo = Get-ADGroupMember -Identity $Group.DistinguishedName -Recursive
# unnecessary.. $MembersCount = ($GroupInfo | Measure-Object).Count
# unused.. $MembersList = $GroupInfo.Name
# unnecessary.. $FriendlyName = Get-ADGroup -Identity $Group.Name
# output an object with the wanted properties
[PsCustomObject]#{
GroupName = $Group.Name
MemberCount = #($GroupInfo).Count # #() in case there is only one member in the group
}
}
# show on screen
$result | Format-Table -AutoSize
# output to CSV file
$result | Export-Csv -Path 'C:\Temp\DLMembers.csv' -NoTypeInformation
As you can see, I'm not using your custom function Get-ADGroupMembersRecursive because I have no idea what that outputs.. Also, there is no need for that because you can use the Get-ADGroupMember cmdlet with the -Recursive switch added

Adding group name row to group member output

I'm trying to export some group memberships all to one CSV file so I can find users who are not in our domain. Everything works great, but when all the outputs get appended I can't see what group each entry is in. Here's what I have now.
$Groups = import-csv "C:\users\USER\desktop\secgroupinput2.csv"
foreach($item in $Groups)
{
Get-ADGroupMember -Server "SERVERDC" -Identity $item.directoryname | export-csv "C:\users\USER\desktop\realexport.csv" -Append
}
How can I add a row between appends with the group name, likely from the import?
Thanks!
I did something similar in the past. Hope this code helps :
Function ADGroupMembers
{
$group = get-content C:\Pshell\PM\group.txt
$i =25
do{
if (get-QADgroup $group[$i] -Empty 0)
{write-output ''; Write-Output -inputobject "The $($group[$i]) group members :"; write-output '';
get-QADGroupMember $group[$i] -IncludeAllProperties | Format-Table -AutoSize DisplayName, Type, Office, Company, Department, Title, WhenCreated | Out-String -Width 4096;
write-output ''}
else {Write-Output -inputobject "*** Member not found in the $($group[$i]) group!"; write-output ''}
$i +=1}
while ($i -ne $group.length)
}
ADGroupMembers | out-File 'c:\Pshell\PM\groupmemberdetails.txt'