Skip to content

Instantly share code, notes, and snippets.

@joerodgers
joerodgers / Test-EntraAccessTokenSignature.ps1
Last active March 15, 2026 09:30
Validates the signature of an Entra access token
function ConvertFrom-Base64Url
{
param
(
[Parameter(Mandatory = $true)]
[string]
$InputString,
[Parameter(Mandatory = $false,ParameterSetName="AsString")]
@joerodgers
joerodgers / New-PublicClientApplicationAccessToken.ps1
Created March 11, 2026 16:56
Uses Microsoft.Identity.Client assembly loaded via the "Microsoft.PowerApps.Administration.PowerShell" module to generate an Entra access token
#requires -modules "Microsoft.PowerApps.Administration.PowerShell"
$clientId = $env:CDX_CLIENTID
$tenantId = $env:CDX_TENANTID
[string[]]$scopes = "https://api.powerplatform.com/.default", "openid", "profile offline_access"
$pca = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($clientId).WithAuthority( "https://login.microsoftonline.com/$tenantId", $true).
WithRedirectUri( "http://localhost" ).
Build()
@joerodgers
joerodgers / Invoke-GraphThreatHuntingQuery.ps1
Last active March 9, 2026 15:10
Example how to leverage Microsoft 365 Defender Graph Threat Hunting endpoint to query for Copilot Interactions in an tenant.
#requires -Modules "Microsoft.Graph.Authentication"
function Invoke-GraphThreatHuntingQuery
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$true)]
$HuntingQuery,
@joerodgers
joerodgers / DefenderAdvancedHunting_KQL.kql
Last active February 4, 2026 16:09
Example queries reporting an agent usage using the CloudAppEvents table in Defender Advanced Hunting
// ALL AGENT INTERACTIONS PER HOUR
CloudAppEvents
| extend AgentName = tostring((RawEventData).AgentName)
| extend UserName = tostring((RawEventData).UserId)
| where ActionType == 'CopilotInteraction'
| where isnotempty(parse_json(RawEventData).AgentName)
| summarize InteractionsPerHour = count() by UserName, DateHour = format_datetime(bin(datetime_utc_to_local(Timestamp,"America/New_York"), 1h), 'yyyy-MM-dd hh:mm:ss'), AgentName
| project ['Date/Hour (Eastern)'] = DateHour, UserName, AgentName, InteractionsPerHour
| order by ['Date/Hour (Eastern)'], InteractionsPerHour desc
@joerodgers
joerodgers / OnGeneratedResponse-Citations.yml
Created December 15, 2025 22:23
Copilot Studio YAML example for custom citations using the OnGeneratedResponse topic
kind: AdaptiveDialog
beginDialog:
kind: OnGeneratedResponse
id: main
priority: 1
actions:
- kind: ConditionGroup
id: has-answer-conditions
conditions:
- id: has-answer
@joerodgers
joerodgers / Set-PowerPlatformEntraHttpConnectionCertificate.ps1
Created December 9, 2025 17:02
Updates the pfx value, password and ClientId of a Entra HTTP Preauthorized connection
#requires -modules "Microsoft.PowerApps.Administration.PowerShell"
function Get-PowerPlatformEntraHttpConnection
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$true)]
[string]
$EnvironmentId,
#requires -modules "PnP.PowerShell"
# requires SharePoint > application > sites.fullcontrol.all permissions
$sites = "https://m365cpi68930152.sharepoint.com/sites/security-policies1",
"https://m365cpi68930152.sharepoint.com/sites/security-policies2"
$timestamp = Get-Date -Format FileDateTime
foreach( $site in $sites )
#requries -modules "Microsoft.PowerApps.Administration.PowerShell"
function Get-AuthorizationHeader
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$true)]
[string]
$EnvironmentUrl
@joerodgers
joerodgers / UserProfilePropertyCache.yaml
Created October 14, 2025 15:13
Example Copilot Studio Topic showing how to cache User Profile properties in a global record variable for 24 hours
kind: AdaptiveDialog
beginDialog:
kind: OnActivity
id: main
condition: =DateDiff(DateAdd(Coalesce(Global.UserProfile.LastRefreshed,Now()), 1440, TimeUnit.Minutes), Now(),TimeUnit.Minutes) > 0
type: Message
actions:
- kind: BeginDialog
id: 0FnaSJ
input: {}
@joerodgers
joerodgers / Test-VNETAppInsightsConnectivity.ps1
Last active November 5, 2025 17:50
Example script for testing DNS and connectivity to the Application Insights from a Power Platform environment connected to a customer managed Azure subnet via enterprise policy
Import-Module -Name "Microsoft.PowerPlatform.EnterprisePolicies" -ErrorAction Stop
Connect-AzAccount
$tenantId = "<YOUR TENANT ID>"
$environmentId = "<ENVIRONMENT ID>"
$hostname = "dc.services.visualstudio.com"
Test-DnsResolution `
-EnvironmentId $environmentId `