Skip to content

Instantly share code, notes, and snippets.

View JustinGrote's full-sized avatar

Justin Grote JustinGrote

View GitHub Profile
@JustinGrote
JustinGrote / Find-MissingPSGalleryPackages.ps1
Created July 2, 2026 03:43
Search for packages not on the PowerShell Gallery
using namespace System.Management.Automation
using namespace System.Collections.Generic
using namespace System.Collections.Concurrent
$baseUri = 'https://www.powershellgallery.com/api/v2/Packages?$orderby=Published desc&$skip='
$maxPackages = 700000
$interval = 100
$statusDictionary = [ConcurrentDictionary[string, bool]]::new()
$existingpackagesjson = (iwr 'https://pwsh.gallery/sleet.packageindex.json').content -replace 'PSObject','__MODULEFASTIGNOREME' | convertfrom-json |% packages
@JustinGrote
JustinGrote / Get-KerberosRC4Events.ps1
Last active June 24, 2026 19:04
Get Kerberos RC4 usage events
using namespace System.Diagnostics.Eventing.Reader
[CmdletBinding(DefaultParameterSetName = 'ByCount')]
param(
#A list of domain controllers to query. Leave blank if running directly on a domain controller.
[string[]]$ComputerName,
#Maximum amount of events to retrieve. This is set to 1000 for a quick initial fetch. Note this is max events *investigated* and not max events returned.
[Parameter(ParameterSetName = 'ByCount')]
[int]$MaxEvents = 1000,
@JustinGrote
JustinGrote / Get-LdapUnsigned.ps1
Created June 23, 2026 19:02
Fetch LDAP Unsigned Events
[CmdletBinding(DefaultParameterSetName = 'ByCount')]
param(
#A list of domain controllers to query. Leave blank if running directly on a domain controller.
[string[]]$ComputerName,
#Maximum amount of events to retrieve. This is set to 1000 for a quick initial fetch. Note this is max events *investigated* and not max events returned.
[Parameter(ParameterSetName = 'ByCount')]
[int]$MaxEvents = 1000,
#How long back to search for events. Overrides MaxEvents if specified.
@JustinGrote
JustinGrote / Get-ExchangeSmtpSessions.ps1
Created May 20, 2026 23:21
Fetch and Parse Exchange Onprem Receive Connector Logs to find SMTP Senders
param(
[Parameter(Mandatory = $true)]
[string[]]$ExchangeServers,
[Parameter(Mandatory = $true)]
[PSCredential]$Credential,
[Parameter(Mandatory = $false)]
[datetime]$StartTime = (Get-Date).AddDays(-1),
@JustinGrote
JustinGrote / Find-CidrPolicyUpdates.kql
Last active April 22, 2026 00:22
Find the changes in an Azure Conditional Access Named Location when so many records exist it uses CompressedCidrIPRanges instead of CidrIPRanges
// The complete data we need gets split over multiple logs, so we have to recombine them. Export to CSV afterwards.
AuditLogs
| where OperationName == "Update policy"
| where isnotempty(CorrelationId) and isnotempty(AdditionalDetails)
| project TimeGenerated, CorrelationId, Identity, AdditionalDetails
| mv-apply d = AdditionalDetails on (
summarize
seq = tolong(take_anyif(tostring(d.value), tostring(coalesce(d.key, d.name)) == "seq")),
b = take_anyif(tostring(d.value), tostring(coalesce(d.key, d.name)) == "b")
@JustinGrote
JustinGrote / MSPartnerBenefits.psm1
Created June 10, 2025 21:17
Scrape the Microsoft Partner Benefits AI for all redeemable Product Keys
#You will have to screen-scrape your bearer token and account GUID from the DevTools
$script:BaseUri = 'https://api.partnerbenefits.microsoft.com'
function Connect-PartnerBenefit {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[securestring]$ApiKey,
#Will connect to partner global account by default, specify this to choose a different account
[string]$AccountId
)
@JustinGrote
JustinGrote / Get-ExoParallelContext.ps1
Created April 17, 2025 21:56
Exchange Online Commands in Parallel
#This function gathers the login context from the .NET type and shows how you can pass that into Foreach -Parallel in order to run in parallel without using an AppID/Secret
#You must be connected to Exchange Online PowerShell
<#
.SYNOPSIS
Prepares the environment to use EXO cmdlets in parallel
#>
@JustinGrote
JustinGrote / ProfileBenchmark.ps1
Last active September 11, 2025 12:58
Benchmark your profile using Profiler
#region ProfileBenchmark
if ($ENV:PWSH_PROFILE_BENCHMARK -and -not $ENV:PWSH_PROFILE_BENCHMARK_RUN) {
Write-Host -Fore Magenta '👷‍♂️ BENCHMARKING PROFILE SETUP'
Invoke-WebRequest bit.ly/modulefast | Invoke-Expression
Install-ModuleFast profiler
# This will ensure we don't end up in a setup loop
Write-Host -Fore Magenta '📈 BENCHMARKING PROFILE'
$profilePath = $MyInvocation.MyCommand.Source
$profileTrace = Trace-Script -ExportPath TEMP:/pwsh-profile -ScriptBlock {
@JustinGrote
JustinGrote / Debug.Tests.ps1
Last active November 27, 2024 18:56
PowerShell Debugging Examples
Describe "Debugging Examples" {
It 'Labs get Treats' {
$recommendedTreat = & $PSScriptRoot/Get-DogTreat.ps1 -DogBreed 'Labrador' -SuperBugged
$recommendedTreat.Calories | Should -BeGreaterThan 0
}
}
@JustinGrote
JustinGrote / Get-InstalledModuleFast.ps1
Last active October 16, 2024 19:09
Get info about locally installed PowerShell modules
function Get-InstalledModuleFast {
param(
#Modules to filter for. Wildcards are supported.
[string]$Name,
#Path(s) to search for modules. Defaults to your PSModulePath paths
[string[]]$ModulePath = ($env:PSModulePath -split [System.IO.Path]::PathSeparator),
#Return all installed modules and not just the latest versions
[switch]$All
)