Introduction
You may have heard that things are better in the cloud, that they reduce your costs and time to manage. However, in order to achieve these benefits in a shared system, Microsoft has to make certain changes so that their systems are more efficient and cost effective, something they can then pass on to their customers. When it comes to PowerShell we see this displayed in a few outward ways as we run scripts and cmdlets to do our tasks. One of these methodologies is the concept of Paging. Paging is a form of throttling where only a certain subset of data, a page, is displayed or returned as a result of a query.
For illustrative purposes, let’s say that a query returns 30 results and each page is limited to 10 results. Each page would contain 10 values of the 30 found and would be logically organize like this (Page 1 to Page 3):
Most cmdlets default to 100 results and show only the first page when queried. For cmdlets limited in this way, we can specify the page size (1-1000) as well as how many pages to display (1-1000). So we can display up to 1,000,000 results which is find for most environments. If this size is a limiting factor, some cmdlets have other filters where the results returned can be restricted to under 1,000,000.
Let’s explore a couple of cmdlets to see how this can be used and changed depending on the number of results.
Cmdlet Examples with Paging Options
For this part of the post we will cover a couple of cmdlets that use this option to control the display a queries results. So, without further ado:
Get-MessageTrace
We use the Get-MessageTrace to track down emails (inbound and outbound) for various reasons – if they were delivered, blocked , etc. How do we know paging is present?
As we can see, page one consists of 1000 messages, which is the default page size for this cmdlet. The second page consists of 636 messages, which is under the 1000 message default and if we try to use a page value of 3, it should fail provide a result of zero:
The reason why this is useful is if you have a large environment and need to find a message, you run a query, and find no results, you may think that using ‘ResultSize’ as a parameter will work. However, no such parameter exists for the Get-MessageTrace cmdlet. Also, in a larger environment, the 1000 pages of 1000 messages may not be enough which means increasing the PageSize value to a value up to the max of 5000. If that isn’t enough, then further filtering must be performed.
Large Environment
Take for example, a real world scenario we can examine how many messages were filtered as SPAM by EOP before they get delivered to these same 30,000 EDU users. First, we need to set the timeframe to be used, pagesize andsome variables to handle discovery.
# Variable Block $Page = 1 $PageSize = 5000 $TotalCount = 0 $Start = '11/29/22 12:01AM' $End = '12/03/22 11:59PM'
With this in hand, we can now loop the cmdlet, searching each page of messages for SPAM messages.
Do { $n = 1 $Results = Get-MessageTrace -StartDate $Start -EndDate $End -page $page -PageSize $PageSize | where {$_.status -eq 'FilteredAsSpam'} $Results2 = Get-MessageTrace -StartDate $Start -EndDate $End -page $page -PageSize $PageSize If ($Results2 -eq $Null) { $page = 1001 } Else { $Results2[0].Received $Count = $Results.Count Write-Host "Found $Count SPAM messages." -ForegroundColor Cyan Write-Host "Page Number - $Page" -ForegroundColor Yellow $Page++ } } While ($Page -lt 1000)
Results would look like this:
Now we have EOP spam filtered results, from each page from the Message Trace. If further investigation is needed, we can dive into each page.
Get-QuarantineMessage
In this example, we run into a similar situation where the potential is there for larger environments to his either the page limit or page size limit. We can work around both of these like so:
$Page = 1 $PageSize = 5000 Do { $Messages = Get-QuarantineMessage -Page $Page -PageSize $PageSize If ($Messages -ne $Null ) { Write-Host "Page $Page" -ForegroundColor Yellow $Messages $Page++ } Else { $Pages = 1001 } $Messages = $Null } While ($Pages -lt 1001)
With this code, the Get-QuarantineMessage cmdlet will list each set of 5000 messages with a page separator which will allow the administrator to go pick a particular message from a particular page. Sample output:
So we can see each page will show a different part of the overall results. Key to this working, without wasting cycles, is the check to see if the $Message variable is empty or null because if it is then the script can exit as no more messages will be found.
Finding Cmdlets with Paging
In a future Post, I will post code for finding all cmdlets in Exchange Online, for Example, that use Paging and have both Page and PageSize parameters. Look for the post in my Quick PowerShell Post of the Week on Feb 22, 2023.
———————————————————————————————————–
Comments? Questions?
Feel free to leave your Comments below! Learn to more efficiently utilize PowerShell to manage Exchange Server, Exchange Online, Microsoft Defender for Office or Microsoft Purview Compliance portals by picking up frequently updated eBooks: