A powerful, browser-based forensic analysis tool for Microsoft Purview audit logs. Analyze, classify, and investigate security incidents directly in your browser with zero server requirements.
- 100% Client-Side Processing - All data stays in your browser, nothing sent to servers
- IP Classification System - Automatically classify IPs as Trusted, Suspicious, or Unknown
- IOC (Indicator of Compromise) Matching - Import and match against custom IOCs
- Multiple View Modes - Timeline, By IP, By User, By Message, By Operation, By Session, Raw
- Advanced Filtering - Search, filter by date range, operation, user, IP class
- Activity Visualization - Interactive charts showing timeline distribution
- CSV Export - Export filtered results with classifications
- Persistent Storage - IP classifications and IOCs saved in localStorage
- Microsoft IP Detection - Auto-detect Microsoft infrastructure IPs
- Parse Error Detection - Identify and flag malformed audit data
🌐 Use Online: https://mwilco03.github.io/PurViewEr/
The installer scripts download the full repository (including bundled libraries) to ~/Downloads/PurViewEr/ and open the app in your default browser.
PowerShell (Windows):
irm https://raw.githubusercontent.com/mwilco03/PurViewEr/main/install.ps1 | iexBash/Zsh (macOS/Linux):
curl -fsSL https://raw.githubusercontent.com/mwilco03/PurViewEr/main/install.sh | bash- Go to the latest release or download the repository
- Download as ZIP and extract to your preferred location
- Open
index.htmlin your web browser - Bookmark the file for future use
Visit https://mwilco03.github.io/PurViewEr/ and bookmark it. Works online with all features, no installation required.
Windows:
.\install.ps1macOS/Linux:
./install.shThe installer downloads index.html to your Downloads folder and opens it automatically.
From Microsoft 365 Compliance Center:
- Navigate to Audit → Search
- Configure your search parameters
- Click Export → Download all results
- Save the CSV file
Required: The CSV must contain an AuditData column with JSON data.
Drag & Drop:
- Drag CSV files directly onto the drop zone
- Multiple files are automatically merged
File Browser:
- Click the drop zone to open file browser
- Select one or multiple CSV files
- Use + Add Files button to append additional data
Automatic Classification:
- Private IPs (10.x, 192.168.x, 172.16-31.x) → Trusted
- All others → Unknown
Manual Classification:
- Click any IP in the classification panel to cycle through:
- Unknown → Trusted → Suspicious → Unknown
Microsoft IPs:
- Automatically detected and tagged with
MSFTbadge - Based on known Microsoft IP ranges
- Click IOC Import panel to expand
- Paste indicators (one per line):
- IP addresses
- User emails
- App IDs
- Subject keywords
- Click Apply IOCs
- Matching records are automatically flagged with
IOCbadge - Matching IPs are auto-classified as Suspicious
Search Bar:
- Searches across: Subject, IP, User, Session, Message ID, Operation, Path
Filters:
- IP Class - Filter by Trusted, Suspicious, Unknown
- Operation - Filter by operation type (MailItemsAccessed, Send, etc.)
- User - Filter by mailbox owner
- Date Range - From/To datetime filters
- IOC Only - Show only IOC-matched records
- Parse Errors - Show only records with malformed AuditData
| View | Description |
|---|---|
| Timeline | Chronological list of all events |
| By IP | Group events by source IP address |
| By User | Group events by mailbox owner |
| By Message | Group events by email message ID |
| By Operation | Group events by operation type |
| By Session | Group events by AAD session ID |
| Raw | Expandable view showing all audit fields |
- Apply desired filters
- Click Export Filtered CSV
- Downloads CSV with:
- All filtered records
- IP classifications
- IOC match flags
- Microsoft IP detection
- All extracted fields
- Modern Browser: Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
- JavaScript: Must be enabled
- localStorage: Required for persistence (optional)
Supported: Microsoft Purview audit log CSV exports
Required Columns:
AuditData- JSON string containing audit details
Parsed Fields:
- ClientIPAddress / ClientIP
- CreationTime
- Operation
- MailboxOwnerUPN / UserId
- Item.Subject / Subject
- Item.InternetMessageId / InternetMessageId
- Item.Path / Path
- AppAccessContext.AADSessionId / SessionId
- AppAccessContext.APIId / AppId
- ClientAppId
- ExternalAccess
- LogonType
- ResultStatus
- Workload
- And many more...
100% Local Processing:
- No data sent to external servers
- No analytics or tracking
- All processing in browser memory
- localStorage used only for:
- IP classifications
- IOC lists
No Network Requirements After Load:
- After initial page load, works completely offline
- CSV files never leave your device
Persisted Data:
- IP classifications (keyed as
purview-forensic-ip-classifications) - IOC lists (keyed as
purview-forensic-iocs)
Session Data:
- Loaded CSV records (in memory only, cleared on page reload)
- Applied filters (in memory only)
Clear Storage:
// Open browser console (F12) and run:
localStorage.removeItem('purview-forensic-ip-classifications');
localStorage.removeItem('purview-forensic-iocs');- React 18 - UI framework
- PapaParse - Robust CSV parsing
- Recharts - Activity timeline visualization
- Babel Standalone - JSX transformation (index.html only)
- Vanilla CSS - No build dependencies
PurViewEr/
├── index.html # Standalone app (CDN dependencies)
├── purview-forensic-analyzer-v2.jsx # React component (for build systems)
├── README.md # This file
├── install.ps1 # Windows installer
└── install.sh # macOS/Linux installer
Option 1: Standalone HTML (Current)
- Single
index.htmlfile - CDN dependencies
- Works immediately in browser
- Requires internet for first load
Option 2: Component-Based (JSX)
- Use
purview-forensic-analyzer-v2.jsx - Integrate into React projects
- Requires build system (Vite, Webpack, etc.)
- Production-ready optimization
Simple HTTP Server:
# Python
python -m http.server 8000
# Node
npx http-server -p 8000
# PHP
php -S localhost:8000Then open: http://localhost:8000/index.html
If using the component version:
# Install dependencies
npm install react react-dom papaparse recharts
# Import in your app
import ForensicAnalyzer from './purview-forensic-analyzer-v2.jsx';
function App() {
return <ForensicAnalyzer />;
}Modify Known Microsoft IP Ranges:
Edit KNOWN_MSFT_PREFIXES array in source code (line 54 in JSX, line 80 in HTML)
Adjust Records Per Page:
Change RECORDS_PER_PAGE constant (default: 50)
Add Custom Fields:
Extend FIELD_EXTRACTION object with new field paths
Error: "No records found in file"
- Solution: Ensure CSV has
AuditDatacolumn - Export from Purview Audit Search, not other sources
Error: "CSV parse failed"
- Solution: Check for delimiter issues
- Ensure UTF-8 encoding
- Try opening in Excel and re-saving
Symptom: Records show PARSE ERR tag
- Cause: Malformed JSON in AuditData column
- Impact: Record loads but some fields may be empty
- Action: Use "Parse errors" filter to isolate
- Check raw AuditData in Raw view
Large Files (>10MB):
- Load in smaller batches
- Use date range filters to reduce displayed records
- Browser may slow with >100,000 records
Slow Filtering:
- Search is debounced (250ms delay)
- Filtering large datasets may take 1-2 seconds
Error: "QuotaExceededError"
- Cause: localStorage full (usually 5-10MB limit)
- Solution: Clear old IP classifications/IOCs
This tool is designed for:
- Post-breach analysis - Investigate compromise timelines
- Threat hunting - Search for suspicious patterns
- Compliance audits - Review mailbox access
- Forensic documentation - Export filtered evidence
- Isolate - Analyze on air-gapped or isolated system
- Classify - Mark known-good IPs as Trusted
- Import IOCs - Add known malicious indicators
- Hunt - Use filters to find suspicious activity
- Export - Document findings with filtered CSV
- Preserve - Keep original CSV files as evidence
- Not Real-Time - Analyzes exported logs only
- No Threat Intelligence - IOCs must be manually imported
- No Automated Alerting - Manual review required
- Browser Dependent - Performance varies by browser/system
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
MIT License - See LICENSE file for details
- Fixed React import order bug in JSX version
- Changed window.storage to localStorage for compatibility
- Added offline installer scripts (PowerShell + Bash)
- Comprehensive README documentation
- GitHub Pages support
- Full forensic analysis capabilities
- IP classification system
- IOC matching
- Multiple view modes
- CSV export
- Issues: Report bugs or request features via GitHub Issues
- Discussions: Ask questions via GitHub Discussions
- Built for security professionals and incident responders
- Inspired by real-world compromise investigations
- Powered by open-source technologies