Creating and Configuring Entra Extension Attributes
Microsoft Exchange spoiled us - mail-enabled objects always had a set of custom attributes ready to use out of the box. Entra ID is less generous, you have to extend the schema yourself from scratch. 1. Create an Application Registration Application Registration works as the namespace for extension attributes. 1 New-MgApplication -DisplayName "Extension Attribute Sample Application" -SignInAudience AzureADMyOrg 2. Create an Extension Property Now we create an attribute itself. 1 New-MgApplicationExtensionProperty -ApplicationId <Id> -Name "Att1" -DataType String -TargetObjects @("Group") 3. Create a Service Principal Without a Service Principal, the extension attributes are defined but cannot be used - the application exists only as a ‘definition’, not as an active entity in your tenant. ...
How to Get SharePoint Item ID Using Microsoft Graph API
Introduction When working with Microsoft Graph API to automate SharePoint operations (like writing script outputs, saving reports, updating Excel files), we can’t just use file paths. We need to work with unique identifiers - specifically - the file ID. This guide walks you through the process of finding a SharePoint item ID by navigating the site hierarchy using Graph API Explorer. The Goal In this example, we’ll find the ID of an Excel file located deep within a SharePoint site structure: ...
Recursive Member Count for Distribution Lists
Get-GroupMemberReport PowerShell script to audit Distribution Lists and Microsoft 365 Groups membership using Microsoft Graph API. Returns transitive (recursive) member counts - including all nested group members. Why? Get-DistributionGroupMember only returns direct members, not nested Exchange Online cmdlets have pagination timeouts on large tenants Graph API’s Get-MgGroupTransitiveMemberCount solves both problems Requirements PowerShell 5.1+ or PowerShell 7+ Microsoft Graph PowerShell SDK Permissions: Group.Read.All, Directory.Read.All Usage 1 2 3 4 5 6 7 8 9 10 11 # Distribution Lists only .\Get-GroupMemberReport.ps1 -DL # Microsoft 365 Groups only .\Get-GroupMemberReport.ps1 -M365 # Both types .\Get-GroupMemberReport.ps1 -All # Test mode - first ~100 DLs or M365 .\Get-GroupMemberReport.ps1 -DL/M365 -TestLimit 100 Output CSV file with columns: ...
When PowerAutomate Can't Regex - Let AI Do The Parsing
Problem I need to monitor my mailbox for certain ticket emails and extract specific data from them. Classic automation stuff. The catch? Power Automate doesn’t support regex. The Workaround Power Automate has this “Run a prompt” action that lets you use GPT to process text. The idea is simple: Get the email Feed it to AI with instructions Get structured JSON back Do whatever you want with clean data General flow description The flow has the following steps: ...
Assign licenses in bulk via Graph API
Add: 1 Get-Content <file path> | foreach {Set-MgUserLicense -UserId $_ -AddLicenses @{SkuID = '2ced8a00...'} -RemoveLicenses @()} Remove: 1 Get-Content <file path> | foreach {Set-MgUserLicense -UserId $_ -RemoveLicenses @('3db7c7ead579...') -AddLicenses @{}} Check for a license SkuId: Get-MgUserLicenseDetail -UserId <UPN>orGet-MgSubscribedSku | fl SkuPartNumber, skuid File path is a TXT file containing UPNs one-per-line.
Force Removal Orphaned Contact in Microsoft 365
The Problem Classic Exchange Online scenario - trying to remove an orphaned (maybe used to be synced) object. Getting slapped in the face with error The Solution Two words: Graph API. Step 1: Get the Mail Contact ID First, we need to identify the exact object we’re dealing with: 1 Get-MailContact lorem.ipsum@contoso.com | Format-List Id This will give the unique identifier for the mail contact. Step 2: Verify the Object in Graph API Better safe than sorry- let’s do a double check. Replace <ID> with the ID from Step 1: ...
How to Get Rid of Power Apps Permissions Consent Form
Permissions Consent Pop-up Every new user must approve permissions when accessing an app. Existing users see this prompt again after app logic or connector updates. App permissions consent pop-up In most scenarios, this pop-up can be bypassed. Hiding consent pop-up This requries a single PowerShell command: 1 Set-AdminPowerAppApisToBypassConsent -EnvironmentName [Guid] -AppName [Guid] Expected result: BypassConsent flag is set We can get guids using PowerShell: ...
Assign Calendar Permissions in Bulk
Just a simple one-liner When you have many room mailboxes, granting someone access to each room calendar one-by-one is painful. This one-liner reads a list of room SMTP addresses from a text file and applies the same permission to each mailbox calendar. 1 2 3 4 5 Get-Content .\rooms.txt | % { Write-Host "Working on $_" -ForegroundColor Cyan Add-MailboxFolderPermission -Identity "$($_.Trim()):\Calendar" -User "przemek@contoso.com" -AccessRights Reviewer } Notes Text file we import via Get-Content contains a room email address per line .Trim is being used to remove blank spaces in TXT file - (’ room@contoso.com’ -> ‘room@contoso.com’) - it’s just a safety feature I like to use In some tenants, the calendar folder name might be localized (for example “Kalendarz” in Poland, “Kalender” in Germany and “Calendier” for France) If permissions are already granted for an user, you need to either remove these and re-add or use Set-MailboxFolderPermissions
Updating Distribution List Extended Attributes with PowerShell
The easy part Creating distribution lists in bulk is quite simple. Just a CSV file: 1 2 3 4 name,mail Fancy Group,Fancy.Group@example.com Another Fancy Group,Another.Fancy.Group@example.com Not That Fancy Group,Not.That.Fancy.Group@example.com And for-each loop 1 2 3 4 5 6 7 Import-Csv .\groups.csv | ForEach-Object { New-DistributionGroup -Name $_.name -PrimarySmtpAddress $_.mail -OrganizationalUnit 'OU=Groups,DC=wrong,DC=went,DC=something,DC=dev' -Type Security } Result: Name DisplayName GroupType PrimarySmtpAddress Fancy Group Fancy Group Universal, SecurityEnabled Fancy.Group@example.com Another Fancy Group Another Fancy Group Universal, SecurityEnabled Another.Fancy.Group@example.com Not That Fancy Group Not That Fancy Group Universal, SecurityEnabled Not.That.Fancy.Group@example.com But updating msExchExtensionAttribute is different A below won’t work as there is no such command under Set-DistributionGroup. ...