I'm a huge fan of Azure Automation. If you're an #AzureAD / #M365 Admin and haven't used it before, then this thread is for you
You will need an Azure subscription, but the first 500 minutes/month are free!
Here's an example of how to automate Azure AD device cleanup :)
First, we're going to log into the Azure portal: portal.azure.com
Search for Automation and click on Automation Accounts
Then we'll click Create, pick the sub and resource group (or create one), give it a descriptive name, select a location, and hit Review + Create
If you haven't heard, the MSOnline and AzureAD PowerShell modules are going away at the end of the year
Instead, we are going to use the new Graph SDK PowerShell modules
So let's go under Modules, click Add a Module, browse the gallery, and add Microsoft.Graph.Authentication
Now, the Graph SDK PowerShell modules are a bit... different
There are modules for every scope rather than one large module like we used to have. So we just did the one required for Authentication, and we also need to add the Microsoft.Graph.Identity.DirectoryManagement module
Now, we need to create a Run as account since Automation's Managed Identities only work for Azure resources (AFAIK - please correct me!)
Next up, we need to grant Graph API permissions to managed devices to the Service Principal that was just created by our Automation Account
So let's head over to App registrations and search for the name of our Automation Account
Select the account, then go to API permissions, and click Add a permission
In the Request API permissions dialog, click Microsoft Graph, then select Application permissions
In the filter, we'll search for Device.ReadWrite.All
Expand Device, check the box for Device.ReadWrite.All, then click Add permission
Now click Grant admin consent for the Service Principal to be authorized for your tenant and confirm
The final step is to create our Runbook
Go back to your Automation account, click Runbooks under Process Automation, and then click Create a runbook
Give it a name, select PowerShell for type, and the runtime needs to match modules, so 5.1 if following the images so far
You can test code in the Test pane (add -WhatIf), but first... Apparently Graph is different than AzureADPreview, so we will need one additional step - adding the Service Principal to the Cloud Device Administrator role
Whoops, don't forget to Publish!
Now go to Azure AD - Roles and Administrators, earch for Cloud Device Administrator, click Add assignments, then search for the Service Principal for your Automation Account, and add it.
You should now be able to run with proper permissions!
If we go back to our Automation Account and look at the Runbook we just created, we can manually run this script by clicking Start. This will take us to the job where we can see output.
We can also see the history under Jobs for our Automation Account.
But let's schedule this!
Open your runbook, then click the Link to Schedule button
We want to link a schedule to our runbook, then add a schedule, and then configure it how we want :)
Here's an example of running daily at midnight
And that's really all there is to it!
You are now automating disabling of devices that haven't talked to AAD in 90 days :D
• • •
Missing some Tweet in this thread? You can try to
force a refresh
I think the most common misunderstanding of Conditional Access is its relationship to authentication, and this results in not understanding how the rest of the controls actually work
Conditional Access performs authorization by evaluating tokens from the authentication service
This provides important insights 💡
CA policies cannot block anything until AFTER authentication occurs
This means CA cannot help with password spray/credential stuffing. This is why we have Password Protection and Smart Lockout.
You likely aren't collecting all available events to the Unified Audit Log
First, not all events are enabled or retained optimally. Consider creating this policy in the Purview portal (leave users and record types blank to collect everything).
Retention is based on license...
This policy only applies to users with the Microsoft 365 Advanced Audit SKU assigned, audit records are retained for 1 year. Audit records for users without this SKU are retained for 180 days (thanks CISA for the bump up from 90 days!)
Second, this still doesn't get everything..
Next we have to enable all the records for mailbox auditing
But wait, Microsoft totally pinky promises that you don't need to manage these records because they enable them for you
So we create a security group named "Salesforce Admins" and add our admins to the group
Then we configure the claims rule in our Identity Provider to send the role value of System Administrator for members of a group with the display name of "Salesforce Admin" 🚩
Unfortunately, display names are almost never unique, so anyone that can create or modify a group to match the display name can now add admins by adding them to this group
In Entra, ANYONE can create a group by default or owners of groups can modify them, no admin roles needed