Az PowerShell Module Cleanup Script

Introduction

I have had some versions of my home-grown PowerShell script around to clean out the residues of obsolete Azure PowerShell modules from my workstations and laptops. Many of you know that those tend to accumulate over time. As a hobby project, I refined it to share with the world. You can find the script on my GitHub page WorkingHardInIT/AzurePowerShellModulesCleanUp: My Ultimate Azure PowerShell Module Cleanup Script

🔍 Az PowerShell Module Cleanup Script

A PowerShell utility for cleaning up old or duplicate versions of Azure PowerShell (Az) modules across Windows PowerShell and PowerShell Core. It ensures that only the latest version of each Az module is retained—keeping your environment clean, fast, and free from version conflicts.


⚙️ Features

  • ✅ Detects all installed Az and Az.* modules
  • 🧩 Groups by PowerShell edition and installation scope (CurrentUser vs AllUsers)
  • ⛔ Skips removal of AllUsers modules if not run as Administrator
  • 🔄 Keeps only the latest version of each module
  • 📋 Logs results to both Markdown and HTML
  • 🎨 Color-coded output with emoji support in PowerShell Core, fallback labels in Windows PowerShell

🧰 Requirements

  • PowerShell 5.1 (Windows PowerShell) or PowerShell Core (7+)
  • Administrator privileges (for full cleanup including AllUsers modules)
  • Az modules already installed via Install-Module

🛠️ Installation

Clone this repo or download the .ps1 script:

git clone https://github.com/yourusername/az-module-cleanup.git

Or simply download CleanupOldAzurePowerShellModulesWorkingHardInIT.ps1.


🚀 Usage

Run the script directly in a Windows Terminal PowerShell session:

.\CleanupOldAzurePowerShellModulesWorkingHardInIT.ps1

💡 If not run as Administrator, the script will prompt to elevate. If declined, only CurrentUser modules will be cleaned.
❗ If you don’t have Windows Terminal, get it or adapt the script to launch Powershell.exe or pwsh.exe directly


📝 Logs

After execution, logs are saved in the following directory:

<Script Directory>\AzModuleCleanupLogs\

Each run creates:

  • AzCleanup_<timestamp>.md – Markdown log (GitHub friendly)
  • AzCleanup_<timestamp>.html – HTML log (colored, styled)

📦 Example Output

🔍 Scanning for duplicate Az module versions by scope and edition...

📌 Az.Accounts (PowerShellCore in AllUsers):
🧩 Versions Installed: 3
❗ Versions to Remove: 2
📋 All Versions: 2.2.0, 2.1.0, 1.9.5

✅ Successfully uninstalled Az.Accounts version 2.1.0
✅ Successfully uninstalled Az.Accounts version 1.9.5

✅ Cleanup complete. Only the latest versions of Az modules are retained.

⚠️ Notes

  • Deletion of modules is attempted first via Uninstall-Module. If that fails, the script tries to remove directories manually.
  • To force elevation in PowerShell Core, wt.exe (Windows Terminal) is used to relaunch with admin rights.

📄 License

This project is licensed under the MIT License.


🙌 Credits

Crafted with care by Didier Van Hoye

Script to Bulk Invite Guest Users to Azure Entra ID

Introduction

Last week, I was on service desk duty. It’s not my favorite field of endeavour, and I’m past my due date for that kind of work. However, doing it once in a while is an eye-opener to how disorganized and chaotic many organizations are. Some requests are ideal to solve by automating them and handing them over to the team to leverage. That is how I wrote a script to bulk invite guest users to Azure Entra ID, as I could not bring myself to click through the same action dozens of times in the portal. You can find the script on my GitHub page https://github.com/WorkingHardInIT/BulkInviteGuestUsersToEntraIdAzure

Script to Bulk Invite Guest Users to Azure Entra ID

📌 Overview

This PowerShell script allows administrators to bulk invite guest users to an Azure Entra ID (formerly Azure Active Directory) tenant using Microsoft Graph. It includes retry logic for connecting to Microsoft Graph, supports both interactive and device code login, and reads user details from a CSV file.

✨ Features

  • Connects to Microsoft Graph securely using MS Graph PowerShell SDK
  • Retry logic with customizable attempt count
  • Supports both interactive and device-based authentication
  • Invites guest users based on a CSV file input
  • Allows optional CC recipients in the invitation email (limited to one due to API constraints)
  • Includes meaningful console output and error handling

📁 Prerequisites


📄 CSV File Format

Create a file named BulkInviteGuestUsersToAzureEntraID.csv in the same folder as the script with the following columns:

emailAddress,displayName,ccRecipients
[email protected],Guest One,[email protected]
[email protected],Guest Two,

Note: Only the first ccRecipient will be used due to a known Microsoft Graph API limitation.


🔧 Script Configuration

Open the script and configure the following variables:

$Scopes = "User.Invite.All" # Required scope
$csvFilePath = ".\BulkInviteGuestUsersToAzureEntraID.csv"
$TenantID = "<your-tenant-id-guid-here>" # Replace with your tenant ID
$emailAddresses = $Null # Optional static list of CC recipients

▶️ How to Run

  1. Open PowerShell as Administrator
  2. Install Microsoft Graph module (if not already):Install-Module Microsoft.Graph -Scope CurrentUser
  3. Execute the script:.\InviteGuestsToAzureEntraID.ps1Or specify login type:Test-GraphConnection -TenantID “<tenant-id>” -Scopes $Scopes -UseDeviceLogin

🧠 Function: Test-GraphConnection

This helper function ensures a valid Microsoft Graph session is established:

  • Disconnects any stale Graph sessions
  • Attempts up to $MaxRetries times to connect
  • Verifies that the session is for the specified Tenant ID
  • Supports -UseDeviceLogin switch for non-interactive login (e.g., headless servers)

📬 Inviting Users

The script loops through all entries in the CSV file and sends out personalized invitations using the New-MgInvitation cmdlet.

Each invite includes:

  • Redirect URL (https://mycompany.portal.com)
  • Display name from CSV
  • Custom message
  • Optional CC recipient (only first address is respected by Graph API)

⚠️ Known Issues

  • CC Recipients Limitation: Only the first email in ccRecipients is honored. This is a known issue in the Microsoft Graph API.
  • Multi-user CC: If different users need unique CCs, adapt the script to parse a ccRecipients column with user-specific values.

📤 Example Output

✅ Using device login for Microsoft Graph...
✅ Microsoft Graph is connected to the correct Azure tenant (xxxx-xxxx-xxxx).
✅ Invitation sent to Guest One using [email protected]
⚠️  Skipped a user due to missing email address.
⚠️  Failed to invite Guest Two: Insufficient privileges to complete the operation

🧽 Cleanup / Disconnect

Graph sessions are managed per execution. If needed, manually disconnect with:

Disconnect-MgGraph

📚 References


🛡️ License

This script is provided as-is without warranty. Use it at your own risk. Feel free to adapt and extend as needed.


✍️ Author

Didier Van Hoye

Contributions welcome!