Progressive hands-on labs covering setup, data generation, upload, classification, 9 discovery tracks, reporting, and cleanup.
PnP regex, eDiscovery manual & API, Activity Explorer, Auto-Apply, Oversharing, Custom SIT, On-Prem Scanner, Defender for Cloud Apps.
Fully automated PowerShell scripts for site provisioning, document generation, upload, discovery, reporting, and cleanup.
Single global-config.json controls all environment values. No hardcoded tenants, URLs, or email addresses anywhere in code.
Zero stored secrets. All authentication via interactive browser OAuth 2.0 flow. No app registrations, certificates, or PATs in code.
Small: ~1,000 docs (demos) · Medium: ~5,000 docs (testing) · Large: ~20,000 docs (enterprise POCs)
Lab 07 fully resets sites, documents, logs, and config back to pristine state. Complete environment ready for next demo iteration.
Validate M365 E5 licensing, PowerShell module versions, and service connectivity. Initialize directory structure and logging infrastructure. Update global-config.json before any other lab.
- Test-Prerequisites.ps1Validates M365 licensing, module versions, and service connectivity00-Prerequisites-Setup/scripts/Test-Prerequisites.ps1
- Initialize-SimulationEnvironment.ps1Creates directory structure (logs, output, generated-documents, reports, temp) and initializes logging00-Prerequisites-Setup/scripts/Initialize-SimulationEnvironment.ps1
Provision SharePoint department sites (HR, Finance, Legal, Marketing, IT). Configure site templates (Communication vs Team), set permissions and ownership. Supports -SkipExisting for idempotent re-runs.
- New-SimulatedSharePointSites.ps1Creates SharePoint sites from global-config.json specifications01-SharePoint-Site-Creation/scripts/New-SimulatedSharePointSites.ps1
- Set-SitePermissions.ps1Configures site permissions and ownership01-SharePoint-Site-Creation/scripts/Set-SitePermissions.ps1
- Verify-SiteCreation.ps1Validates that all sites were created successfully01-SharePoint-Site-Creation/scripts/Verify-SiteCreation.ps1
- Show-SiteCreationReport.ps1Generates a report of created sites and their status01-SharePoint-Site-Creation/scripts/Show-SiteCreationReport.ps1
- Show-ValidationReport.ps1Displays site validation results01-SharePoint-Site-Creation/scripts/Show-ValidationReport.ps1
Generate realistic documents with built-in Sensitive Information Types (SSN, Credit Cards, Passports, Driver's Licenses, ITIN, Bank Accounts). Mixed formats: 45% docx · 30% xlsx · 15% pdf · 10% txt. Scale: 500–1,000 (Small) · 5,000 (Medium) · 20,000 (Large).
- Invoke-BulkDocumentGeneration.ps1Orchestrates bulk document generation at configured scale level02-Test-Data-Generation/scripts/Invoke-BulkDocumentGeneration.ps1
- New-SimulatedHRDocuments.ps1Generates HR documents containing SSNs and employee PII02-Test-Data-Generation/scripts/New-SimulatedHRDocuments.ps1
- New-SimulatedFinancialRecords.ps1Creates financial records with credit card, bank account, and ABA routing numbers02-Test-Data-Generation/scripts/New-SimulatedFinancialRecords.ps1
- New-SimulatedPIIContent.ps1Generates identity documents (passports, driver's licenses, ITIN)02-Test-Data-Generation/scripts/New-SimulatedPIIContent.ps1
- New-MixedContentDocuments.ps1Creates documents with multiple PII types across formats02-Test-Data-Generation/scripts/New-MixedContentDocuments.ps1
- Remove-GeneratedDocuments.ps1Removes locally generated documents for cleanup02-Test-Data-Generation/scripts/Remove-GeneratedDocuments.ps1
Bulk upload documents to SharePoint with intelligent distribution (HR docs → HR site, Finance → Finance site). Applies SharePoint metadata: Department, ContentType, PIIDensity, GeneratedDate. Throttling-aware with automatic retry logic (600 req/min, 2,500 req/hr).
- Upload-AllDocuments.ps1Main entry point — orchestrates bulk upload across all sites03-Document-Upload-Distribution/scripts/Upload-AllDocuments.ps1
- Upload-ToSingleSite.ps1Uploads documents to a specific SharePoint site03-Document-Upload-Distribution/scripts/Upload-ToSingleSite.ps1
- Test-UploadValidation.ps1Validates upload completion and document count accuracy03-Document-Upload-Distribution/scripts/Test-UploadValidation.ps1
- Grant-AppSitePermissions.ps1Grants required permissions for upload operations03-Document-Upload-Distribution/scripts/Grant-AppSitePermissions.ps1
Execute On-Demand Classification via purview.microsoft.com. Review estimation (300–500 items) and cost ($5–$15 typical). Classification runs asynchronously for up to 7 days. Validates 100% Purview SIT detection accuracy in Content Explorer.
- Navigate to purview.microsoft.com → Information Protection → Classification
- Create On-Demand Classification scan for simulation sites
- Review estimation results and cost analysis
- Start classification → monitor via portal status
- After 7 days: validate results in Content Explorer
Nine distinct discovery methods with different timelines, accuracy, and use cases. Choose based on your timing requirements. See the Discovery Methods page for the full comparison matrix and decision guide.
Consolidate discovery results from Labs 05a/05b/05c. Classify files into High/Medium/Low severity tiers. Preview deletions with dry-run (-WhatIf), then apply with explicit -Apply gate. SharePoint Recycle Bin used for reversible cleanup.
- Aggregate-RemediationReport.ps1Consolidates CSV outputs from multiple discovery methods into unified remediation plan06-Reporting-and-Remediation/scripts/Aggregate-RemediationReport.ps1
- Analyze-SeverityBasedRemediation.ps1Classifies detected files into High/Medium/Low severity tiers06-Reporting-and-Remediation/scripts/Analyze-SeverityBasedRemediation.ps1
- Remove-SharePointDuplicates.ps1Safely removes low-risk duplicate files via SharePoint Recycle Bin06-Reporting-and-Remediation/scripts/Remove-SharePointDuplicates.ps1
Full environment reset: removes simulation sites, deletes local generated documents, restores global-config.json to template defaults, and exports cleanup documentation. Supports -WhatIf preview mode and confirmation prompts for safety.
- Remove-SimulationResources.ps1Removes SharePoint sites and all uploaded simulation content07-Cleanup-Reset/scripts/Remove-SimulationResources.ps1
- Reset-Environment.ps1Full environment reset including local files and config restoration07-Cleanup-Reset/scripts/Reset-Environment.ps1
- Test-CleanupCompletion.ps1Validates that all simulation resources have been removed07-Cleanup-Reset/scripts/Test-CleanupCompletion.ps1
- Export-FinalDocumentation.ps1Exports cleanup documentation and audit trail07-Cleanup-Reset/scripts/Export-FinalDocumentation.ps1
| Track | Method | Timeline | SIT Accuracy | Automation | Best For |
|---|---|---|---|---|---|
| 05a PnP Direct | File enumeration + regex | Immediate | 70–90% | PowerShell | Quick interim, learning |
| 05b eDiscovery Manual | Portal + Purview SITs | 24 hours | ~100% | Portal UI | One-time compliance |
| 05c eDiscovery API | Microsoft Graph API | 24 hours | ~100% | Fully automated | Recurring scans, SIEM |
| 05d Activity Explorer | Audit-trail events | 24–48 hr | n/a (events) | Portal CSV export | Monitoring movement |
| 05e Auto-Apply | Retention policy simulation | 1–7 days | ~100% | Portal UI | Ongoing enforcement |
| 05f Oversharing | DSPM, DAG, RCD review | Portal review | n/a (access) | Portal UI | Access risk posture |
| 05g Custom Detection | Custom SIT, EDM, OCR | Portal setup | ~100% | Portal config | Data built-ins miss |
| 05h On-Prem Scanner | IP Scanner host | Scanner host | ~100% | Host cmdlets | On-prem file shares |
| 05i Defender CAS | MDCA file policy | Portal review | ~100% | Portal policy | Third-party SaaS |
| 05-Temp Temporal | 4-interval longitudinal | 2–3 weeks | ~100% | Periodic scans | Classification drift research |
⚡ PnP Direct File Access
Direct file enumeration with regex pattern matching. Fastest path — no indexing wait. Best for immediate results and learning the discovery workflow.
✅ eDiscovery Manual
Portal-based search using Purview's built-in SITs with Cases preview and Condition builder. Direct export in 5–10 minutes.
🏆 eDiscovery Graph API
Microsoft Graph eDiscovery API for automated, recurring scans. SIEM integration ready. 100% Purview SIT accuracy with PowerShell automation.
📈 Activity Explorer Monitoring
Audit-trail view of what happens to sensitive data — classification changes, downloads, shares. Cross-workload monitoring across M365.
🎯 Auto-Apply Policies
Official SIT detection via auto-apply retention policy simulation. Tracks label enforcement activity across the tenant over time.
🔐 Access & Oversharing Posture
Who can reach sensitive data? DSPM for data security posture, DSPM for AI, Data Access Governance, and Reports & Content Discovery.
🧪 Custom Detection
Custom SITs (regex), Exact Data Match (EDM), Trainable Classifiers, and OCR for document images. For data the built-ins miss.
🏢 On-Premises Scanner
Extends discovery to on-premises Windows file shares via the Information Protection Scanner. Analyzes detailed scanner reports.
☁️ Defender for Cloud Apps
MDCA file policy with content inspection for SITs across Box, Dropbox, Google Drive, and other third-party SaaS apps.
4-interval temporal tracking (24hr, 7d, 14d, 21d) to observe classification drift and evolution. Research-focused longitudinal study. Scripts: Invoke-TemporalScan.ps1, Compare-TemporalScans.ps1, Invoke-TemporalAnalysis.ps1
Compare results across all discovery methods with side-by-side accuracy, coverage, and confidence analysis.
- Invoke-CrossLabAnalysis.ps1Produces comparative report across all discovery method outputs05-Discovery-Methods/scripts/Invoke-CrossLabAnalysis.ps1
- Resolve-UnmappedSITGuids.ps1Maps unmapped SIT GUIDs to human-readable names in discovery reports05-Discovery-Methods/scripts/Resolve-UnmappedSITGuids.ps1
- Expand-eDiscoveryExportPackages.ps1Expands and processes eDiscovery export packages for analysis05-Discovery-Methods/scripts/Expand-eDiscoveryExportPackages.ps1
- Connect-PurviewServices.ps1Browser-based interactive authentication to SharePoint, Exchange, and GraphShared-Utilities/Connect-PurviewServices.ps1
- Import-GlobalConfig.ps1Reads and validates global-config.json — single source of truth for all env valuesShared-Utilities/Import-GlobalConfig.ps1
- Import-PurviewModules.ps1Imports PnP.PowerShell, ExchangeOnlineManagement, Microsoft.Graph with minimum version checksShared-Utilities/Import-PurviewModules.ps1
- Write-SimulationLog.ps1Canonical logger — DO NOT use bare Write-Host for state loggingShared-Utilities/Write-SimulationLog.ps1
- Test-ServiceConnection.ps1Validates active connections to SharePoint, Exchange, and Graph servicesShared-Utilities/Test-ServiceConnection.ps1
- Get-SimulationProgress.ps1Reports current simulation state and progress across all labsShared-Utilities/Get-SimulationProgress.ps1
- Merge-LabConfig.ps1Merges lab-specific config with global config for per-lab overridesShared-Utilities/Merge-LabConfig.ps1
- Resolve-GlobalReference.ps1Resolves dynamic references within configuration valuesShared-Utilities/Resolve-GlobalReference.ps1
- Functions/Connection-Management.ps1Reusable connection management functions (retry, session validation, throttle handling)Shared-Utilities/Functions/Connection-Management.ps1
- Invoke-PnPDirectFileDiscovery.ps1Main discovery script — PnP file enumeration + regex SIT matching across all sites05-Discovery-Methods/05a-PnP-Direct-File-Access/scripts/Invoke-PnPDirectFileDiscovery.ps1
- Open-LatestReport.ps1Opens the most recent discovery CSV report for review05-Discovery-Methods/05a-PnP-Direct-File-Access/scripts/Open-LatestReport.ps1
- Test-ContentIndexingStatus.ps1Checks SharePoint Search indexing readiness before eDiscovery search05-Discovery-Methods/05b-eDiscovery-Compliance-Search/scripts/Test-ContentIndexingStatus.ps1
- Invoke-eDiscoveryResultsAnalysis.ps1Analyzes eDiscovery search results and generates summary report05-Discovery-Methods/05b-eDiscovery-Compliance-Search/scripts/Invoke-eDiscoveryResultsAnalysis.ps1
- Expand-eDiscoveryExportPackages.ps1Expands downloaded eDiscovery export packages for analysis05-Discovery-Methods/05b-eDiscovery-Compliance-Search/scripts/Expand-eDiscoveryExportPackages.ps1
- Invoke-GraphSitDiscovery.ps1Main Graph API discovery — automated eDiscovery via Microsoft Graph05-Discovery-Methods/05c-Graph-API-Discovery/scripts/Invoke-GraphSitDiscovery.ps1
- Test-GraphConnectivity.ps1Validates Graph API connection and required delegated permissions05-Discovery-Methods/05c-Graph-API-Discovery/scripts/Test-GraphConnectivity.ps1
- Grant-GraphPermissions.ps1Grants required delegated Graph API permissions for discovery05-Discovery-Methods/05c-Graph-API-Discovery/scripts/Grant-GraphPermissions.ps1
- Export-SearchResults.ps1Exports Graph eDiscovery search results to CSV05-Discovery-Methods/05c-Graph-API-Discovery/scripts/Export-SearchResults.ps1
- Get-ExistingCases.ps1Lists existing eDiscovery cases in the tenant05-Discovery-Methods/05c-Graph-API-Discovery/scripts/Get-ExistingCases.ps1
- Invoke-GraphDiscoveryAnalysis.ps1Analyzes Graph discovery results and generates comparison reports05-Discovery-Methods/05c-Graph-API-Discovery/scripts/Invoke-GraphDiscoveryAnalysis.ps1
- Compare-Discovery-Results.ps1Side-by-side comparison of 05a (regex) vs 05c (Graph API) results05-Discovery-Methods/05c-Graph-API-Discovery/scripts/Compare-Discovery-Results.ps1
- Test-SiteAvailability.ps1Verifies SharePoint sites are available and indexed for Graph search05-Discovery-Methods/05c-Graph-API-Discovery/scripts/Test-SiteAvailability.ps1
- Expand-eDiscoveryExportPackages.ps1Expands and processes eDiscovery export packages from Graph API05-Discovery-Methods/05c-Graph-API-Discovery/scripts/Expand-eDiscoveryExportPackages.ps1
- Invoke-ActivityExplorerAnalysis.ps1Exports and analyzes Activity Explorer audit events for classified content05-Discovery-Methods/05d-Activity-Explorer-Monitoring/scripts/Invoke-ActivityExplorerAnalysis.ps1
- Invoke-PolicySimulationAnalysis.ps1Analyzes auto-apply policy simulation results and enforcement statistics05-Discovery-Methods/05e-Auto-Apply-Policies-Discovery/scripts/Invoke-PolicySimulationAnalysis.ps1
- Analyze-ScannerDetailedReport.ps1Processes and analyzes On-Premises Scanner detailed report output05-Discovery-Methods/05h-OnPrem-Scanner-Discovery/scripts/Analyze-ScannerDetailedReport.ps1
| Config Key / Class | Required Placeholder | Example |
|---|---|---|
| Tenant URL | https://contoso.sharepoint.com | Replace with your tenant in global-config.json only |
| Admin URL | https://contoso-admin.sharepoint.com | — |
| Admin Email | admin@example.com | — |
| User Email | user@example.com | — |
| Tenant / Object / App ID | 00000000-0000-0000-0000-000000000000 | All GUIDs use zero placeholder |
| Org Names | Contoso, Fabrikam | — |
| Domains | example.com, contoso.com | — |
| Site Collections | https://contoso.sharepoint.com/sites/Example | — |
Committed to git. Contains the shape of configuration with placeholder values. Used as the starting point for contributors. Never contains real values.
Gitignored. Contains real tenant values filled in by the contributor. Read at runtime by all scripts via Import-GlobalConfig.ps1. Never committed.
| Scale | Documents | Generation Time | Upload Time | Storage | Best For |
|---|---|---|---|---|---|
| Small | ~1,000 | 5–10 min | 20–40 min | ~100 MB | Testing, demos, learning |
| Medium | ~5,000 | 30–60 min | 1–2 hr | ~500 MB | Development, validation |
| Large | ~20,000 | 1–2 hr | 3–5 hr | 10–15 GB | Enterprise POC, production demo |
PnP PowerShell: 600 requests/min · 2,500 requests/hour
All upload and discovery scripts include automatic retry logic with exponential back-off.
Monitor throttling in script output — scripts will pause automatically when limits are hit.
@idea-intake → @artifact-resolver → persona work → @owner-approval → mergeTier-1 orchestrator that activates exactly one persona per request. Routes work to the appropriate Tier-2 agent based on the change type. All requests should start here.
Classifies requests, generates the plan (epic + gated child issues), drafts issues with acceptance criteria and squad:<persona> labels. No work starts without an @idea-intake issue.
Picks the persona, creates a feature branch off main, builds the artifact, opens the PR linked to the issue, and runs validation. All PRs are opened by @artifact-resolver only.
On marcusjacobson's go-ahead, applies the owner-approved label, squash-merges the PR, and deletes the branch. Merge gate — no merge without owner sign-off.
| Persona | Charter File | Responsible For |
|---|---|---|
| @lab-architect | lab-architect-charter.md | Cross-lab structure, ADRs, sequencing |
| @powershell-automation | powershell-automation-charter.md | All *.ps1 / *.psm1 / Shared-Utilities |
| @purview-specialist | purview-specialist-charter.md | SIT mapping, DLP, eDiscovery, classification logic |
| @security-steward | security-steward-charter.md | Auth flows, secret hygiene, placeholder enforcement |
| @validation-lead | validation-lead-charter.md | reports/, validation scripts, acceptance thresholds |
| @scribe | scribe-charter.md | README.md, guides, ADRs, squad memory updates |
- No work without an issue from @idea-intake
- No PR opened by any path other than @artifact-resolver
- No direct push to main
- No merge without the owner-approved label and marcusjacobson's go-ahead
- No persona reviews its own PR
- No writes to .squad/memory/** outside the Scribe handoff workflow (append-only)
- All agent outputs are proposals until the owner approves
| Change Type | Route To |
|---|---|
| Cross-lab structure, ADR, sequencing | @lab-architect |
| Any *.ps1 / *.psm1 / Shared-Utilities | @powershell-automation |
| SIT mapping, DLP, eDiscovery, classification logic | @purview-specialist |
| Auth flow, secret hygiene, placeholder enforcement | @security-steward |
| reports/, validation scripts, acceptance thresholds | @validation-lead |
| README.md, guides, ADRs, .squad/memory updates | @scribe |
| New / unscoped request | @idea-intake first |
| Open the PR for any of the above | @artifact-resolver |
| Final merge gate | @owner-approval |