Thursday, May 2, 2024
HomePowershellReport Mailbox and OneDrive Measurement in PowerShell through Microsoft Graph API

Report Mailbox and OneDrive Measurement in PowerShell through Microsoft Graph API


Report Mailbox sizes, OneDrive sizes, or multi functional, with PowerShell and the MS Graph API

Within the tutorial under I clarify how one can:

Within the weblog put up I exploit PowerShell and the Microsoft Graph API. I constructed my very own modules across the API. I don’t use the official Microsoft PowerShell module.

Within the weblog put up under, I’m utilizing a submodule known as Optimized.Mga.Report.
This can be a submodule of Optimized.Mga.

Acquired suggestions? Please go away a remark!


Earlier than we are able to begin…

We want the next:


PowerShell module Optimized.Mga.Report

  • When you have suggestions for me, you possibly can go away a touch upon this put up, or on Github.
  • If you wish to know extra about learn how to use and skim the module, try this weblog.

AzureAD registered utility

Undecided learn how to get began with an AzureAD registered utility for the Microsoft Graph API?

I wrote a web page for this which you’ll find right here:
Tips on how to begin with Microsoft Graph in PowerShell by Bas Wijdenes

Microsoft additionally created a weblog put up about learn how to get began with an AzureAD registered utility for the Microsoft Graph API.
You’ll find that right here:
Handle app registration and API permission for Microsoft Graph notifications – Microsoft Graph | Microsoft Docs


Let’s get began with Optimized.Mga in PowerShell

Getting the Authorization token from Microsoft Graph API

Open Powershell!

To put in the module & submodule you should use the next cmdlet:

Set up-Module Optimized.Mga.Report -Scope CurrentUser

Copy the under cmdlet.
Replace the variables and select the way you’d like to connect with the Graph API.

By working the cmdlet you’ll create an Authorization token that different cmdlets (like Get-Mga) will robotically use within the backend.

$null = Join-Mga -ClientSecret 'XXXX' -ApplicationID 'b5954443-ad10-4d1c-8cbc-dc05268a1858' -Tenant 'bwit.onmicrosoft.com'

If the whole lot went effectively, you’ve obtained a message stating that you simply obtained an authorization token.


Let’s begin with the studies


Report Mailbox sizes

The Report module incorporates a number of cmdlets for mailboxes. You may see which cmdlets exist by working the cmdlet under.

Get-Command -name "*Mailbox*" -Module 'Optimized.Mga.Report'

In concept, you can run all of them to see what info they return. These instructions are purely about studies and you cannot change something in your tenant with these cmdlets.

Play with all of it you need, however the cmdlet we want now could be Get-MgaReportMailboxUsageDetail.

Get-MgaReportMailboxUsageDetail

LastActivityDate             : 2022-04-01
CreatedDate                  : 2022-03-31
ItemCount                    : 63
DeletedItemSizeInGb          : 0
DisplayName                  : Bas Wijdenes
UserPrincipalName            : [email protected]
HasArchive                   : True
IsDeleted                    : False
ProhibitSendQuotaInGB        : 99
ProhibitSendReceiveQuotaInGb : 100
SizeInGb                     : 0
IssueWarningQuotaInGB        : 98
DeletedItemCount             : 46
DeletedItemQuotaInGb         : 30

I’ve shortened the response above to 1 person. You’ll most likely see extra customers.

The Gb is calculated robotically from the bytes within the backend. You may acknowledge this from the ‘InGb’ within the property identify. At 0 Gb it means there are so few gadgets in it that it’s robotically calculated at 0 Gb.

I’d love to listen to your suggestions on whether or not you’d nonetheless like to incorporate the bytes.
I’m not going to transform it from Bytes to Kb, Mb, AND Gb, since a mailbox might comprise 100Gb, bytes, Kbs, and Mbs are negligible, however it is likely to be higher to incorporate the unique bytes as effectively.

After we obtain the response in a variable, we are able to make a report of this, or mix it with, for instance… the OneDrive measurement.

$MailboxSizes = Get-MgaReportMailboxUsageDetail

Report OneDrive Sizes

The Report module incorporates a number of cmdlets for OneDrive as effectively. You may see which cmdlets exist by working the cmdlet under.

Get-Command -name "*OneDrive*" -Module 'Optimized.Mga.Report'

You may check them once more if you need, however the cmdlet we want now could be Get-MgaReportMailboxUsageDetail.

Get-MgaReportOneDriveUsageAccountDetail

SiteUrl           : XXXXXXXXXX
AllocatedSizeInGb : 1024
SizeInGb          : 0,03
UserPrincipalName : [email protected]
FreeSizeInGb      : 1023,97
FileCount         : 15
ActiveFileCount   : 0
LastActivityDate  : 2022-04-01
IsDeleted         : False
DisplayName       : Bas Wijdenes

And with this cmdlet the identical story as with Get-MgaReportMailboxUsageDetail. The bytes have been transformed to Gb. I’m curious whether or not you like to see the unique worth or whether or not it’s tremendous in Gb.

And let’s put it in a variable once more.

$OneDriveSizes = Get-MgaReportOneDriveUsageAccountDetail

Mailbox measurement & OneDrive measurement in a single report

We have now our information within the following variables $MailboxSizes & $OneDriveSizes.
Now we simply must put them collectively.

What essential is to me in my code, is velocity, optimization, and comprehensible scripting.

We are able to and can method this in numerous methods and I wish to present the variations right here.

In case you are solely in search of the most effective resolution, go to header: The entire script for probably the most optimized means.


Fairly obscure and a gradual resolution

What we are able to do is that we run via the $MailboxSizes with foreach after which we discover the OneDrive person with a The place-Object.

$Customers = @()
foreach ($MailboxSize in $MailboxSizes) {
    $CurrentOneDriveUser = $null
    $Person = New-Object PSObject
    $CurrentOneDriveUser = $OneDriveSizes | The place-Object { $_.UserPrincipalName -eq $MailboxSize.UserPrincipalName } 
    $Person | Add-Member -NotePropertyName 'UPN' -NotePropertyValue $MailboxSize.UserPrincipalName
    $Person | Add-Member -NotePropertyName 'MailboxSizeInGb' -NotePropertyValue $MailboxSize.SizeInGb
    $Person | Add-Member -NotePropertyName 'OneDriveSizeInGb' -NotePropertyValue $CurrentOneDriveUser.SizeInGb
    $Customers += $Person
}

With Add-Member you can also make customized objects with the property you discover helpful.

This script is gradual and tough to learn as a result of there are a number of instructions within the foreach loop.
I desire to reduce the instructions in a foreach loop as a result of that simply makes the script slower.
It’s best to first accumulate the massive numbers in a single go after which match them collectively.

A Measure-Command exhibits (10240 mailboxes): TotalSeconds : 29,7377941


The simplest to know, however a gradual resolution

We are going to run the identical foreach loop with the The place-Object once more, however take away the Add-Member this time.

This may be the entire script:

$Customers = @()
foreach ($MailboxSize in $MailboxSizes) {
    $CurrentOneDriveUser = $null
    $CurrentOneDriveUser = $OneDriveSizes | The place-Object { $_.UserPrincipalName -eq $MailboxSize.UserPrincipalName } 
    $Object = [PSCustomObject]@{
        UPN          = $MailboxSize.UserPrincipalName
        MailboxSize  = $MailboxSize.SizeInGb
        OneDriveSize = $CurrentOneDriveUser.SizeInGb
    }
    $Customers += $Object
}

I discover this a straightforward to learn script.

The one downside is that this isn’t optimized. What now occurs within the script is that we run via the The place-Object each time to search out the precise OneDrive. I presently solely have 20 mailboxes in my tenant, so it doesn’t matter a lot based mostly on time, however suppose you’ve 10000+ Mailboxes, this can save much more time.

Let’s check this by rising the $MailboxSizes array to 10240 mailboxes after which run a Measure-Command to check how lengthy this script takes: TotalSeconds : 8,1102409.

This isn’t too dangerous for me, however suppose you wish to add much more studies, and so on. then this isn’t the precise method by way of optimisation.

You wish to decrease the The place-Object‘s as effectively.


Most optimized approach to embrace each studies in a single

A The place-Object is gradual. You like to match through hashtables. The script can be a bit longer so readability can be harder, however the velocity is an enormous distinction, particularly on bigger tenants.

First we are going to convert the $OneDriveSizes to a hashtable. You are able to do that with the next script:

$OneDriveSizesHashTable = @{}
foreach ($OneDriveSize in $OneDriveSizes) {
    $OneDriveSizesHashTable.Add($OneDriveSize.UserPrincipalName, $OneDriveSize)
}

A foreach loop via variables or objects may be very quick even with a lot of objects. It’s because no different instructions are known as.

By utilizing the above script, your script can be bigger and due to this fact much less readable. For me it will be important that I perceive it myself, but in addition my fellow colleagues.

After which we undergo the $MailboxSizes once more and match on the hashtable as within the script under.

$ReportSizesHashTable = [System.Collections.Generic.List[Object]]::new()
foreach ($MailboxSize in $MailboxSizes) {
    $CurrentOneDriveUser = $null
    $CurrentOneDriveUser = $OneDriveSizesHashTable[$MailboxSize.UserPrincipalName]
    if ($null -ne $CurrentOneDriveUser) {
        $Object = [PSCustomObject]@{
            UPN          = $MailboxSize.UserPrincipalName
            MailboxSize  = $MailboxSize.SizeInGb
            OneDriveSize = $CurrentOneDriveUser.SizeInGb
        }
        $ReportSizesHashTable.Add($Object)
    }
}

A Measure-Command on 10240 mailboxes exhibits the distinction in velocity between these 3 methods: TotalSeconds : 0,2675163


The entire script for probably the most optimized means

$OneDriveSizesHashTable = @{}
foreach ($OneDriveSize in $OneDriveSizes){
$OneDriveSizesHashTable.Add($OneDriveSize.UserPrincipalName, $OneDriveSize)
}

$ReportSizesHashTable = [System.Collections.Generic.List[Object]]::new()
foreach ($MailboxSize in $MailboxSizes) {
    $CurrentOneDriveUser = $null
    $CurrentOneDriveUser = $OneDriveSizesHashTable[$MailboxSize.UserPrincipalName]
    if ($null -ne $CurrentOneDriveUser) {
        $Object = [PSCustomObject]@{
            UPN          = $MailboxSize.UserPrincipalName
            MailboxSize  = $MailboxSize.SizeInGb
            OneDriveSize = $CurrentOneDriveUser.SizeInGb
        }
        $ReportSizesHashTable.Add($Object)
    }
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments