Security automation playbooks, scripts, and pipelines for Azure and Microsoft Sentinel. Automates incident response, threat hunting, and security operations workflows.
Built by a Cybersecurity Architect to eliminate manual, repetitive security tasks and reduce mean time to respond (MTTR) in enterprise environments.
Security teams spend 60–70% of their time on repetitive tasks that can be automated: alert triage, enrichment, containment actions, and reporting. This repository contains production-tested automation that directly reduces analyst toil.
Every automation in this repository:
- Has a defined trigger (manual, scheduled, or alert-based)
- Is idempotent (safe to run multiple times)
- Logs all actions for audit purposes
Has defined rollback or undo procedures where applicable
- Includes error handling that fails safely, not silently
Security automation fails for three reasons:
- Automation without context: Scripts that fire on alerts without enrichment, generating false positive containment actions that break production
- No error handling: Automation that silently fails, leaving analysts with a false sense of coverage
Undocumented assumptions: Automations that work in one environment but fail in another because environment-specific variables are hardcoded
This repository addresses all three. Every automation includes enrichment steps before action, explicit error handling, and documented configuration requirements.
security-automation/ ├── sentinel-playbooks/ │ ├── incident-response/ │ │ ├── ip-enrichment-virustotal.json # Enrich IP with VirusTotal on incident creation │ │ ├── user-disable-on-high-risk.json # Disable Entra ID user on High risk alert │ │ └── isolate-vm-on-alert.json # Isolate VM via Defender for Endpoint │ └── threat-hunting/ │ ├── scheduled-hunt-runner.json # Weekly automated threat hunt scheduler │ └── ioc-sweep.json # IOC sweep across all logs on demand ├── powershell/ │ ├── entra-id/ │ │ ├── Get-StaleAccounts.ps1 # Find inactive accounts for access review │ │ └── Set-ConditionalAccessReport.ps1 # Export CA policy state to CSV │ ├── azure-security/ │ │ ├── Get-StoragePublicAccess.ps1 # Audit public storage accounts at scale │ │ └── Enable-DefenderForCloud.ps1 # Enable Defender plans across subscriptions │ └── sentinel/ │ ├── Export-IncidentMetrics.ps1 # Weekly incident metrics for reporting │ └── Sync-WatchlistFromCSV.ps1 # Update Sentinel watchlists from CSV source ├── kql-hunting-queries/ │ ├── identity/ │ │ └── stale-admin-accounts.kql # Admins with no sign-in in 30+ days │ ├── network/ │ │ └── firewall-top-blocked-ips.kql # Top blocked IPs from Azure Firewall logs │ └── cloud/ │ └── resource-creation-anomaly.kql # Unusual resource creation patterns ├── docs/ │ ├── playbook-design-guide.md # Standards for building Sentinel playbooks │ └── automation-decision-matrix.md # When to automate vs. human-in-the-loop └── README.md
Playbook Trigger Action Risk Level Status IP Enrichment — VirusTotal Incident creation Enrich IP entities with VT reputation Low 🗓️ Planned User Disable — High Risk Sentinel alert Disable Entra ID account, revoke sessions High 🗓️ Planned VM Isolation — MDE Sentinel alert Isolate endpoint via Defender for Endpoint API High 🗓️ Planned IOC Sweep Manual / Scheduled Run IOC KQL query across all log tables Medium 🗓️ Planned
Script Purpose Schedule Status Get-StaleAccounts.ps1 Find accounts inactive 30+ days Weekly 🗓️ Planned Get-StoragePublicAccess.ps1 Audit all storage accounts for public access Monthly 🗓️ Planned Export-IncidentMetrics.ps1 Weekly Sentinel incident metrics report Weekly 🗓️ Planned Enable-DefenderForCloud.ps1 Enable all Defender plans in new subscription On-demand 🗓️ Planned
Not all automation should be fully automated. The risk classification:
Low Risk → Fully automated (enrichment, notification, tagging) Medium Risk → Automated with Teams/email approval gate High Risk → Automation prepares context, human approves action Critical → Human-only (account deletion, firewall rule changes)User account disablement and VM isolation are classified as High Risk because both can cause immediate production impact if triggered on a false positive. These playbooks include an approval step.
Every script and playbook must be safe to run multiple times. Requirements:
- Check current state before making changes (does the account already exist? is the VM already isolated?)
- Log "no action needed — already in desired state" rather than failing
Never fail destructively (e.g., deleting a resource that already does not exist)
All automation logs to a central Log Analytics workspace table (
SecurityAutomation_CLcustom table or built-in Azure Monitor logs). Minimum log fields:
- Timestamp
- AutomationName
- TriggeredBy (incident ID, scheduled job ID, or manual operator)
- TargetResource (user, IP, VM, storage account)
- ActionTaken
ActionResult (Success / Failed / Skipped)
- ErrorDetails (if failed)
- All playbooks use Managed Identity for Azure API calls — no stored credentials
- Logic App Managed Identities are scoped to minimum required permissions (not Contributor on subscription)
- PowerShell scripts require explicit Azure module installation — never use automatic module install in production pipelines
- KQL hunting queries are read-only — no action capabilities
API connectors (VirusTotal, external threat intel) use dedicated service accounts, not personal accounts
- All automation changes are logged and tied to a ticket/incident ID for audit trail
Surya | Cybersecurity Architect | CISSP
Specializing in Microsoft Sentinel, Security Automation, and Azure Security.
86sunbot/security-automation
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|