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.

Recent Articles

Automating with PowerShell: making stolen tokens useless with Global Secure Access

Last week I watched Merill Fernando talk to Alex Pavlovsky and Marilee Tuscak from the Entra team about something I’d kinda put under the “needs a GSA licence” branch and i’d check it out later, turns out that like most people, I half-assed the documentation and it turns out it doesn’t. There’s two features that come with any P1 license; Compliant network check and Source IP Restoration. So BP, P1, or even frontline worker licenses already have this.

CIPP ❤️ #IntuneForMSPs

We’re Joining #IntuneForMSPs 🎉

Being invited by Microsoft to join a global initiative is a big moment for us, and we want to be clear about why it matters. #IntuneForMSPs is Microsoft’s program to help MSPs deliver Microsoft 365, Intune, and Copilot services at scale, and CIPP is now part of it, bringing the largest MSP community in the channel directly to Microsoft.

The return of CyberDrain CTF

CyberDrain CTF returns! (and so do I!)

It’s been since september that I actually picked up a digital pen equivalent and wrote anything down. This was due to me being busy with life but also my side projects like CIPP. I’m trying to get back into the game of scripting and blogging about these scripts. There’s still so much to automate and so little time, right? ;)