Uninstall-Graph PowerShell

1 minute read

The Graph PowerShell module is a complicated beast. It has multiple modules and due to various reasons you might want to get back to a clean slate of no Graph PowerShell modules in your system.

To solve this I built a module that does just one thing

Uninstall-Graph

Uninstall-Graph landing page

You can get it at uninstall-graph.merill.net.

It basically runs through multiple times to uninstall all the modules and then finally cleans out the folders for the ones that are stubborn.

Remember to restart a fresh PowerShell session after running this.

Why is the Graph PowerShell module so special?

For starters, some graph modules depend on other graph modules then you have various non-Microsoft modules (like Maester) that rely on Graph modules.

This means uninstalling them is not as simple as running

Uninstall-Module Microsoft.Graph

You would typically see something like this error.

PackageManagement\Uninstall-Package : The module 'Microsoft.Graph.Applications' of version '2.12.0' in module base folder 'C:\Program Files\WindowsPowerShell\Modules\Microsoft.Graph.Applications\2.12.0' cannot be uninstalled, because one or more other modules 'Microsoft.Graph' are dependent on this module. Uninstall the modules that depend on this module before uninstalling module 'Microsoft.Graph.Applications'.

Why would you need to uninstall Microsoft Graph in the first place?

Well the most common reason is that you end up with different versions of the various Graph PowerShell modules and one day you will be hit errors like this

Could not load file or assembly 'Microsoft.Graph.Authentication, Version=2.8.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

or

Import Graph module fails with Could not load file or assembly 'Azure.Core, Version=1.39.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8' or one of its dependencies. The system cannot find the file specified

or something similar.

So getting back to a clean slate and then installing the modules afresh is my preferred solution for this problem.

I’m keen on having this module address all the edge cases when it comes to uninstalling the Graph PS modules. So if you come across any issues please raise them on GitHub. Thanks!

How I create the Entra.Chat podcast

3 minute read

All of the apps/tools I use below are free ($0) except

  • Riverside Standard (I got a 50% discount coupon so paid $90 for first year)
  • Podcast Chapters which was a one time $20.
  • Fedica - for cross posting podcast clips ($10 per month)

I run a weekly podcast with a new guest for each episode.

This is a solo effort where I do EVERYTHING (schedule, interview, edit, publish).

So I am constantly scheduling, recording, editing and publishing my podcast. Even reaching out and keeping track of the people I reached out is crazy since I might have DMd on LinkedIn, Twitter, Email, Teams/Slack.

I tried various note taking apps and calendar integrations like Notion but couldn’t get a handle on things.

What finally worked for me is

superthread.com

Superthread kanban board

Using it I was able to create a kanban where I progressed each guest through a workflow. They went from

  • Backlog - People I want to get on the podcast
  • Scheduling - People I’ve reached out to (this card has status us Invited/Agreed) if they say yes I tag as Agreed so I know I can schedule them.
  • Scheduled - This is once I have them locked in for a date
  • Recorded - These are ones I’ve completed recording but haven’t edited or published
  • Editing In Progress - These are ones that I’m editing
  • Published - These are ones that have gone out to everyone.

Superthread has a rich notes page that is linked to the card for each person/episode. This way I can quickly drill into the note where I store questions and add in notes during the meeting.

I like it so much I use it for tracking my content ideas and ideas for the apps I’m building.

Superthread content tracking

Podcast Editing Process

Okay, now to the actual editing and publishing process (I use Riverside to edit)

I publish video to YouTube and Spotify and audio to everywhere else. I use Substack as my pod website, audio file host.

Here’s my workflow (I keep this in an .md file and keep refining them each week (One day I’m hoping to build an AI agent that automates all this)

# Podcast creation process

## Edit in Riverside

- In Riverside, edit the podcast by listening to the audio and making cuts as needed.
- Use the smart scene option to generate automatic multicam cuts.
- Change video layout (eg me scratching my head)
- If track is not in sync with video click through and add a delay to the track.

Export a 4k version of the video (only use the remove watermark option on export).

## DaVinci Resolve

- Import the video into DaVinci Resolve.
- Use the Assets in this folder (intro, outro etc)
- Take two or three interesting clips from the content and insert them at the beginning.
- The YT thumbnail should be relevant to the first clip or overall theme of the podcast.

Render YouTube 4k preset and audio only with mp3 audio.

## Titles, Chapters and Description

- Upload audio track to substack to create transcript and download it.
- Use the prompt.md in Gemini to generate titles, chapters and description.
- Create a chapters.csv file with the chapters and timestamps generated by Gemini.
- Use Podcast Chapters (https://chaptersapp.com/) and import the mp3, csv and add images
  and chapter titles.

I download the transcript generated by Substack (they do it for free!) and copy/paste the prompt and attach the file to create the notes as well as the csv file for burning the chapter markers and notes into the mp3 file (using chaptersapp.com).

Once I burn the .mp3 with chapter notes I re-upload it to Substack (this is the version that gets sent out).

Podcast clips

I create about 5-6 short clips out of the recording. Because I don’t have the premium version in Riverside I create a portrait video version in Riverside, export it and then use Da Vinci to cut out about 5-6 short clips that are 1-2 min long.

I then use Fedica (a paid service) to schedule and publish one clip every day of the week (plus I sprinkle some for future dates). These get cross posted to all the social media including YT Shorts and TikTok.

So what do you think? What areas would you improve on this? Anything that I should drop? Things I should do to improve the process?

Service Principal as a 'Plan B' emergency access break-glass account

4 minute read

In the world of Microsoft Entra ID management, few topics generate as much passionate debate as emergency access strategies.

Recently, I posed this question in a poll on LinkedIn and X:

What do you think of using Apps (Service Principals) as a ‘Plan B’ emergency access account?

Poll question

Here’s the combined results from the 817 votes.

Poll results

This split reflects the nuanced nature of the topic, with no clear consensus. In this blog post, I’ll break down the approach of assigning a Global Administrator (GA) role to an SP for emergency access, analyze the pros and cons based on community feedback, and share my personal take on the matter.

Why emergency access accounts?

Getting locked out of your Entra tenant is the stuff of nightmares for any IT administrator or security professional. Whether it’s a misconfigured Conditional Access policy, a lost or broken multi-factor authentication device, or an expired credential, the inability to access your critical cloud environment can bring operations to a grinding halt.

Microsoft’s recommendation has been to set up a “break-glass” or “emergency access” user account. These highly privileged accounts are kept under strict control, excluded from standard Conditional Access policies and secured with robust methods like FIDO2 keys stored securely offsite. Their usage is heavily monitored and alerts are triggered immediately upon sign-in.

But in the evolving landscape of cloud identity, a new idea has surfaced, sparking considerable debate: What about using an Application (specifically, a Service Principal) with Global Administrator permissions as an emergency access mechanism?

This approach hinges on the fact that Service Principals authenticate differently than users, often using certificates or secrets, which bypasses user-focused Conditional Access policies. The idea is to create a Service Principal, grant it the Global Administrator Entra role, and secure its credentials (ideally a certificate on a hardware security module like a YubiKey) and monitor its activity rigorously.

The earliest reference for this approach that I’ve seen is this reddit post from 2023 ‘Using Service principal as Azure AD Break glass access’. At that time I dismissed the idea, but lately I’ve seen quite a few posts on various forums where admins had locked themselves out of their tenant and it got me thinking about using SPs.

So that’s where the poll came in - “What do you think of using Apps (Service Principals) as a ‘Plan B’ emergency access account?” The results, based on 817 votes, were quite telling:

  • Yes: 165 (20.2%)
  • No: 327 (40.0%)
  • Maybe: 325 (39.8%)

The poll results clearly indicate a significant level of hesitation or outright opposition to this approach. The combined “No” and “Maybe” votes represent nearly 80% of the responses, suggesting that while there’s some interest or recognition of potential edge cases (“Maybe”), the majority are either against it or highly skeptical.

Let’s delve into the lively discussion that followed to understand the reasoning behind these votes.

Analysis of Community Responses: The Pros and Cons Unpacked

Arguments Against (The “No” Votes and Skeptical “Maybe”s)

  1. Lack of MFA: Service Principals cannot natively perform multi-factor authentication in the same way a user account does. While certificate-based authentication is strong, it’s seen by many as not a direct equivalent to user+MFA.
  2. Credential Management Hell: The security relies entirely on credential security (secrets or certificates). Many expressed concern about managing these.
  3. Privilege Escalation Path: The App Administrator and Cloud Application Administrator roles can manage credentials for Service Principals. If not tightly controlled (e.g., via PIM), an attacker could gain GA access.
  4. Complexity and “Hackiness”: Adds unnecessary complexity that introduces risk.
  5. Lack of Dedicated Controls: No Restricted Administrative Units (RAUs) for Service Principals.
  6. Workload Identity CA Dependency: Many organizations haven’t implemented Workload Identity CA policies.
  7. Doesn’t Solve Core Problems: Doesn’t address root causes of lockouts (poor policy design).

Arguments For or Accepting in Specific Cases

  1. Bypassing Restrictive CA Policies: A Service Principal can circumvent user-based CA policies that might block all user sign-ins.
  2. MSPs and Scaling: Managing physical FIDO keys across numerous clients is logistically challenging. An SP approach could be more scalable.
  3. Requires a Robust Framework: Certificate on HSM, comprehensive monitoring, clear boundaries, protection against modification.
  4. Microsoft Should Build It: Microsoft should create a built-in, purpose-designed recovery account feature.
  5. Better Than Poor User Break-Glass: A well-implemented SP break-glass could be more secure than poorly secured user break-glass accounts.

Conclusion from the Responses

The community sentiment: Using a Service Principal with GA rights as a general break-glass is largely viewed with skepticism (combined 80% “No” and “Maybe”).

My Personal Opinion

(Personal opinion, not representing Microsoft)

I lean towards “Yes” for specific types of tenants:

  1. Increased Lockout Vectors: The ways to lock yourself out have proliferated.
  2. Difficulty of Recovery: Recovering access via Microsoft Support is difficult and time-consuming by design.
  3. Tenant Type Matters:
    • Entra ID Free Tenants, M365 Dev tenants: (Yes) - No clear way to prove ownership.
    • Customers with Enterprise Agreements: Diminished need (Maybe).
    • Production tenants where your CEO can call Satya: Do you even need break-glass accounts?

Creating a Break-Glass Service Principal account

  • Create Emergency Access Service Principal: Dedicated app. Multi-tenant SPs cannot be blocked by Workload ID CA policies in other tenants (today).
  • Grant Entra GA role: Hard to predict what can go wrong; wide role needed.
  • Secure Credentials with HSM Certificate: Generate CSR on a local HSM (YubiKey). Private key never leaves the HSM.
  • Robust Monitoring: Immediate, high-priority alerting whenever the SP signs in. SIEM integration, KQL queries, multi-channel alerts.
  • Redundancy for Monitoring: Separate, independent heartbeat check system.

Someday I hope to build a PowerShell module or an app that makes it super easy to set this up correctly and manage it.

References and further reading

Using Pester to regression test Maester tests

1 minute read

Pester tests for Maester

Pester tests for Maester tests!

I was fixing a Maester bug and thought it would be good to share my process for going about it.

We start off with a Maester bug (Issue with MT. 1016 #804). In this instance the tenant had a CA policy for All Users but did not have one explicitly targeting guests.

While it’s always a better practice to have a separate set of policies for guests, Maester should not penalise them for this. Technically they are in the clear since MFA being applied to all users including guests.

Now the existing code for this check was getting too long and adding more parts to this expression was going to make it hard to maintain.

Original code for Guest MFA check

GitHub Copilot to the rescue! I prompted and got a much cleaner implementation and was able to add the additional check.

Refactored code for Guest MFA check

Now we need to test if it’s working as expected. This involves creating a bunch of CA policies to test and how do we make sure it keeps working with future changes?

That’s where Pester tests come in. I created a bunch of Pester tests to simulate various types of CA policies. Some targeting all users, others targeting just guests and also checking if any type of guest had been excluded.

Pester tests to validate Test-MtCaMfaForGuest

How I went about this was copying out the json of the CA policy. This one here targets guests but excludes the B2B Collab Guest type. This type of policy should be failed by Maester since the tenant is missing an important chunk of guest users being required to have MFA.

JSON of CA policy used for mocking tests

How I use AI as a second brain

less than 1 minute read

This is the start of a conversation I had with an AI to think through the design of changes I’m making to Lokka.

So far I’ve been mostly using GitHub Copilot and others to do specific tasks but I’m now starting to have design discussions and conversations to look for areas that I might be missing (or to play devils advocate).

I also pitted the LLMs against each other. Here’s a comparison.

Claude summary

Claude provided a nice clean summary while GitHub Copilot is not just for code, it’s great for design thinking too.

GitHub Copilot

The last one I tried was Google Gemini’s Deep Research which looked up over 190+ sites including Microsoft docs, LLM docs to provide a complete four page report. Very impressive.

Google Gemini Deep Research

My projects

1 minute read

My projects

If you find them useful please leave a note!


Microsoft Community

Utilities that anyone in the Microsoft community will find useful.


Microsoft Entra

Utilities for Microsoft 365 and Microsoft Entra admins and cybersecurity folks.

  • Entra.News - Stay up to date on all things Entra with this weekly newsletter.
  • Entra.Chat - A weekly podcast on Microsoft Entra.
  • idPowerToys.merill.net - Microsoft Entra related power toys including a Conditional Access visualizer and Entra mind maps.
  • aka.ms/AppNames - Repository hosting a daily updated csv/json of Microsoft first party app names and their GUIDs
  • Entra Exporter - PowerShell module that exports all the config and data of a Microsoft Entra tenant.
  • Azure AD Assessment - Guidance to assess the health of an Azure AD tenant.
  • MSIdentityTools - Collection of useful cmdlets for common Azure AD functionality

Microsoft Graph

Utilities for everyone that works with Microsoft Graph and Graph PowerShell.

  • Graph X-Ray - Fiddler for Microsoft! Convert your actions in the Azure Portal to Graph PowerShell commands.
  • Graph Permissions Explorer - Site that shows all the Graph APIs and data exposed for a given Graph Permission.

I just launched 🦋 Bluesky.ms!

1 minute read

🚀 I just launched my weekend hack project 🦋. With Twitter becoming unusable a whole heap of the Microsoft community is now on Bluesky and having a blast.

I made Bluesky.ms to make it easy to find each other. If you are already on Bluesky, add your profile so others can find you.

If you haven’t started on Bluesky here’s a primer.

🦋 What is Bluesky?

Bluesky is a social app that is designed to not be controlled by a single company. It’s an open network and a version of social media where it’s built by many people, and it still comes together as a cohesive, easy-to-use experience.

✅ Where do I sign up

🚀 How do I find people?

Rebuilding all the folks you know or finding people with similar interests take time. Here are some neat ways to bootstrap the process.

✅ Starter Packs

These are lists of Bluesky users that you can bulk follow. The starter packs help you quickly get started on Bluesky and follow folks in the Microsoft community.

See bluesky.ms/starterpacks for the latest list.

You can also find other non-Microsoft starter packs over at blueskydirectory.com/starter-packs

✅ Help others find you

If you write about Microsoft content and want others to find you, add your profile over at bluesky.ms.

This crowd sourced database welcomes everyone. If you find it’s missing anyone please feel free to add them in.

Let’s build some awesome open communities!

Graph API: Minimal permissions to read user group membership

1 minute read

Here’s an interesting question I received today.

What are the minimal permissions required to read group membership for a user?

The ask was for an application so we need to grant Application permissions and the first attempt was with User.Read.All permission.

When you run this query you do get the groups the user is a member of but it is limited to just the group id. The permission is not enough to get the name of the group.

Invoke-GraphRequest -Uri 'https://graph.microsoft.com/v1.0/users/[email protected]/memberOf/microsoft.graph.group?$select=displayName' | ConvertTo-Json

screenshot showing querying by group member with user.read permission

Now this would be perfectly valid if your app needed just the ID of the group.

However if the app needs the name and other details of the group then you will need to grant additional permissions.

My immediate thought was to grant Group.Read.All but this is a scary permissions, especially when it is an application permission. This will grant tenant wide access to read any information stored in a Group or Team. This includes files and messages in a channel.

So what’s the least privilege permission that will grant access to just the display name?

As of today, the answer is GroupMember.Read.All permission. The reason I say “as of today” is because the permissions are constantly being updated and new permissions are being added, so it is always a good idea to check the docs for the least privilege permissions. Since I did this frequently I built a site to easily show the least privilege permissions Microsoft Graph permissions reference.

screenshot showing querying by group member with user.read permission