Developers in the organization use both – Azure Apps and SharePoint Apps to work with SharePoint sites in their “daemon” applications. You want to know – what are SharePoint Apps registered, who register SharePoint Apps.
One of the approaches – track Apps/Owners with Unified Audit Log
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 need to run some PnP PowerShell code unattended (daemon app, with no user interaction) against SharePoint and/or Azure AD. PnP require authentication with a certificate. You want certificate stored securely in Azure Key Vault.
create a self-signed certificate
register an application in Azure
add API application permissions to the app
upload the certificate to the app
create an Azure Key Vault
provide permissions to the Key Vault for the user
upload certificate to the Key Vault manually (with GUI)
now you can run this code and it will not ask you to login:
# set parameters:
$orgName = "orgname"
$clientID = "" # Client ID
$VaultName = "" # Azure Key Vault Name
$certName = "" # Certificate Name as in Azure Key Vault
$tenant = "$orgName.onmicrosoft.com"
$adminUrl = "https://$orgName-admin.sharepoint.com"
# run the following
$secretSecureString = Get-AzKeyVaultSecret -VaultName $vaultName -Name $certName
$secretPlainText = ConvertFrom-SecureString -AsPlainText -SecureString $secretSecureString.SecretValue
Connect-PnPOnline -Url $adminUrl -ClientId $clientID -CertificateBase64Encoded $secretPlainText -Tenant $tenant
The same PowerShell code in GitHub: https://github.com/VladilenK/PowerShell/blob/main/PnP/Connect-PnPOnline-with-certificate.ps1
PowerShell is our best friend when it comes to ad-hoc and/or scheduled reports in Microsoft 365. PnP team is doing great job providing more and more functionality with PnP PowerShell module for Office 365 SharePoint and Teams.
Small and medium business organizations are mostly good, but for large companies it might be a problem due to just huge amount of data stored in SharePoint. PowerShell reports on all users or all sites might run days… which is probably OK if you run this report once, but totally not acceptable if you need this report e.g. daily/weekly or on-demand.
How can we make heavy PowerShell scripts run faster?
Of course, you start with logic (algorithm) and leveraging full PowerShell functionality (e.g. PowerShell 7 parallelism or PnP batching).
What if you did everything, but it still takes too long? You need something like brute force – the closer your code runs to your tenant – the better. What are the option? – Automation account runbook (+workflow) – Azure Function Apps – Azure VM in the region closest to your Tenant
Automation account runbook (+workflow)
Seemed like a good option, but not something Microsoft promotes. Even opposite – automation accounts support only PowerShell 5 (not 7), no plug-ins for VS Code and recently there were messages on some retirement or smth.
Meantime, I tested it – and did not find any significant increasing in speed. In a nutshell, what is behind this service? Same windows machines running somewhere in Azure .
Quick answer: spin-up a few VMs in different Azure regions, then ping your SharePoint tenant. The moment you see 1ms ping you know the tenant exact location.
Microsoft says: “Customers should view tenant specific data location information in your Microsoft 365 Admin Center in Settings | Org settings | Organization Profile | Data location.” And it might look like:
That’s accurate to the geography (e.g. US, UE, AP), but not to the region (for instance – “Central US”, “UK West” or “Australia Southeast”). In other words, If you know your data are in the US, you do not know where exactly – East/West/Central or South US. Meantime when you create an Azure resource (e.g. Virtual Machine) – you can select specific region.
How do I know – where is my Microsoft 365 tenant actually located?
Can we just ping the tenant, analyze result and find Office 365 tenant region? Luckily, SharePoint tenant is pinging with just PS>ping tenantName.SharePoint.com I have tested 5 regions and 4 different tenants:
ping from/to (ms)
tenant 1 (US)
tenant 2 (EU)
tenant 3 (US)
tenant 4 (US)
South Central US
So I figured it out: My o365 tenants #3 and #4 regions are South Central US (Texas, San Antonio), tenant #1 resides in East US.
Why do I need this?
Imagine you are running heavy reports against your tenant. So probably you want your code running as close as possible to your tenant. For this, you can spin-up a VM in Azure or use Azure Functions – just select proper region 🙂 (please check also “Long-running PowerShell reports optimization in Office 365“)