A powerful PowerShell tool for collecting Windows Event Logs (.evtx files) across an Active Directory domain. Supports pull-based collection, GPO scheduled tasks, and GPO script deployment methods.
- Features
- Requirements
- Installation
- Usage
- Parameters
- Examples
- Network Share Setup
- GPO Deployment Guide
- Non-Administrator Usage
- Troubleshooting
- Performance Considerations
- Security Considerations
- Output Structure
- Frequently Asked Questions
- Three Collection Methods:
- Pull Method: Directly collect logs from remote systems via access administrative shares
- GPO Method: Deploy a scheduled task policy that makes systems push logs to a central share
- GPO Script Method: Deploy a PowerShell script via GPO for flexible collection options
- Generate-Only Mode: Create GPO files without requiring domain admin privileges
- High-Performance Threading: Uses runspace pools for true parallel execution (up to 50 concurrent threads)
- Filtering:
- Skip small/empty logs (customizable)
- Filter by log name patterns
- Target specific computers or OUs
- Comprehensive Logging: Detailed logging with timestamps and log levels
- GPO Automation: Automatically creates and configures GPOs or generates files for manual deployment
- Flexible Authentication: Support for alternate credentials and non-admin scenarios
- Reporting: Exports collection results to CSV
- Windows PowerShell 5.1 or PowerShell 7+
- Administrative privileges (script must run as administrator)
- Domain-joined computer with access to domain controllers
- ActiveDirectory module (installed with RSAT)
- GroupPolicy module (required for GPO method)
-
Pull Method:
- Access to administrative shares (C$) on target computers
- TCP ports 445 (SMB) and 135 (RPC)
- WMI/RPC connectivity
-
GPO Method:
- Writable network share accessible by all domain computers
- Proper NTFS and share permissions
- Domain Administrator or equivalent permissions for:
- Enumerating domain computers
- Creating and linking GPOs (GPO method)
- Accessing administrative shares (Pull method)
- Download
EventLogCollector.ps1to your management workstation - Ensure RSAT (Remote Server Administration Tools) is installed:
# Windows 10/11 Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 Add-WindowsCapability -Online -Name Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0 # Windows Server Install-WindowsFeature -Name RSAT-AD-PowerShell, GPMC
- Create an output directory for collected logs:
New-Item -Path "C:\EventLogCollections" -ItemType Directory
The script will gracefully handle non-administrator scenarios and guide you through privilege requirements for each method.
The pull method connects directly to each computer and copies event logs via administrative shares.
# Collect from all domain computers
.\EventLogCollector.ps1 -OutputPath "C:\EventLogCollections" -Method Pull
# Collect from specific computers
.\EventLogCollector.ps1 -OutputPath "C:\EventLogCollections" -ComputerName "SERVER01","SERVER02"
# Use alternate credentials (recommended for non-admin users)
.\EventLogCollector.ps1 -OutputPath "C:\EventLogCollections" -UseAlternateCredentials
# Provide credentials directly
$cred = Get-Credential
.\EventLogCollector.ps1 -OutputPath "C:\EventLogCollections" -Credential $credThe GPO method creates a Group Policy with a scheduled task that configures computers to push their logs to a network share.
# Create GPO for log collection and install it
.\EventLogCollector.ps1 -Method GPO -NetworkSharePath "\\fileserver\EventLogs" -OutputPath "C:\EventLogCollections"
# Generate GPO files only (no admin required just generate GPO)
.\EventLogCollector.ps1 -Method GPO -NetworkSharePath "\\fileserver\EventLogs" -GenerateOnly -OutputPath "C:\EventLogCollections"
# Create GPO and link to specific OUs
.\EventLogCollector.ps1 -Method GPO -NetworkSharePath "\\fileserver\EventLogs" -TargetOU "OU=Servers,DC=domain,DC=com" -OutputPath "C:\EventLogCollections"
# Create GPO but don't link it
.\EventLogCollector.ps1 -Method GPO -NetworkSharePath "\\fileserver\EventLogs" -SkipGPOLink -OutputPath "C:\EventLogCollections"
# Use alternate credentials for GPO operations
.\EventLogCollector.ps1 -Method GPO -NetworkSharePath "\\fileserver\EventLogs" -UseAlternateCredentials -OutputPath "C:\EventLogCollections"The GPO Script method deploys a PowerShell script via GPO for more flexible collection options.
# Create GPO with script deployment
.\EventLogCollector.ps1 -Method GPOScript -NetworkSharePath "\\fileserver\EventLogs" -OutputPath "C:\EventLogCollections"
# Generate script files only (no admin required)
.\EventLogCollector.ps1 -Method GPOScript -NetworkSharePath "\\fileserver\EventLogs" -GenerateOnly -OutputPath "C:\EventLogCollections"
# Deploy to specific OUs with custom GPO name
.\EventLogCollector.ps1 -Method GPOScript -NetworkSharePath "\\fileserver\EventLogs" -GPOName "CustomLogCollection" -TargetOU "OU=Servers,DC=domain,DC=com" -OutputPath "C:\EventLogCollections"| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| OutputPath | String | Yes | - | Directory where collected logs/files will be stored |
| Method | String | No | Pull | Collection method: 'Pull', 'GPO', or 'GPOScript' |
| ComputerName | String[] | No | All computers | Specific computers to collect from (Pull method) |
| Credential | PSCredential | No | Current user | Alternate credentials for authentication |
| UseAlternateCredentials | Switch | No | False | Prompt for alternate credentials |
| MaxThreads | Int | No | 20 | Maximum concurrent collection threads (1-50) |
| ExcludeSmallLogs | Boolean | No | True | Skip logs smaller than 70KB |
| LogNameFilter | String | No | * | Wildcard pattern for log names |
| NetworkSharePath | String | Required (GPO) | - | UNC path for GPO collections |
| GPOName | String | No | EventLogCollection-Policy | Name for the GPO |
| GenerateOnly | Switch | No | False | Generate GPO files without creating GPO |
| SkipGPOLink | Switch | No | False | Create GPO but don't link to any OU |
| TargetOU | String[] | No | Domain root | OUs to link the GPO to |
# Collect all logs from all domain computers
.\EventLogCollector.ps1 -OutputPath "E:\Evidence\Case001"# Use alternate credentials when not running as admin
.\EventLogCollector.ps1 -OutputPath "E:\Evidence\Case002" -UseAlternateCredentials
# Or provide credentials directly
$adminCred = Get-Credential -Message "Enter Domain Admin credentials"
.\EventLogCollector.ps1 -OutputPath "E:\Evidence\Case003" -Credential $adminCred# Collect only Security and System logs from specific servers
.\EventLogCollector.ps1 -OutputPath "E:\Evidence\Case004" `
-ComputerName "DC01","FILESERVER01","WEBSERVER01" `
-LogNameFilter "*Security*","*System*" `
-MaxThreads 5# Generate GPO files without admin privileges
.\EventLogCollector.ps1 -Method GPO `
-NetworkSharePath "\\LOGSERVER\EventLogs$" `
-OutputPath "E:\Evidence" `
-GenerateOnly
# Review generated files and deployment instructions# Create GPO and link to Servers OU (requires admin)
.\EventLogCollector.ps1 -Method GPO `
-NetworkSharePath "\\LOGSERVER\EventLogs$" `
-OutputPath "E:\Evidence" `
-GPOName "Server-EventLog-Collection" `
-TargetOU "OU=Servers,OU=Corp,DC=contoso,DC=com"# Deploy collection script via GPO
.\EventLogCollector.ps1 -Method GPOScript `
-NetworkSharePath "\\LOGSERVER\EventLogs$" `
-OutputPath "E:\Evidence" `
-GPOName "EventLog-Script-Collection"
# Generate script files only (no admin required)
.\EventLogCollector.ps1 -Method GPOScript `
-NetworkSharePath "\\LOGSERVER\EventLogs$" `
-OutputPath "E:\Evidence" `
-GenerateOnly# Create GPO but don't link it (link manually later)
.\EventLogCollector.ps1 -Method GPO `
-NetworkSharePath "\\LOGSERVER\EventLogs$" `
-OutputPath "E:\Evidence" `
-SkipGPOLink `
-UseAlternateCredentials# Optional: Use the helper script to set up network share
.\Setup-EventLogShare.ps1 -Path "D:\EventLogs" -ShareName "EventLogs$"
# With quota and auditing
.\Setup-EventLogShare.ps1 -Path "D:\EventLogs" -ShareName "EventLogs$" `
-QuotaGB 500 -EnableAuditingIMPORTANT: Before using GPO-based methods, you must properly configure a network share. The share must be accessible by all domain computers with appropriate permissions.
# 1. Create share folder
New-Item -Path "D:\EventLogs" -ItemType Directory
# 2. Create SMB share
New-SmbShare -Name "EventLogs$" -Path "D:\EventLogs" `
-FullAccess "Domain Admins" `
-ChangeAccess "Domain Computers"
# 3. Set NTFS permissions
$acl = Get-Acl "D:\EventLogs"
# Domain Computers - Modify (This folder only)
$computersPerm = New-Object System.Security.AccessControl.FileSystemAccessRule(
"Domain Computers", "Modify", "None", "None", "Allow")
$acl.AddAccessRule($computersPerm)
# CREATOR OWNER - Full Control (Subfolders and files only)
$creatorPerm = New-Object System.Security.AccessControl.FileSystemAccessRule(
"CREATOR OWNER", "FullControl", "ContainerInherit,ObjectInherit",
"InheritOnly", "Allow")
$acl.AddAccessRule($creatorPerm)
# Apply permissions
Set-Acl "D:\EventLogs" $acl-
Share Permissions:
- Domain Computers: Change
- Domain Admins: Full Control
- SYSTEM: Full Control
-
NTFS Permissions:
D:\EventLogs\ ├── Domain Computers: Modify (This folder only) ├── CREATOR OWNER: Full Control (Subfolders and files only) └── Domain Admins: Full Control (This folder, subfolders and files) -
Testing Access:
# From a domain computer: Test-Path "\\SERVER\EventLogs$" New-Item -Path "\\SERVER\EventLogs$\$env:COMPUTERNAME" -ItemType Directory
An optional helper script Setup-EventLogShare.ps1 is provided for automated share configuration with additional features like quotas and auditing.
This method creates a scheduled task via GPO that runs daily to collect logs.
# Full deployment (requires admin)
.\EventLogCollector.ps1 -Method GPO `
-NetworkSharePath "\\server\EventLogs$" `
-OutputPath "C:\GPOManagement"
# Generate files only
.\EventLogCollector.ps1 -Method GPO `
-NetworkSharePath "\\server\EventLogs$" `
-OutputPath "C:\GPOManagement" `
-GenerateOnly- Open Group Policy Management Console (GPMC)
- Create new GPO or edit existing
- Navigate to: Computer Configuration > Preferences > Control Panel Settings > Scheduled Tasks
- Create new scheduled task with generated XML content
- Link GPO to appropriate OUs
This method deploys a PowerShell script that can be run at startup or on schedule.
- Startup Script: Runs at computer startup
- Scheduled Task: Runs on schedule via GPO preference
- Immediate Task: Runs once when GPO applies
- More flexible collection logic
- Better error handling and logging
- Easier to update without modifying GPO
- Can add custom features (compression, filtering, etc.)
To target specific computers:
- Select the GPO in GPMC
- Under "Security Filtering", remove "Authenticated Users"
- Add specific computer groups (e.g., "Domain Controllers", "Member Servers")
-
Force policy update:
gpupdate /force -
Check GPO application:
gpresult /r /scope computer
-
Verify scheduled task (Method 1):
Get-ScheduledTask -TaskName "*EventLog*"
-
Check script deployment (Method 2):
Get-ChildItem "C:\Windows\SYSVOL\sysvol\$env:USERDNSDOMAIN\Policies"
The script gracefully handles non-administrator scenarios and provides appropriate guidance.
-
Pull Method:
# Script will prompt for credentials .\EventLogCollector.ps1 -OutputPath "C:\Collections" -UseAlternateCredentials
-
GPO Methods - Generate Only:
# Generate GPO files without creating GPO .\EventLogCollector.ps1 -Method GPO -GenerateOnly ` -NetworkSharePath "\\server\share" ` -OutputPath "C:\GPOFiles"
The script supports multiple credential scenarios:
- Running as Domain Admin: Full functionality, no additional credentials needed
- Running as Regular User:
- Use
-UseAlternateCredentialsto prompt for admin credentials - Use
-Credentialparameter with pre-created credential object
- Use
- Generate-Only Mode: No special privileges required
-
Security Analyst without Domain Admin:
# Get credentials from password manager $cred = Get-Credential -UserName "DOMAIN\ServiceAccount" # Run collection .\EventLogCollector.ps1 -OutputPath "E:\Evidence" ` -Credential $cred -Method Pull
-
Prepare GPO for Admin Review:
# Generate files for admin to implement .\EventLogCollector.ps1 -Method GPO -GenerateOnly ` -NetworkSharePath "\\approved\share" ` -OutputPath "C:\ForReview"
-
Test Script Locally:
# Test on local machine only .\EventLogCollector.ps1 -OutputPath "C:\LocalTest" ` -ComputerName $env:COMPUTERNAME
Symptom: "Access is denied" when accessing remote computers
Solutions:
- Ensure running as Domain Administrator
- Check Windows Firewall rules:
# Enable File and Printer Sharing Enable-NetFirewallRule -DisplayGroup "File and Printer Sharing"
- Verify WinRM is enabled:
Enable-PSRemoting -Force
Symptom: Computers not pushing logs after GPO deployment
Solutions:
- Check GPO application:
gpresult /r /scope computer
- Verify scheduled task creation:
Get-ScheduledTask -TaskName "*EventLog*"
- Check Event Viewer for Group Policy errors
Symptom: Computers cannot write to network share
Solutions:
- Verify computer account permissions:
# Test from affected computer Test-Path "\\FILESERVER\EventLogs$" New-Item -Path "\\FILESERVER\EventLogs$\$env:COMPUTERNAME" -ItemType Directory
- Check for Kerberos issues:
klist purge klist
Symptom: Collection is slow or times out
Solutions:
- Reduce MaxThreads parameter
- Target specific computers instead of entire domain
- Schedule collections during off-hours
- Implement collection in phases
Enable verbose logging for troubleshooting:
$VerbosePreference = "Continue"
$DebugPreference = "Continue"
.\EventLogCollector.ps1 -OutputPath "C:\Debug" -Method Pull-
Thread Count:
- LAN environments: 20-50 threads
- WAN/Remote sites: 5-10 threads
- Limited bandwidth: 1-5 threads
-
Collection Scheduling:
- Avoid business hours
- Stagger collections across time zones
- Consider network maintenance windows
-
Storage Planning:
- Typical server: 500MB-2GB of logs
- Domain Controller: 2GB-10GB of logs
- Plan for 3-5GB per server average
-
Network Impact:
# Estimate bandwidth usage $avgLogSize = 500MB $computerCount = 100 $totalData = $avgLogSize * $computerCount # With 10 concurrent threads over 1 hour $bandwidth = ($totalData / 1hour) * 10 / $computerCount
For domains with 1000+ computers:
-
Phased Collection:
# Collect by OU $ous = @("OU=Servers,DC=domain,DC=com", "OU=Workstations,DC=domain,DC=com") foreach ($ou in $ous) { $computers = Get-ADComputer -SearchBase $ou -Filter * .\EventLogCollector.ps1 -ComputerName $computers.Name -OutputPath "C:\Collections\$($ou.Split(',')[0])" }
-
Regional Collection Servers:
- Deploy multiple collection points
- Use DFS for replication
- Implement regional GPOs
-
Least Privilege:
- Use dedicated service account for GPO method
- Grant minimum required permissions
- Implement time-based access control
-
Audit Trail:
- Enable auditing on collection share
- Monitor script execution logs
- Track access patterns
-
Data Protection:
- Encrypt network share (EFS/BitLocker)
- Implement access controls
- Regular cleanup of old logs
-
Secure Script Deployment:
# Sign the script $cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert Set-AuthenticodeSignature -FilePath .\EventLogCollector.ps1 -Certificate $cert
- Ensure compliance with data retention policies
- Consider privacy regulations (GDPR, HIPAA)
- Document access and usage
- Implement data lifecycle management
C:\EventLogCollections\
├── COMPUTER01-Application.evtx
├── COMPUTER01-Security.evtx
├── COMPUTER01-System.evtx
├── COMPUTER02-Application.evtx
├── EventLogCollection_20250605_143022.log
└── CollectionResults_20250605_143022.csv
\\FILESERVER\EventLogs$\
├── COMPUTER01\
│ ├── Application.evtx
│ ├── Security.evtx
│ └── System.evtx
├── COMPUTER02\
│ ├── Application.evtx
│ └── System.evtx
└── Monitor-EventLogCollection.ps1
| ComputerName | LogsCopied | Status | Error |
|---|---|---|---|
| COMPUTER001 | 0 | Unreachable | |
| COMPUTER002 | 5 | Success | |
| COMPUTER003 | 0 | Failed | Access denied |
A: Plan for 3-5GB per server. A 100-computer environment typically needs 300-500GB for a full collection.
A: Yes, but workstation logs are typically smaller (100-500MB). Consider collecting only critical workstations.
A: Depends on network speed and thread count. Typical rates:
- LAN: 50-100 computers/hour with 20 threads
- WAN: 10-20 computers/hour with 5 threads
A: Yes, use Task Scheduler:
<Exec>
<Command>powershell.exe</Command>
<Arguments>-File C:\Scripts\EventLogCollector.ps1 -OutputPath E:\Collections\%DATE% -Method Pull</Arguments>
</Exec>A:
- Pull method: Computer is marked as "Unreachable"
- GPO method: Logs are collected when computer comes online
A: Pull method supports this with appropriate credentials:
$cred = Get-Credential
.\EventLogCollector.ps1 -ComputerName "WORKGROUP-PC" -Credential $cred -OutputPath "C:\Collections"A: Implement retention policy:
# Delete collections older than 30 days
Get-ChildItem "E:\Collections" -Directory |
Where-Object {$_.CreationTime -lt (Get-Date).AddDays(-30)} |
Remove-Item -Recurse -ForceA: The script collects entire log files. Use separate tools for filtering:
# Post-process collected logs
Get-WinEvent -Path ".\COMPUTER01-Security.evtx" |
Where-Object {$_.Id -in @(4624,4625,4634)}A: The script collects only current logs from \Windows\System32\Winevt\Logs\. Archived logs must be collected separately.
For issues, feature requests, or contributions:
- Document the issue with error messages and logs
- Include environment details (OS version, domain functional level)
- Provide minimal reproduction steps
- v2.0 (2025): Complete rewrite with modern PowerShell, threading, and GPO support
- v0.3A (2019): Original script with basic functionality
See LICENSE file
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.