Skip to content

Instantly share code, notes, and snippets.

View bill-long's full-sized avatar

Bill Long bill-long

  • Microsoft
View GitHub Profile
#Requires -Modules Microsoft.Graph, Microsoft.Graph.Users.Actions
Connect-MgGraph -Scopes "User.Read.All", "Mail.ReadBasic", "Mail.Read", "Mail.ReadWrite" -DeviceAuth -ContextScope Process
$userId = (Invoke-MgGraphRequest -Uri "v1.0/me")["id"]
# Only returns 10 items by default
Get-MgUserMessage -UserId $userId | ft ReceivedDateTime,Subject
# You can filter for stuff older than a certain date
Get-MgUserMessage -UserId $userId -Filter "ReceivedDateTime lt 2023-01-25" | ft ReceivedDateTime,Subject
@bill-long
bill-long / GetSignedXmlResponseCerts.ps1
Last active October 11, 2022 21:15
Intended to help diagnose the following error from Exchange Mitigation Service: "This XML is not deemed safe to consume since Response xml''s signing cert is invalid or not from microsoft""
$url = "https://officeclient.microsoft.com/getexchangemitigations"
$r = Invoke-WebRequest $url
$x = [xml]$r.Content
$signedXml = New-Object System.Security.Cryptography.Xml.SignedXml($x)
$sigNode = $x.GetElementsByTagName("Signature")
$signedXml.LoadXml([System.Xml.XmlElement] ($sigNode[0]))
$signedXml.Signature.KeyInfo.Certificates | Format-List
$signedXml.Signature.KeyInfo.Certificates | ForEach-Object {
@bill-long
bill-long / Test-AutoDiscover.ps1
Created October 4, 2022 20:23
Super simple AutoDiscover test. Does not attempt to encapsulate all of Outlook's logic.
[CmdletBinding()]
param (
[Parameter()]
[string]
$HostName,
[Parameter()]
[string]
$EmailAddress
)
[CmdletBinding()]
param (
[Parameter()]
[int]
$PercentCPUThreshold = 80,
[Parameter()]
[int]
$DurationMilliseconds = 10000
)
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]
$Mailbox,
[Parameter(Mandatory = $true)]
[string]
$MID
)
Get-ExchangeServer | Where-Object { $_.admindisplayversion -notlike "*14.*" -and $_.admindisplayversion -notlike "*15.0*" } | ForEach-Object {
$server = $_
[xml]$result = Get-ExchangeDiagnosticInfo $Server -Process EdgeTransport -Component ResourceThrottling
$bp = $result.Diagnostics.Components.ResourceThrottling.ResourceTracker.ResourceMeter | Where-Object { $_.CurrentResourceUse -notlike "low" }
$bp | ForEach-Object { Add-Member -InputObject $_ -MemberType NoteProperty -Name "Server" -Value $server }
$bp
} | Format-Table Server, CurrentResourceUse, Resource
function FindConnectionsWithoutSTARTTLS {
param(
$LocalEndpoint,
[Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[Alias('FullName')]
[string[]]$LogFile,
$Header = @('date-time', 'connector-id', 'session-id', 'sequence-number', 'local-endpoint', 'remote-endpoint', 'event', 'data', 'context')
)
@bill-long
bill-long / ParseRCALogExamples.ps1
Last active September 23, 2021 23:00
RpcClientAccess log parse examples for MapiExceptionRpcServerTooBusy
# Show MapiExceptionRpcServerTooBusy count by file
Get-ChildItem *.log | Sort-Object LastWriteTime | % {
$count = (sls "MapiExceptionRpcServerTooBusy" $_).Count
[PSCustomObject]@{ File = $_.Name; LastWrite = $_.LastWriteTime; Count = $count }
} | ft
# Show MapiExceptionRpcServerTooBusy count by hour
sls "^(\S+?),.*MapiExceptionRpcServerTooBusy" *.log | % {
@bill-long
bill-long / Export-PublicFolderHierarchy.ps1
Last active August 4, 2021 04:40
Exports all Public Folders and System Folders. If the script is interrupted, just run it again and it will resume.
[CmdletBinding()]
param (
[Parameter()]
[string[]]
$Properties = @("Identity", "EntryId", "DumpsterEntryId", "FolderSize", "FolderClass"),
[Parameter()]
[string]
$OutputFile = "$PSScriptRoot\PFHierarchy.csv"
)
# Note that this assumes we're running from the folder with the EWS logs in it.
# Choose the most recent 50 logs
Get-ChildItem *.log | Sort-Object LastWriteTime -Descending | Select-Object -First 50 | ForEach-Object { Import-Csv $_ } | Where-Object { $_.SoapAction -like "Resolve*"} | ForEach-Object {
# Produce a new object that only has the fields we care about
# One important part of this is we are converting the time and request times from strings into sortable values
[PSCustomObject]@{
DateTime = [DateTime]::Parse($_.DateTime)
ClientIpAddress = $_.ClientIpAddress
AuthenticatedUser = $_.AuthenticatedUser
UserAgent = $_.UserAgent