Skip to content

Instantly share code, notes, and snippets.

@soulemike
soulemike / ServiceEM-Classification-Config.md
Last active October 12, 2026 05:56
Automatic Classification Config Generation

Automatic Classification Config Generation for ServiceEM

Summary

ServiceEM creates groups with a predictable naming convention, but classification reports require explicit tier metadata. Since groups do not support Custom Security Attributes (CSA), the only automatic classification path is AlternateObjectTierLevelAttributes.

This design adds an optional -UpdateClassificationConfig switch to landing-zone creation that automatically generates AlternateObjectTierLevelAttributes.Group filters from the ServiceEM naming convention and persists them to EntraOpsConfig.json. The implementation supports multiple runs with varying prefixes, merges without destroying existing filters, and an opt-in force overwrite for intentional replacement.


@soulemike
soulemike / PR67-PIM-Policy-Race-Condition-Recommendations.md
Created October 10, 2026 19:18
PR 67 Recommendation: Use `Wait-EntraOpsServiceEMCondition` to Fix PIM Policy Race Condition

PR 67 Recommendation: Use Wait-EntraOpsServiceEMCondition to Fix PIM Policy Race Condition

Date: 2026-10-10 Issue: New-EntraOpsServicePIMPolicy.ps1 fails intermittently on newly created groups due to Graph API eventual consistency Existing Solution: Wait-EntraOpsServiceEMCondition (already used throughout ServiceEM cmdlets)


1. Yes — The Existing Method Solves This Problem

@soulemike
soulemike / model-config-optimizer.md
Last active September 18, 2026 15:28
Model Config Optimizer Skill
name model-config-optimizer
description Optimize LLM model assignments across any agent harness using log-based usage analysis, pricing research, and ROI-driven selection. Prevents naive "upgrade everything" cost explosions.
category system-optimization
version 1.3.0

Model Configuration Optimizer

Optimize which LLM model each agent in a harness uses. Balance cost vs. capability using actual usage data rather than assumptions.

@soulemike
soulemike / linkedInPostSummary.ps1
Created October 13, 2025 17:19
For the provided list of LinkedIn activity URLs returns an array of hashtables, each containing the original activity URL, the HTML doc for the activity URL, the timestamp of the post, the post content, a shortened version of the post content, and an AI generated summary of the content.
$activities = @"
https://www.linkedin.com/feed/update/urn:li:activity:7383533745330618368
https://www.linkedin.com/feed/update/urn:li:activity:7383532739548979200
https://www.linkedin.com/posts/douglasfinke_ai-that-works-the-sf-unconference-is-under-activity-7383507297903206400-zvu0
"@
$activities = $activities.Split("`n")
$posts = @()
$regex = "[-:](?'id'[0-9]{19})[-\/?\$\s]"
@soulemike
soulemike / AzureArcFeatureMap.mermaid
Last active August 29, 2025 13:59
Azure Arc Feature Map
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@soulemike
soulemike / DefenderForServersMap.mermaid
Created August 27, 2025 17:12
Microsoft Defender for Servers Feature Map
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

If you have ever seen one of my presentations on or we have ever discussed technology security or operations, you have likely heard me say something like: At a certain maturity level everything is just exception management. Keep reading to get more details on one of the most common exception management techniques, compensatory or compensating controls.

What is a control?

The ComplianceForge team provides a nice definition:

"Controls are safeguards or countermeasures implemented to manage risks and protect assets. Cybersecurity controls can be technical, administrative, or physical and are designed to reduce vulnerabilities, prevent threats and ensure confidentiality, integrity and availability of information." (ComplianceForge, 2025)

In the simplest of terms your organization has said, "We care about X". The control documents what you are doing to protect "X".

function Update-MtLicenseCache {
[OutputType([System.Void])]
[CmdletBinding(
SupportsShouldProcess,
ConfirmImpact = "Low"
)]
param (
[Switch]$Force,
[String]$FileName="maesterLicenses.csv"
GraphActivity
| take 1000
| extend properties.timeGenerated, properties.appId, properties.roles, properties.scopes
| extend properties.requestUri, properties.requestMethod, properties.responseStatusCode
//
// Use to filter by App ID
//| where tostring(properties_appId) == "<AppId>"
//
// Use to summarize by app reg permissions used
//| where isnotempty(properties_roles)
function Connect-EntraIga {
[CmdletBinding()]
param (
[Parameter(ParameterSetName="All",Mandatory)]
[switch]$All,
[Parameter(ParameterSetName="Graph",Mandatory)]
[switch]$Graph,
[Parameter(ParameterSetName="All")]
[Parameter(ParameterSetName="Graph")]