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!

Veeam Vanguard 2025

Veeam Vanguard 2025

I have some fantastic news to share. I’ve been awarded Veeam Vanguard status for the 11th consecutive year! Yes, I made Veeam Vanguard 2025.

A decade of community bliss

I have been a proud and satisfied Veeam customer for over a decade. Throughout this journey, I have shared my experiences and insights from the field while using their products. Over the years, the IT landscape has evolved tremendously. While many advancements have made things easier and more efficient, they have also introduced a more diverse, complex, and fragmented environment that requires data protection and management.
From simple file restores to full-scale disaster recoveries across on-premises, hybrid, and cloud environments, Veeam has continuously evolved to meet these challenges with excellence. Today, Veeam offers such a powerful and versatile suite of products that it has become a benchmark in many architectural designs.
We live in an era of uncertainty, rapid change, and shifting landscapes. The need to navigate these challenges has never been more critical. More than ever, the ability to handle both minor incidents and large-scale catastrophes has become the foundation of modern IT strategies. Ransomware, cybercrime, political instability, and economic turmoil have brought data protection to the forefront of discussions with partners and colleagues. The knowledge and expertise I’ve gained by working with Veeam, alongside the brilliant minds in the Veeam 100 community, have empowered me to contribute to these conversations and develop solutions that address today’s evolving threats.

Thank you, Veeam Community

To my fellow Veeam Vanguards, legends, and MVPs, thank you for being part of this incredible journey. A special shoutout to Mike Resseler for initially bringing me into this program. I also want to express my gratitude to Rick Vanover, Nikola Pejková, Madalina Cristil, Safiya Mohamed, Michael Cade, Edwin Weijdema, and Anton Gostev for their trust and support over the years. Their dedication to making Veeam and its community a success is unparalleled.
The support from Veeam’s leadership, including Anton Gostev and many of their employees, truly makes the Veeam community the best in the industry. They not only enable but actively empower the community in every possible way.
Here’s to another year of great conversations, collaboration, innovation, and success!
hashtag#Veeam hashtag#Veeam100 hashtag#VeeamVanguard hashtag#Community

See Veeam 100 Directory | Veeam Community Resource Hub for more information.

How to fix locking yourself out of OPNsense

Introduction

Eventually, we all make the mistake of locking ourselves out of our firewalls. Let’s look at how to fix locking yourself out of OPNsense. Let’s look at how to fix locking yourself out of OPNsense.

How to fix locking yourself out of OPNsense

With OPNsense, this is mainly due to an error in Interface configuration and firewall rules. You know, when we are too “strict” and deny traffic from private networks on the interface we use for management.

How to fix locking yourself out of OPNsense

Cause 1: Firewall rules are blocking you

These can be user-treated rules or the rules added when you select to block private address ranges on an interface.

There is an easy solution, but it requires console access. If OPNsense runs in a virtual machine, that is relatively easy, especially in the lab or when you are the hypervisor administrator. Now, if OPNsense is running on an appliance, you’ll probably need physical access to that device. Bring a keyboard and a monitor with whatever cable (VGA/DVI/HDMI/DisplayPort/USB-C) is required, or connect a physical console cable to connect to the device. This can only be done remotely if the console port is available over ethernet.

Log in with an account with sufficient rights and drop into the shell by selecting option 8.

How to fix locking yourself out of OPNsense

Type:

pfctl -d

Hit “Enter”. This turns the OPNsense device into a router only by disabling the firewall. That means you now have access again via HTTPS or SSH on the interfaces you list for administration despite the error you made in the firewall rules for those interfaces.

Connect via the Web GUI and fix that mistake. When done, turn the firewall back on. To do so type:

pfctl -e

Hit “Enter”. The firewall is now enabled again.

Test whether you still have Web GUI or SSH access. If so, mission accomplished.

Cause 2: You no longer have HTTPS/SSH listening on the interface you have access to

By default, you listen to all non WAN interfaces. You might have reduced this to one or more but accidentally forgot to select the one(s) you need.

No fear, under /conf/conf.xml, you can edit the administrative webgui and ssh settings. In the example below, I have customized those settings (via the WebGUI) to listen to the specified ports.

WebGUI

SSH

How to fix locking yourself out of OPNsense

Add the missing interface(s) or allow the WebGUI and SSH to listen to all of them again by reverting the settings back to default and not specifying any interfaces, as in the example below.

WebGUI

How to fix locking yourself out of OPNsense

SSH

To edit these files, you can use vi, which is available by default. If you prefer Nano or such, you can install it via the FreeBSD package manager:

pkg install nano

Voila, those are the most common ways to get out of a pickle when you have locked yourself out of OPNsense.