I was having a discussion the other day about helping organizations to cleanup ungoverned guests in their organization. While the discussion was cenered around using Azure AD Access Reviews to review the existing guests to determine if they should remain or be removed, I wanted to see about reducing the number of guests that need to be reviewed first.
With the recent announcement of Microsoft Graph PowerShell v2 is now in public preview, half the size and speeds up automation I knew one of the exciting new features is to connect with the module using managed identities, so I thought I would see what that experience would be look like for this solution.
The v2 module is currently in public preview, so I'll walk through the steps on how you can import this prerelease version into your Azure Automation environment to use in your runbook.
I also want to use other features of the platform to limit the scope of what the automation can manage, so we'll be using the dynamic administrative units feature to scope the process only to guest users.
So below we will walk through:
- Using the Microsoft Graph SDK Module v2 pre-release to execute PowerShell commands using managed identities
- Constrain the ability to remove guests only in a specific administrative unit
- Automate identifying guests which were invited over XX days ago, but who never redeemed the invitation. (This can happen due to email typos, etc.)
Create the Azure Automation Account
Running PowerShell without local machines
- You can create the Azure Automation account in the Azure portal

2. Confirm the Managed Identity Service Principal ID
In this case the ObjectID of the Service Principal that represents the system managed identity is 84836a0e-c213-4184-b7fe-10cc88ad13c6 as shown below.

Grant the Managed Identity Permissions
Granting the SP the ability to manage users in a dynamic administrative unit
For this scenario we are going to grant the service principal the User Administrator role over a dynamic administrative unit which is scoped to users with userType == guest.
- Create an administrative unit for guests to be managed
Using the Entra admin portal, create the Administrative Unit (AU) that will contain all the guests in the tenant

2. Update the administrative unit to be dynamic assignment
After the administrative unit is created, open it's properties and set the Membership type to Dynamic user

3. Configure Dynamic membership rules for AU membership
For this scenario, we want only guest users to be contained in this administrative unit, so we will use a dynamic filter based upon (user.userType -eq "Guest") and save the AU configuration.

4. Assign the Service Principal the User Administrator role on the AU
In order to grant the AU scoped permissions, we can assign the service principal for he managed identity we created the User Administrator role on the AU scope as a permanent active assignment.
You can use the SP object ID or display name to select the member in the dialog for assignment.


Since we are scoping the application identity permissions using directory roles to the scope of the AU, we also need to assign Directory Reader to the tenant scope.


Import Modules into Azure Automation Account
Using the PowerShell Gallery
In order to do these tasks using the public preview of the V2 MS Graph SDK PowerShell module, we'll manually import these into our 7.1 runspace.
We will also be using the MSIdentityTools module from the PowerShell Gallery since it already contains a cmdlet (Get-MsIDUnredeemedInviteUser) which makes it easy for us to enumerate guest users who exist in the tenant who were invited in the past but have not redeemd the invitation.
- Download the latest v2 version of the Microsoft.Graph.Authentication module
You can visit the PowerShell Gallery and see the Manual Download link of the nupkg for the v2 version of the Microsoft.Graph.Authentication module (This would be the 2.0.0-preview4 version at the time of this post)

Click on the manual download tab, and click on the Download raw nupkg file which will start the download. Once download is complete, rename file to microsoft.graph.authentication.zip
2. Download the latest v2 version of the Microsoft.Graph.Users module
You can visit the PowerShell Gallery and see the Manual Download link of the nupkg for the v2 version of the microsoft.graph.users module (This would be the 2.0.0-preview4 version at the time of this post)

Click on the manual download tab, and click on the Download raw nupkg file which will start the download. Once download is complete, rename file to microsoft.graph.users.zip
3. Import microsoft.graph.authentication pre-release module into Azure Automation
We will first import the microsoft.graph.authentication modul since it is a dependency for other subsequent modules.
In the module section, click add a module. and browse for file for the microsoft.graph.authentication.zip file you downloaded and renamed earlier. Set the runtime version to 7.1 (preview) and click import.

It will take some time to import which you can monitor by filtering on the Importing status.

4. Import microsoft.graph.users pre-release module into Azure Automation
Once the previous model has completed importing, we will now import the microsoft.graph.users module
In the module section, click add module. and browse for file for the microsoft.graph.users.zip file you downloaded and renamed earlier. Set the runtime version to 7.1 (preview) and click import.

5. Import the MSIdentityTools module from the PowerShell Gallery
Since this module exists in the PowerShell Gallery we don't need to manually import it.
In the module section, click add module. and browse from gallery for"MSIdentityTools" module, and select it. Set the runtime version to 7.1 (preview) and click import.


Create Runbook for PowerShell code
Using MS Graph SDK Module V2 pre-release
- Create the Runbook in your Azure Automation account
Using the Azure Portal, you can create new runbook in the Azure Automation account you created earlier. Give it a name that makes sense to your organization, a PowerShell runbook type and a 7.1 (preview) runtime version.

2. Edit Runbook to insert your PowerShell Code
Here is an example piece of code to enumerate guests invited before XX days ago, who have not redeemed, to use as a the population to remove from the tenant. This is just a quick example, so use your own logic to determine the actions you want to take to remove the unredeemed users.
Import-Module -Name Microsoft.Graph.Authentication -MinimumVersion 2.0.0
Import-Module -Name Microsoft.Graph.Users -MinimumVersion 2.0.0
Import-Module MSIdentityTools
$InvitedDaysAgo = 90
Connect-MgGraph -Identity
#Write-Output (Get-MgContext|out-string)
$StaleGuests = Get-MsIdUnredeemedInvitedUser -InvitedBeforeDaysAgo $InvitedDaysAgo|where-object -FilterScript {$_.UserType -eq 'Guest'}
Write-Output ("{0} Guests to be removed!" -f $($StaleGuests|measure-object).count)
if ($StaleGuests.count -lt 100 -and $StaleGuests.count -gt 0)
{
foreach ($u in $StaleGuests)
{
Write-Output ("Removing Unredeemed User {0} [{1}] ({2})" -f $u.UserPrincipalName,$u.UserId,$u.mail)
try
{
Remove-mgUser -UserId $u.UserId -ErrorAction Stop
Write-Output ("{0} User has been removed!" -f $u.UserPrincipalName)
}
catch
{
Write-Error $_
}
}
}
else
{
Write-Output ("Stale Guests count ({0}) is 0 or greater than 100. Skipping!" -f $($StaleGuests.count))
}
Save code in your runbook. You can now use the test pane to execute your code to see the results.

Once tested, you can now publish your runbook and schedule it to run on a schedule or on-demand. I would recommend checking out the docs on Configure runbook output and message streams | Microsoft Learn to optimize the information signaling for yoru runbook jobs as well.

Conclusion
Using Managed Identities is easy with Powershell SDK Module v2
With the pre-release v2 module, we can see how managed identity support helps simplify how we use PowerShell to do automation activities for Entra and Microsoft Graph. As the previous identity focused PowerShell modules are deprecated I look forward to improving the MS Graph SDK module's capablities and improving the user experience.
Once the modules progress to release and supporting modules are updated to take advantage of the new v2 capabilities, I am excited to see how customers can utilize them to use minimal code when needed, while they also use no-code solutions like Logic Apps for workflows and identity actions in their environment.