Function to Spot ALL All-User and All-Guest Groups in Entra ID

There are probably many scenario’s where you’d like to identify which Entra groups contain ‘all users’, ‘all guests’ or a combination (all members+all guests).

In my case, I want to use this in M365Permissions, but also needed it for a Maester test to be more precise. It had to be language and implementation agnostic.

M365Permissions uses this mainly for reports that look at oversharing (e.g. when securing a tenant or implementing copilot). But this could also be useful for red/blue teams or any other tenant analysis tooling.

In M365Permissions, I initially looked at the dynamic rule itself, but this is unreliable. Dynamic rules can contain many additional components and can be ordered or written in many ways or the group may have been created without a dynamic rule through e.g. automation.

So I decided to use another approach!

Just get all tenant users from Graph (counts per type).

Then for a given group, look if it matches one of those counts and return a type. Of course, casting members to users to avoid counting devices and looking up membership recursively 🙂

Function: https://github.com/jflieben/assortedFunctionsV2/blob/main/Get-EntraDynamicGroupType.ps1

Azure VM Spot Pricing API

The Azure Retail Prices API does not give correct prices for SPOT VM’s (which can change at any time).

As I use SPOT VM’s a lot to scan largers tenants with M365Permissions to avoid throttling and get results FAST, I needed a reliable way to get the lowest priced F-series VM to temporarily finish a scan queue before getting discarded again.

I created an initial function using the ‘hidden’ retail billing API which calls the ‘https://s2.billing.ext.azure.com/api/Billing/Subscription/GetSpecsCosts?SpotPricing=true’ endpoint.

My post on Linked then got some advice Morten which I now finally got around into creating a function for, using an official instead of ‘hidden’ API!

This resulted in the Get-VmSpotPrices function, which I’m sharing for free through Github:

https://github.com/jflieben/assortedFunctionsV2/blob/main/Get-VmSpotPrices.ps1

Converting onedrive url to UPN

Had a bit of a struggle converting onedrive for business url’s reliably to UPN’s.

Since a path might contain /personal/ multiple times, and we have those pesky national tenants with special url’s to deal with…

So thought I’d share:

function Get-UPNFromOnedriveUrl{
    Param(
        [string]$url
    )

    $userName = ''
    if ($url -match ':\/\/.*?\..*?\/personal\/(.*?)\/') {
        $userName = $matches[1]
    }else {
        Throw "Invalid OneDrive URL format: $url"
    }

    if(!$global:tenantODStyleDomains){
        $global:tenantODStyleDomains = New-GraphQuery -Uri "https://graph.microsoft.com/v1.0/domains" -Method GET -resource "https://graph.microsoft.com" | ForEach-Object { $_.id.replace(".","_") }
    }

    foreach($tenantODStyleDomain in $global:tenantODStyleDomains){
        if($userName -like "*_$tenantODStyleDomain"){
            $prefix = $userName.Replace("$tenantODStyleDomain","") 
            $suffix = $tenantODStyleDomain.Replace("_",".")
            break
        }
    }

    return "$prefix@$suffix".Replace("_","").ToLower()
}

M365Permissions v1.2.3

Performance improvements and Onenote Notebooks.

Today’s release has a ‘special guest’; Morten (blog)! He completely rewrote the entra user and group retrieval code, greatly improving both performance and total capacity!

Other changes of note:

  1. Add support for Onenote Notebook sharing permissions
  2. Treat anonymous sharing links as ‘deleted’ if the sharing level at the site forbids anonymous sharing

Full changelog here

Download / Use:

M365Permissions module page | Github | PSGallery

Microsoft 365, Azure, Automation & Code