Let say you administer Microsoft 365 SharePoint Online and you want to get a list of new SharePoint sites (e.g. sites created during last week/month).
With GUI it’s done easily: SharePoint Admin Center -> Active Sites -> sort based on “Date Created” – done.
With PowerShell – not so simple. “Get-PnPTenantSite” cmdlet returns site objects but the object does not have “Created” field. You have to connect separately to each site and get root web object where you can check when the web was created. For small environments it is possible, for large environments it can take days… And still not nice. -Filter option would help, but “…Currently, you can filter by these properties: Owner, Template, LockState, Url.”
Get-SPOSite – similar experience.
Microsoft Graph API helps. It returns result in seconds. There are some pros and cons for each method though.
Microsoft Graph Search API allows KQL in queries. So we can form a query with something like “created>=1/1/2021” and use entity type = ‘[“site”]’. Search should return only sites created after Jan 01, 2021.
This option is also based on Microsoft Graph API, but sites entry point, which allows search too and sort results by property “createdDateTime”. So we will just search for everything and select how many results we need based on createdDateTime property.
Scenario: you administer SharePoint Online Microsoft 365 tenant business asks you to remove mobile phone numbers from SharePoint User Profiles:
As a SharePoint administrator, you can do it: 1. Start Microsoft 365 SharePoint Admin Center 2. Navigate to More Features -> User Profiles -> Manage User Properties
3. Under “Contact Information” -> Mobile phone -> Edit
4. Uncheck “Replicable”, Save, wait a minute or two 5. – Select “Default Privacy Settings”: “Only Me” – Uncheck “User can override” – Uncheck “Allow users to edit values for this property” – Uncheck “Show in the profile properties section of the user’s profile page” – Uncheck “Indexed”
A pop-up window will appear to authenticate interactively. If you are already authenticated with another credentials (or single-sigh-on) – an interactive window might pop up and disappear – so you are not able to enter your admin id. To ensure Connect-PnPOnline prompts you for your credentials – use ” -ForceAuthentication” option.
If you are a SharePoint tenant admin – you can connect to a tenant with:
NB: For delegated permissions, the effective permissions of your app are the intersection of the delegated permissions the app has been granted (via consent) and the privileges of the currently signed-in user. Your app can never have more privileges than the signed-in user.
The code must run without user interaction (unattended, aka daemon app). Sometimes this is also called “SharePoint Automation”.
The solution is based on a new Graph API feature – Sites.Selected and a classic SP-Only app.
Register an Azure App and configure it: MS Graph API permissions: add -> Microsoft Graph -> Applications Permissions -> “sites.selected”
Ask SharePoint/Tenant admin run PowerShell code (e.g. this one) to assign proper permissions to your azure app for a specific site collection (consider site owner consent)
Provide SharePoint API permissions: (require Site Collection Owner/Admin account) – use https://YourTenant.sharepoint.com/teams/YourSite/_layouts/15/appinv.aspx to add SharePoint API permissions to your app. E.g. full control permissions to site collection would be
You are a developer or power user in a company with Microsoft 365 tenant. You need to connect to Microsoft Graph and then call Microsoft Graph API to consume some MS Graph resources on behalf of authenticated user programmatically with PowerShell – e.g. add/remove documents or list items, search for sites or documents content etc. – whatever available with Graph API.
You do not have tenant admin permissions or any tenant-level admin permissions (SharePoint, Teams, Exchange etc. ). But you can register an Azure App and request tenant admin consent.
register an Azure App
under authentication blade – add platform – “Mobile and Desktop app” add “http://localhost” (and select …/nativeclient Url ?)