Capitalizing on the huge advantages that managed identities in Azure offer, here’s another use case similar to the scheduled migration script that also uses it’s managed identity (and graph permissions) to autonomously run as an Azure Runbook without any credentials stored.
The script will log in to Graph, retrieve all unique license types and how they are assigned to users, and will then email an HTML report (table) the the specified recipient, order by email domain.
Connect-AzAccount and my own silent token function use the Microsoft built in client ID of “1950a258-227b-4e31-a9cf-717495945fc2”.
The resulting token has some openID scopes and most backend calls use RBAC, but I wanted to experiment by adding OAuth2 permissions and app roles to it so I can use the context/cached refresh token to also call other Microsoft API’s.
I discovered that this can be done by adding the client to your AzureAD as an SPN (Enterprise Application):
Since this is Microsoft owned app, you’ll actually see that show up in AzureAD:
Next, we can add the AuditLog.Read.All permission to the local instance of this app ($spn), this is a Graph permission, so we first need to get the resourceId of graph in our tenant:
Any future tokens you grab for graph.microsoft.com using 1950a258-227b-4e31-a9cf-717495945fc2 as clientId will now contain the AuditLog.Read.All scope as well;
You should also be able to add approles, but since (hopefully) only Microsoft has the client credentials, they won’t do much.
When auditing a Sharepoint environment, an important component is permissions;
invited users
sharing links
inherited permissions
unique permissions
broken inheritance
sites, webs
lists, libraries
I’ve heavily modified Salaudeen Rajack’s work to share a more fully featured and faster PowerShell auditing script that will dump all unique permissions (up to item level, recursively) for all sharepoint sites (including O365 group sites). For files, folders, sites, libraries, etc etc.
It retrieves membership of groups so the resulting CSV file contains all permissions, with exception of the “Everyone” group, which is listed as a group instead.
the script uses device based logon, just follow the prompts.
don’t forget to first set permissions on all sites for your admin account, see script header for an example
requires the PnP module
you can exclude specific sites or users from the report if needed, configure siteIgnoreList or principalIgnoreList for that
Runtime on an environment with over 1000 sites and millions of objects was about 6 hours. If you environment is too large, contact me and I can perhaps introduce e.g. multi-threading.
In many situations, this solution is a little overkill though, so I’ve also created a second version which simply allows you to redirect any local folder (including variable paths!) to any location in a user’s Onedrive folder.
It can be used as a onetimer or as logonscript, and it can also be used to migrate existing content or create hard links for specific local appdata folders.