There is no light out here.

Dark mode is the only mode.

Granting App Permissions to a SharePoint Site via Graph API

The Task Grant an Azure AD app write access to a single SharePoint site - instead of every site in the tenant. Prerequisites Global Administrator role or Site Owner permissions on the target site An app registration with the Sites.Selected permission Checking Existing Permissions GET request: https://graph.microsoft.com/v1.0/sites/{site-id}/permissions Empty value: [] means no app-level permissions have been granted yet Granting Permissions POST request Body: 1 2 3 4 5 6 7 8 9 10 11 { "roles": ["write"], "grantedToIdentities": [ { "application": { "id": "APP_CLIENT_ID_HERE", "displayName": "Your App Name" } } ] } Request body: application ID + display name ...

July 29, 2026 · 1 min · 136 words · Przemek

Which groups do users belong to? A Graph API approach

What’s that? Just another script for listing users and their group memberships. You feed it a text file with UPNs, it queries Microsoft Graph, and spits out a flat CSV like: UserPrincipalName PrimarySmtpAddress GroupName GroupEmail GroupType [email protected] [email protected] Some DL [email protected] DistributionList [email protected] [email protected] Security Group ABC [email protected] MailSecurityGroup [email protected] [email protected] Some DL [email protected] DistributionList Where’s it? On GitHub Requirements PowerShell 5.1+ or PowerShell 7+ Microsoft Graph PowerShell SDK Permissions: User.Read.All, GroupMember.Read.All, Group.Read.All

March 23, 2026 · 1 min · 73 words · Przemek

How to Update Proxy Addresses for a Cloud-Only Object

Problem If you want to add or remove (basically update) a proxy address on a cloud-only account - without an Exchange mailbox - you cannot. There is no such option in the GUI and PowerShell won’t allow it either, throwing an error: Set-MgUser : Property 'proxyAddresses' is read-only and cannot be set. Status: 400 (BadRequest) ErrorCode: Request_BadRequest Solution Use the Graph API BETA endpoint. Method: PATCH URL: https://graph.microsoft.com/beta/users/<User_ID> Request Body: 1 2 3 4 5 6 7 8 { "proxyAddresses": [ "SMTP:PrimarySMTPAddress", "smtp:Alias1", "smtp:Alias2", "smtp:Alias3" ] } Expected Response: 204 No Content An example ...

March 16, 2026 · 1 min · 122 words · Przemek

Search Tenant Objects by Domain

Domain Removal Issues If you want to remove a domain from an M365 tenant, you need to deprovision all associated objects first - easy to say, harder to do. If the domain is not federated, M365 can handle it for you - it simply removes aliases and updates the Primary SMTP address and/or UPN to the default domain (domain.onmicrosoft.com). However, this does not work for federated domains. You have to remove everything manually, which is manageable for one domain. In my case, I had to remove 150. ...

March 16, 2026 · 2 min · 267 words · Przemek

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: ...

February 6, 2026 · 1 min · 200 words · Przemek

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.

January 26, 2026 · 1 min · 51 words · Przemek

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 [email protected] | 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: ...

January 26, 2026 · 1 min · 177 words · Przemek