Control 3.9: Microsoft Sentinel Integration - PowerShell Setup
This playbook provides PowerShell and KQL scripts for Control 3.9.
Prerequisites
# Install required modules
Install-Module -Name Az.SecurityInsights -Force -AllowClobber
Install-Module -Name Az.OperationalInsights -Force -AllowClobber
# Connect to Azure
Connect-AzAccount
Select-AzSubscription -SubscriptionId "your-subscription-id"
KQL Queries for Agent Monitoring
Unusual Agent Data Access Pattern
// Detect unusual agent data access patterns
let baseline = materialize(
OfficeActivity
| where TimeGenerated > ago(30d) and TimeGenerated < ago(1d)
| where UserId contains "agent" or ApplicationName contains "Copilot"
| summarize AvgAccess = count() / 30.0 by UserId
);
OfficeActivity
| where TimeGenerated > ago(1h)
| where UserId contains "agent" or ApplicationName contains "Copilot"
| summarize CurrentAccess = count() by UserId
| join kind=inner baseline on UserId
| where CurrentAccess > AvgAccess * 3
| project
UserId,
CurrentAccess,
Baseline = round(AvgAccess, 0),
Deviation = round(CurrentAccess / AvgAccess, 1)
Agent DLP Violation Detection
// Detect DLP violations by AI agents
// Note: Use CloudAppEvents or MicrosoftPurviewInformationProtection table
// DlpAll is not a valid table name in Log Analytics
CloudAppEvents
| where TimeGenerated > ago(1h)
| where ActionType has_any ("DlpRuleMatch", "DlpPolicyMatch")
| where AccountDisplayName contains "agent" or AccountDisplayName contains "copilot" or AccountDisplayName contains "bot"
| summarize
ViolationCount = count(),
Policies = make_set(PolicyMatchInfo),
Applications = make_set(Application)
by AccountDisplayName
| where ViolationCount > 0
| order by ViolationCount desc
Alternative: MicrosoftPurviewInformationProtection Table
If using Microsoft Purview data connector, you can also query
MicrosoftPurviewInformationProtection for DLP events with richer policy details.
After-Hours Agent Activity
// Detect agent activity outside business hours
let BusinessHoursStart = 7;
let BusinessHoursEnd = 19;
OfficeActivity
| where TimeGenerated > ago(24h)
| where UserId contains "agent" or ApplicationName contains "Copilot"
| extend LocalHour = datetime_part("hour", TimeGenerated)
| where LocalHour < BusinessHoursStart or LocalHour > BusinessHoursEnd
| summarize
OffHoursEvents = count(),
Operations = make_set(Operation)
by UserId, bin(TimeGenerated, 1h)
| where OffHoursEvents > 10
Agent Data Exfiltration Pattern
// Detect potential data exfiltration by agents
OfficeActivity
| where TimeGenerated > ago(1h)
| where UserId contains "agent" or ApplicationName contains "Copilot"
| where Operation in ("FileDownloaded", "FileSyncDownloadedFull", "FileAccessed")
| summarize
FileCount = count(),
TotalSize = sum(tolong(FileSize)),
UniqueFiles = dcount(OfficeObjectId)
by UserId, bin(TimeGenerated, 15m)
| where FileCount > 50 or TotalSize > 100000000
PowerShell: Create Analytics Rule
function New-AgentAnalyticsRule {
param(
[Parameter(Mandatory=$true)]
[string]$WorkspaceName,
[Parameter(Mandatory=$true)]
[string]$ResourceGroupName,
[string]$RuleName = "Unusual Agent Data Access",
[string]$Severity = "Medium"
)
Write-Host "Creating analytics rule: $RuleName" -ForegroundColor Cyan
$query = @'
let baseline = materialize(
OfficeActivity
| where TimeGenerated > ago(30d) and TimeGenerated < ago(1d)
| where UserId contains "agent" or ApplicationName contains "Copilot"
| summarize AvgAccess = count() / 30.0 by UserId
);
OfficeActivity
| where TimeGenerated > ago(1h)
| where UserId contains "agent" or ApplicationName contains "Copilot"
| summarize CurrentAccess = count() by UserId
| join kind=inner baseline on UserId
| where CurrentAccess > AvgAccess * 3
'@
$ruleParams = @{
ResourceGroupName = $ResourceGroupName
WorkspaceName = $WorkspaceName
DisplayName = $RuleName
Enabled = $true
Severity = $Severity
Query = $query
QueryFrequency = "PT5M"
QueryPeriod = "PT1H"
TriggerOperator = "GreaterThan"
TriggerThreshold = 0
}
try {
New-AzSentinelAlertRule @ruleParams -Kind Scheduled
Write-Host "Rule created successfully" -ForegroundColor Green
}
catch {
Write-Error "Failed to create rule: $_"
}
}
PowerShell: Get Agent-Related Incidents
function Get-AgentSecurityIncidents {
param(
[Parameter(Mandatory=$true)]
[string]$WorkspaceName,
[Parameter(Mandatory=$true)]
[string]$ResourceGroupName,
[int]$DaysBack = 7
)
Write-Host "Retrieving agent-related incidents..." -ForegroundColor Cyan
$incidents = Get-AzSentinelIncident -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName
$agentIncidents = $incidents | Where-Object {
$_.Title -like "*agent*" -or
$_.Title -like "*copilot*" -or
$_.Title -like "*bot*"
}
Write-Host "Found $($agentIncidents.Count) agent-related incidents" -ForegroundColor Green
$agentIncidents | Select-Object Title, Severity, Status, CreatedTimeUtc | Format-Table
return $agentIncidents
}
PowerShell: Export Sentinel Report
function Export-SentinelAgentReport {
param(
[Parameter(Mandatory=$true)]
[string]$WorkspaceId,
[int]$DaysBack = 30,
[string]$OutputPath = ".\SentinelAgentReport-$(Get-Date -Format 'yyyyMMdd').html"
)
Write-Host "Generating Sentinel agent report..." -ForegroundColor Cyan
# Query Log Analytics
$query = @"
OfficeActivity
| where TimeGenerated > ago($($DaysBack)d)
| where UserId contains "agent" or ApplicationName contains "Copilot"
| summarize
TotalEvents = count(),
UniqueAgents = dcount(UserId),
UniqueOperations = dcount(Operation)
| project TotalEvents, UniqueAgents, UniqueOperations
"@
$result = Invoke-AzOperationalInsightsQuery -WorkspaceId $WorkspaceId -Query $query
$html = @"
<!DOCTYPE html>
<html>
<head>
<title>Sentinel Agent Activity Report</title>
<style>
body { font-family: 'Segoe UI', sans-serif; margin: 40px; }
h1 { color: #0078d4; }
.metric { display: inline-block; padding: 20px; background: #f0f0f0; border-radius: 8px; margin: 10px; }
</style>
</head>
<body>
<h1>Microsoft Sentinel - Agent Activity Report</h1>
<p>Period: Last $DaysBack days | Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm')</p>
<div class="metric">
<h3>Total Events</h3>
<p style="font-size: 28px;">$($result.Results[0].TotalEvents)</p>
</div>
<div class="metric">
<h3>Unique Agents</h3>
<p style="font-size: 28px;">$($result.Results[0].UniqueAgents)</p>
</div>
</body>
</html>
"@
$html | Out-File $OutputPath -Encoding UTF8
Write-Host "Report generated: $OutputPath" -ForegroundColor Green
}
Usage Examples
# Create analytics rule
New-AgentAnalyticsRule -WorkspaceName "sentinel-workspace" -ResourceGroupName "rg-security"
# Get agent incidents
Get-AgentSecurityIncidents -WorkspaceName "sentinel-workspace" -ResourceGroupName "rg-security"
# Export report
Export-SentinelAgentReport -WorkspaceId "workspace-guid"
Next Steps
- Portal Walkthrough - Manual configuration
- Verification & Testing - Test procedures
- Troubleshooting - Common issues
Updated: January 2026 | Version: v1.2