Pipeline Configuration
Configure scan schedule, commit behavior, inventory storage, module versions, and more.
Quick Reference
| Setting | File | Default | Purpose |
|---|---|---|---|
| Schedule (cron) | monitor-pipeline.yml / .github/workflows/scan.yml | 0 */6 * * * | How often scan runs |
| Inventory path | src/Scan-PimState.ps1 | ./inventory/ | Where state is stored |
| Commit message | monitor-pipeline.yml / .github/workflows/scan.yml | ISO 8601 timestamp | Git commit format |
| Git author | src/git.ps1 | "PIM Monitor" | Author name |
| Module version | monitor-pipeline.yml / .github/workflows/scan.yml | 2.35.1 | PowerShell module version |
| HTML report | Pipeline variable | Unset | Generate scan report artifact |
| Expiring window | Pipeline variable | 14 days | Expiring assignment detection |
Schedule & Triggers
Change the scan schedule
Edit the cron expression in monitor-pipeline.yml (Azure DevOps) or .github/workflows/scan.yml (GitHub Actions):
Azure DevOps:
schedules:
- cron: "0 */6 * * *"
displayName: "PIM Change Scan (4x daily)"
branches:
include: [main]
always: true
GitHub Actions:
on:
schedule:
- cron: '0 */6 * * *'
Cron Pattern Guide
0 */6 * * * = Every 6 hours (default)
0 * * * * = Every hour
0 */3 * * * = Every 3 hours
0 9 * * * = Daily at 9 AM UTC
0 9 * * 1-5 = Weekdays at 9 AM UTC
0 0 * * 0 = Weekly (Sunday midnight UTC)
*/30 * * * * = Every 30 minutes
Why not every minute?
- Graph API throttling (429 errors on frequent requests)
- Noise reduction (PIM changes rarely occur every minute)
- Cost efficiency (fewer pipeline runs = lower compute costs)
Allow manual triggers
Azure DevOps:
trigger: none
pr: none
schedules:
- cron: "0 */6 * * *"
displayName: "PIM Change Scan"
branches:
include: [main]
always: true
Users can then click Run in the Azure DevOps UI without waiting for schedule.
GitHub Actions (enabled by default):
on:
schedule:
- cron: '0 */6 * * *'
workflow_dispatch: # Manual trigger
Commit & Repository
Change the commit message format
Edit the git step in monitor-pipeline.yml (Azure DevOps) or .github/workflows/scan.yml (GitHub Actions):
Current format (ISO 8601 timestamp):
git commit -m "scan: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
Example commit messages:
scan: 2026-04-27T18:42:15Z
chore: pim scan at 2026-04-27
feat: pim changes on 2026-04-27
SCAN: Daily security check
Any format works as long as it's unique enough to identify scans in git log.
Customize git commit author
Edit src/git.ps1 (lines ~33-34):
git config user.name "PIM Monitor"
git config user.email "pim-monitor@pipeline"
Change to:
git config user.name "Azure Security Team"
The name and email appear in git history and commit metadata.
Store inventory in a subfolder
Edit src/Scan-PimState.ps1 (line ~51):
$inventoryRoot = Join-Path -Path (Get-Location) -ChildPath "inventory"
Change to:
$inventoryRoot = Join-Path -Path (Get-Location) -ChildPath "security/pim-inventory"
Then update the git add step to match:
Azure DevOps monitor-pipeline.yml:
git add security/pim-inventory/ expected-changes.json 2>/dev/null || true
GitHub Actions .github/workflows/scan.yml:
git add security/pim-inventory/ expected-changes.json
Module & Dependencies
Pin Microsoft.Graph module version
The PowerShell pipeline uses Microsoft.Graph for Azure AD queries. You can pin a specific version.
Current default: 2.35.1
Edit in monitor-pipeline.yml (Azure DevOps, line ~14) or .github/workflows/scan.yml (GitHub Actions, line ~17):
variables:
MSGRAPH_VERSION: "2.35.1"
Change to:
variables:
MSGRAPH_VERSION: "2.36.0"
When to change:
- New Graph API features required
- Critical security patch released
- Compatibility issue with current version
- Microsoft deprecates the version
What happens:
- Pipeline cache key includes version
- Changing version automatically invalidates cache
- Module is re-downloaded on next run
- Previous version cache is kept for 7 days
How to check latest:
Find-Module Microsoft.Graph | Select-Object Version
Reporting & Artifacts
Enable HTML scan report artifact
Set REPORT_ARTIFACT=true in your pipeline variables.
Azure DevOps:
- Pipelines → PIM Monitor → Edit → Variables
- Add:
REPORT_ARTIFACT=true
GitHub Actions:
- Settings → Secrets and variables → Actions → Variables
- Add:
REPORT_ARTIFACT=true
The scan generates scan-report.html and publishes it as an artifact.
Report includes:
- Severity summary with counts
- All detected changes organized by severity
- Before/after diffs
- Tenant info and timestamp
- Commit SHA (if available)
See Reporting & Artifacts for details.
Expiring assignments window
Set EXPIRING_WINDOW_DAYS in your pipeline variables to control early warning for expiring PIM assignments.
Default: 14 days
Examples:
7= 1 week advance notice14= 2 weeks (default)30= 1 month
Assignments expiring within this window are flagged as Informational severity changes.
See Expiring Assignments for details.
Environment-Specific Configuration
Staging vs. Production
If you have multiple Azure AD tenants or want different schedules per environment, create separate pipeline files:
Azure DevOps:
# monitor-pipeline-prod.yml
schedules:
- cron: "0 */6 * * *"
# monitor-pipeline-staging.yml
schedules:
- cron: "0 0 * * 0" # Weekly
Then configure two pipelines in Azure DevOps UI pointing to different files.
GitHub Actions:
# .github/workflows/scan-prod.yml
# .github/workflows/scan-staging.yml
Platform Comparison
| Setting | Azure DevOps | GitHub Actions |
|---|---|---|
| Schedule location | monitor-pipeline.yml | .github/workflows/scan.yml |
| Manual trigger | Built-in (click Run) | workflow_dispatch: in YAML |
| Module cache | Via pipeline cache | actions/cache@v4 |
| Artifacts | Build artifacts storage | Artifact storage |
| Cron syntax | Same cron format | Same cron format |
Troubleshooting
Pipeline not running on schedule
Check:
- Is the
mainbranch the default branch? Scheduled runs only on default branch - Are workflows enabled? (GitHub Actions)
- Check pipeline run history for errors
- Verify cron syntax (test at https://crontab.guru/)
Module cache not working
Check:
- Did you change
MSGRAPH_VERSION? Cache is invalidated on version change - Is cache size exceeded? Pipelines have cache limits
- Try manually clearing cache and re-running
Inventory not committing
Check:
- Are there any changes to commit? No-change scans skip commit
- Verify git config is correct (user.name, user.email set in
src/git.ps1) - Check pipeline permissions: must have write access to repository
Artifact not generating
Check:
- Is
REPORT_ARTIFACT=trueset in variables? - Were changes detected? Report only generates on changes
- Check pipeline logs for permission errors
Related Pages
- Environment Variables — REPORT_ARTIFACT, EXPIRING_WINDOW_DAYS
- GitHub Actions Setup — Full GitHub Actions configuration
- Expiring Assignments — EXPIRING_WINDOW_DAYS details
- Reporting — HTML report artifact details
- Notifications — Notification triggers and configuration