Monitoring with PowerShell: Monitoring Onedrive and Sharepoint file limits

I love our cloud deployments. I’m amazed at how well people are adapting to working with an online online environment and using the tools cross platform such as the Onedrive and Teams client. As both a tech, and on the management side of the house it’s great to see such flexibility.

The only downside we’ve found so far is that you do have pay a lot of attention to the current limitations of the application your running. So in our case we have a bunch of OneDrive clients. These clients have to be taught you can’t just drop everything in a single location like we did with a file server.

So we are now monitoring some of the limitations that exist in the OneDrive sync client. One of the limitations is that you should not sync libraries with more than 100,000 files, so whenever we reach 90000 files, we create a new library or move data for our clients.

All Tenants Script

The script uses the Graph API. Get all the keys from the Secure App Model script. It will run for all tenants and alert on each that has more than 90000 files.

$ApplicationId = 'YOURAPPLICATIONID'
$ApplicationSecret = 'YOURAPPLICATIONSECRET' | Convertto-SecureString -AsPlainText -Force
$TenantID = 'YOURTENANTID'
$RefreshToken = 'YOURUNBELIEVEBALLYLONGREFRESHTOKEN'
$upn = 'UPN-Used-To-Generate-Tokens'
##############################
$credential = New-Object System.Management.Automation.PSCredential($ApplicationId, $ApplicationSecret)
write-host "Generating access tokens" -ForegroundColor Green
$aadGraphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.windows.net/.default' -ServicePrincipal -Tenant $tenantID 
$graphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.microsoft.com/.default' -ServicePrincipal -Tenant $tenantID
write-host "Connecting to MSOLService" -ForegroundColor Green
Connect-MsolService -AdGraphAccessToken $aadGraphToken.AccessToken -MsGraphAccessToken $graphToken.AccessToken
write-host "Grabbing client list" -ForegroundColor Green
$customers = Get-MsolPartnerContract -All
write-host "Connecting to clients" -ForegroundColor Green

$LimitsReached = foreach ($customer in $customers) {
    write-host "Generating token for $($Customer.name)" -ForegroundColor Green
    $graphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.microsoft.com/.default' -ServicePrincipal -Tenant $customer.TenantID
    $Header = @{
        Authorization = "Bearer $($graphToken.AccessToken)"
    }
    Write-Host   "Grabbing data for $($customer.name)" -ForegroundColor green
    $OneDriveUsageURI = "https://graph.microsoft.com/v1.0/reports/getOneDriveUsageAccountDetail(period='D7')"
    $OneDriveUsageReports = (Invoke-RestMethod -Uri $OneDriveUsageURI -Headers $Header -Method Get -ContentType "application/json") | ConvertFrom-Csv

    $SharepointUsageReportsURI = "https://graph.microsoft.com/v1.0/reports/getSharePointSiteUsageDetail(period='D7')"
    $SharepointUsageReports = (Invoke-RestMethod -Uri $SharepointUsageReportsURI -Headers $Header -Method Get -ContentType "application/json") | ConvertFrom-Csv
    
    
    foreach ($SharepointReport in $SharepointUsageReports) {
        if ([int]$SharepointReport.'File count' -ge [int]"90000") {
            $SharepointReport 
        }
    }

    foreach ($OneDriveReport in $OneDriveUsageReports) {
        if ([int]$OneDriveReport.'File count' -ge [int]"90000") {
        $OneDriveReport
        }
    }

     

}

if (!$LimitsReached) {
    Write-Host   "Healthy" -ForegroundColor green
}
else {
    Write-Host   "Unhealthy" -ForegroundColor Red
    $LimitsReached
}

Single Tenant Script

This version runs only for the tenant you’ve entered, so you can specify which tenants you want to monitor.

$ApplicationId = 'YOURAPPLICATIONID'
$ApplicationSecret = 'YOURAPPLICATIONSECRET' | Convertto-SecureString -AsPlainText -Force
$TenantID = 'YOURTENANTID'
$RefreshToken = 'YOURUNBELIEVEBALLYLONGREFRESHTOKEN'
$upn = 'UPN-Used-To-Generate-Tokens'
$TenantToMonitor = "Blabla.onmicrosoft.com"
##############################

$LimitsReached = 

    write-host "Generating token for $($TenantToMonitor)" -ForegroundColor Green
    $graphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.microsoft.com/.default' -ServicePrincipal -Tenant $TenantToMonitor
    $Header = @{
        Authorization = "Bearer $($graphToken.AccessToken)"
    }
    Write-Host   "Grabbing data for $($TenantToMonitor)" -ForegroundColor green
    $OneDriveUsageURI = "https://graph.microsoft.com/v1.0/reports/getOneDriveUsageAccountDetail(period='D7')"
    $OneDriveUsageReports = (Invoke-RestMethod -Uri $OneDriveUsageURI -Headers $Header -Method Get -ContentType "application/json") | ConvertFrom-Csv

    $SharepointUsageReportsURI = "https://graph.microsoft.com/v1.0/reports/getSharePointSiteUsageDetail(period='D7')"
    $SharepointUsageReports = (Invoke-RestMethod -Uri $SharepointUsageReportsURI -Headers $Header -Method Get -ContentType "application/json") | ConvertFrom-Csv
    
    
    foreach ($SharepointReport in $SharepointUsageReports) {
        if ([int]$SharepointReport.'File count' -ge [int]"90000") {
            $SharepointReport 
        }
    }

    foreach ($OneDriveReport in $OneDriveUsageReports) {
        if ([int]$OneDriveReport.'File count' -ge [int]"90000") {
        $OneDriveReport
        }
    }

     


if (!$LimitsReached) {
    Write-Host   "Healthy" -ForegroundColor green
}
else {
    Write-Host   "Unhealthy" -ForegroundColor Red
    $LimitsReached
}

So that’s it. As always, Happy PowerShelling.

Kelvin Tegelaar
Follow me

11 thoughts on “Monitoring with PowerShell: Monitoring Onedrive and Sharepoint file limits

  1. Darren

    Hey Kelvin,

    First of all, love your work!

    Just started getting into the Delegated Permissions via PowerShell thing. I managed to generate the keys and connect to MSOL etc and run commands on customer tenants. However, when I run either script above I am getting an error at the Invoke-RestMethod command which when I run just that command I get the error below. Wondering if there is some sort of propagation time involved (I only just created the App and Keys 30 minutes ago) or if there is something else I am missing:

    Invoke-RestMethod : {
    “error”: {
    “code”: “S2SUnauthorized”,
    “message”: “Invalid permission.”,
    “innerError”: {
    “request-id”: “Blah-Blah”,
    “date”: “2020-03-21T07:10:17”
    }
    }
    }
    At line:1 char:1
    + Invoke-RestMethod -Uri $OneDriveUsageURI -Headers $Header -Method Get …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

    Reply
      1. Darren

        Doh! No, missed that small detail…(;-) I went straight to this latest “Monitoring Onedrive and Sharepoint file limits” blog so missed the permissions bit in the previous blog.

        Anyway, added the Reports.Read.All permission and Granted Admin Consent and…..still getting the same error on the Invoke-RestMethod command. I am guessing that I have the right checklist or am I missing something else?

        Reply
          1. Darren

            Found it! I needed to add MS Graph, Reports.Read.All, Delegated Permission to the API Permissions. Not yet sure if this is in addition to. or instead of Reports.Read.All, Application permission described in the previous blog. It started working immediately after I added the Delegated permission and I haven’t tried without the Application permission.

  2. Nick M.

    I’ve completed all the steps in your previous blog post in order to get the secret keys. I am however getting the following error when I run this. We do have MFA (running a third party version and not Microsoft’s version). Any idea what could be causing this?

    New-PartnerAccessToken : AADSTS50079: Due to a configuration change made by your administrator, or because you moved to a new location, you must enroll in multi-factor
    authentication to access ‘00000002-0000-0ff1-ce00-000000000000’.

    Reply
    1. Kelvin Tegelaar Post author

      Yeah, when using a different MFA/SSO supplier this method breaks. Just found that out this weekend 🙂 a solution is provisioning O365 MFA and then performing it again.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.