As the title said. im looking for a way to list every user, with the group(s), they are in.
I'm aware of how you could use Get-AzureADGroupMember -ObjectId "groupidhere"
and then the output is all the users in that group. but how would you automate this? is this even possible to do with powershell?
after this ill be using this table to create a table in Hudu. i havent seen anyone do this with groups and users together though, so for all i know its not possible or supposed to be.
So the output i get here from $Users to also show some of the output from $Groups_Name
A table where i have all the info about a user, but also what groups they are in.
| Name | Email | Group |
so the output would be something like this:
DisplayName UserPrincipalName DisplayName
----------- ----------------- -----------
Name Nameson user#domain.com Group names
Name Nameson user#domain.com Group names
Name Nameson user#domain.com Group names
Name Nameson user#domain.com Group names
Name Nameson user#domain.com Group names
Name Nameson user#domain.com Group names
Name Nameson user#domain.com Group names
Name Nameson user#domain.com Group names
Script im working on (i know this is super messy)
# Table of all users
$Users = Get-AzureADUser -All:$true
# Table of all groups
$Groups = Get-AzureADGroup
# ALL users ObjectId
$Users_ObjectId = $Users | Select-Object ObjectId
# ALL Groups ObjectId
$Groups_ObjectId = $Groups | Select-Object ObjectId
#Group names - list
$Groups_Name = $Groups | Select-Object DisplayName
#User names - list
$Users_Name = $Users | Select-Object DisplayName
foreach ($i in $Users ) {
# If
if ($Groups -contains $Users_ObjectId) {
#print a table with desired formatting
#$Users $Groups_Name
}
}
Try using Get-AzureADUserMembership like this:
$users = Get-AzureADUser -All $true
$report = Foreach ($user in $users) {
$groups = $user | Get-AzureADUserMembership
# create output objects with username and groups:
Foreach ($group in $groups) {
[PSCustomObject][ordered]#{
UserDisplayName = $user.DisplayName
UserPrincipalName = $user.UserPrincipalName
GroupDisplayName = $group.DisplayName
}}}
# print a table with desired formatting
$report | ft
And the report looks like so:
UserDisplayName UserPrincipalName GroupDisplayName
--------------- ----------------- ----------------
John Smith j.smith#domain.com Marketing
John Smith j.smith#domain.com Marketing-VIPs
John Doe j.doe#domain.com Sales
John Doe j.doe#domain.com Management
Related
Problem & what i have now
The script
comments are in norwegian btw, if they look strange lol
Connect-AzureAD
#variabel
$Users = Get-AzureADUser -All:$true | where-object { $null -ne $_.AssignedLicenses.SkuId } | Sort-Object CompanyName, UserPrincipalName| Select-Object -Property CompanyName, DisplayName, UserPrincipalName, Department, Mobile, TelephoneNumber
#formatting
$userlistTable = $Users | Format-Table
$userlistHTML = $Users | ConvertTo-Html
#outputs
$userlistHTML > out.html # ut som HTML
$userlistTable > out.txt # ut som Tabell i .txt
$userlistTable # ut som Tabell i terminal
My output as it stands right now:
CompanyName DisplayName UserPrincipalName Department Mobile TelephoneNumber
----------- ----------- ----------------- ---------- ------ ---------------
Company inc Usser Name username#website.com Callsenter 12345678 87654321
What i would like. is a table that has all the info in the output of $Users to inclide the users "SkuPartNumber".
The field u get by running the command Get-AzureADSubscribedSku | Select -Property SkuPartNumber
I would also like to get the users "manager", that u get by running Get-AzureADUserManager.
that last command uses the users Object ID to find their manager.
And to be honest, im very lost on how to combine these commands into one table.
its not the end of the world as it is right now. i could of just have multiple tables but having to manually cross reference these takes some time.
Im really not sure why these things are split into different commands to be honest. i get that a license is via 365 and not azure. but it seems a little backwards that i cant see the licenses from the command showing me all the user information. when a user class in powershell DOES infact show the sku ID. its burried within AssignedLicenses from running the command:
Get-AzureADUser | where-object -property UserPrincipalName -eq "emailhere#domain.com" | FL
This will give you among other things, this info:
AssignedLicenses : {class AssignedLicense {
DisabledPlans: System.Collections.Generic.List`1[System.String]
SkuId: 3b555118-da6a-4418-894f-7df1e2096870
}
conclusion
I know this was a long read. and if u made it this far im sorry.
any help with this would be amazing. This might be super easy to do, but im very far from a powershell wiz. thanks again for reading, and any help.
You can add additional properties to selected objects with calculated properties like Select #{label='name';expression={foo}}
$Users = Get-AzureADUser -All:$true
$Users | Where-Object { $_.AssignedLicenses.SkuId } |
Select-Object -Property UserPrincipalName, ## other properties here...
#{l='ManagerUPN';e={($_ | Get-AzureADUserManager).UserPrincipalName}},
#{l='AssignedSKUs';e={$_.AssignedLicenses.SkuId -join ';'}}
UserPrincipalName ManagerUPN AssignedSKUs
----------------- ---------- ------------
user#domain.com manager#domain.com 00000000-0000-0000-0000-000000000000;11111111-1111-1111-1111-111111111111
It can be slow to run Get-AzureADUserManager for every user, but that's how azure stores the relationships.
When you have a lot of users, it can be slightly faster to get the manager users first, then use Get-AzureADUserDirectReport -all $true to expand all the directreports in one call. The Microsoft.Graph.Users module is also a bit more lightweight
i have a lots of azure ad group with this format "AA - BB - xxx" where xxx can be anything.
i am trying to do a report on how many members in this azure ad group by display the azure ad group name and the number of its members.
i know to do 1 group is using this:
(Get-AzureADGroupMember -all 1 -ObjectId "xxxxx").count
how do i do lots of group with same group naming format to display its name and number of members?
thanks.
You need to first get all groups with such a name and then loop over the resulting list like:
$result = Get-AzureADGroup -Filter "startswith(DisplayName, 'AA - BB -')" -All $true | ForEach-Object {
[PsCustomObject]#{
Group = $_.DisplayName
MemberCount = #(Get-AzureADGroupMember -ObjectId $_.ObjectId -All $true).Count
}
}
# output on screen
$result | Format-Table -AutoSize
# save as Csv file
$result | Export-Csv -Path 'X:\PathTo\GroupMemberCount.csv' -NoTypeInformation
Apparently, the startswith() Filter on Get-AzureADGroup does not always return the wanted results (depending on the version of the OData language??).
In that case do
$result = Get-AzureADGroup | Where-Object {$_.DisplayName -like 'AA - BB -*'} | ForEach-Object {...}
I'm currently working on a script to manage Azure AD (as opposed to the console GUI) and am having issues at one particular part. I'm trying to do an 'add user to group' module, but with Add-AzureADGroupMember requiring the group ObjectId and not display name, it's not initially user-friendly.
Here's what I tried initially:
>> $UPN = "someuser#domain.com"
>> $Selected = "Group Display Name"
>> $Group = Get-AzureADGroup -Filter "DisplayName eq '$Selected'" -All $true | Select-Object -Property ObjectID
>> Add-AzureADGroupMember -ObjectID $Group -RefObjectID $UPN
The problem I have with this, is that $Group is returning '#{ObjectId=fba435cc-913c-46a0-9932-17c01733e143}' as opposed to '{fba435cc-913c-46a0-9932-17c01733e143}'
Is there a better way I can pass the group's ObjectID to a variable? I'd like for users to be able to select the display name and have the variable return the objectID.
To get just the value of a property, use ForEach-Object -MemberName instead of Select-Object -Property:
$Group = Get-AzureADGroup -Filter "DisplayName eq '$Selected'" -All $true | ForEach-Object -MemberName ObjectID
I'm having a problem when outputting my foreach loop to a csv file.
My Groups are set like this:
$Groups = "Group1", "Group2", "Group3"
My code is:
$results = ForEach ($Group in $Groups) {
$memberof = get-adgroup $Group | select -expandproperty distinguishedname
Write-Output $Group
Get-ADObject -Filter 'memberof -eq $memberof -and (ObjectClass -eq "user" -or ObjectClass -eq "contact")' -properties * | select name, Objectclass, mail
Write-Output ""
Write-Output ""
}
$results | Export-csv Contacts.csv -NoTypeInformation
The problem seems to be coming from the Write-Output lines but I have no clue why. When I run my code without writing to a csv file, I get the expected result, something like:
NameOfGroup1
name Objectclass mail
---- ----------- ----
User1 user User1#mail.com
User2 user User2#mail.com
#Spaces caused by write-output ""
NameOfGroup2
User1 user User1#mail.com
Contact1 contact Contact1#externalmail.com
Then again when I run my code to write to csv file and have the write-output $Group commented out I get a similar result.
But if I run my full code from the top of this page including the write-output $Group, it comes out like this:
I've figured out what these results represent but I haven't got clue why they do print out like this.
Eseentially the numbers refer to the length of the group name, so the first 17 would be a 17 character group name, and then the number of lines below is equal to the number of contacts and users that are inside that group. The 2 zeros at the end of each group are the length of the write-output "" lines.
What is causing this behavior?
The following code will closely output what you are attempting.
$results = ForEach ($Group in $Groups) {
$memberof = get-adgroup $Group | select -expandproperty distinguishedname
Get-ADUser -Filter "memberof -eq '$memberof' -and (ObjectClass -eq 'user' -or ObjectClass -eq 'contact')" -properties name,ObjectClass,Mail | Select-Object #{n='Group';e={$Group}},name, Objectclass, mail
[pscustomobject]"" | Select-Object Group,Name,ObjectClass,Mail
[pscustomobject]"" | Select-Object Group,Name,ObjectClass,Mail
}
$results | Export-csv Contacts.csv -NoTypeInformation
Explanation:
Export-Csv converts an object or array of objects with properties into a CSV file. You can see the same result in the console with ConvertTo-Csv. Properties are converted into columns and property values are placed under their associated columns. When you output a string as in Write-Output $Group, it has a property of Length. To fix this, you need to add $Group as a calculated property in your Select-Object. If you want to do blank lines in your CSV, then you should output another object with all of the property values as ''.
When you mix objects in your PowerShell outputs, you can see unexpected results. Your Get-ADObject outputs a custom object. Your Write-Output lines output a string. Those two object types do not share properties. So you only see the properties for the first object in your array, which is a string. If you put all of the Write-Output statements at the end of your loop, you will see more properties in your CSV. See below for an example that just by reversing the order of processed objects, you get a different result.
$str = "string"
$obj = [pscustomobject]#{property1 = "value1"; property2 = "value2"}
$str,$obj | convertto-csv -notype
"Length"
"6"
$obj,$str | convertto-csv -notype
"property1","property2"
"value1","value2"
,
Notice the properties available to the custom object $obj and the string $str.
$obj | get-member -Type Properties
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
property1 NoteProperty string property1=value1
property2 NoteProperty string property2=value2
$str | get-member -Type Properties
TypeName: System.String
Name MemberType Definition
---- ---------- ----------
Length Property int Length {get;}
I am making a script to query active directory via powershell and pull all computers that contain a username in the description field, then filter that list with only computers last logged in the past 14 days.
This is what I have so far:
$queryAD = Get-ADComputer -SearchBase 'OU=West Division,DC=cable,DC=comcast,DC=com' -Properties Name, Description -Filter {(Name -like "WA*") -and (Description -like $wildCard)} | Select-Object Name, Description
$lastLogon = $queryAD | Select-Object -ExpandProperty Description | %{$_.replace(("$NTname" + ";"),"").split(";")[0]} | %{get-date $_ -format d}
I'd like to add the list generated from $lastLogon to $queryAD, right now $queryAD is returning two columns with headers Name and Description. I need a third header added called Last Logon Date and contain the list in $lastLogon. Please advise.
You could assign the values to an array of objects to make your output cleaner (if this method is providing you the data you want) like so:
$queryAD = Get-ADComputer -SearchBase 'OU=West Division,DC=cable,DC=comcast,DC=com' -Properties Name, Description -Filter {(Name -like "WA*") -and (Description -like $wildCard)} | Select-Object Name, Description
$computer_list = #()
foreach($computer in $queryAD) {
$computer_info = New-Object PSObject -Property #{
Name = $computer.Name
Description = $computer.Description
LastLogonDate = $computer | Select-Object -ExpandProperty Description | %{$_.replace(("$NTname" + ";"),"").split(";")[0]} | %{get-date $_ -format d}
}
$computer_list += $computer_info
}
in which case $computer_list will contain all of the info you're gathering in tidy objects.
...but this method seems overcomplicated. Look into this blog entry by Matt Vogt for a better way to query for old machines in AD.