Response/Invoke-ForensicCollection.ps1

function Invoke-ForensicCollection {
    <#
    .SYNOPSIS
        Collects comprehensive forensic evidence from the system
    .DESCRIPTION
        Performs detailed forensic data collection including memory dumps, disk artifacts,
        registry hives, event logs, and system state information
    .PARAMETER CollectionType
        Type of collection: Quick, Standard, or Comprehensive
    .PARAMETER OutputPath
        Path to save collected evidence
    .PARAMETER IncludeMemoryDump
        Include memory dump (requires large disk space)
    .PARAMETER IncludeDiskArtifacts
        Collect disk-based artifacts (MFT, prefetch, etc.)
    .EXAMPLE
        Invoke-ForensicCollection -CollectionType Standard -OutputPath "C:\Forensics"
        Invoke-ForensicCollection -CollectionType Comprehensive -IncludeMemoryDump -OutputPath "D:\Evidence"
    .OUTPUTS
        PSCustomObject with collection results
    #>

    
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateSet('Quick', 'Standard', 'Comprehensive')]
        [string]$CollectionType,
        
        [Parameter(Mandatory = $true)]
        [string]$OutputPath,
        
        [Parameter()]
        [switch]$IncludeMemoryDump,
        
        [Parameter()]
        [switch]$IncludeDiskArtifacts
    )
    
    begin {
        Write-Host "=== FORENSIC EVIDENCE COLLECTION ===" -ForegroundColor Cyan
        Write-Host "Collection Type: $CollectionType" -ForegroundColor Yellow
        Write-Host "Start Time: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Yellow
        
        # Check for admin privileges
        $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
        if (-not $isAdmin) {
            throw "Forensic collection requires Administrator privileges!"
        }
        
        # Create output directory with timestamp
        $timestamp = Get-Date -Format 'yyyyMMdd_HHmmss'
        $collectionPath = Join-Path $OutputPath "ForensicCollection_$timestamp"
        New-Item -Path $collectionPath -ItemType Directory -Force | Out-Null
        
        # Create subdirectories
        $directories = @(
            'SystemInfo',
            'EventLogs',
            'Registry',
            'Network',
            'Processes',
            'FileSystem',
            'Memory',
            'Timeline'
        )
        
        foreach ($dir in $directories) {
            New-Item -Path (Join-Path $collectionPath $dir) -ItemType Directory -Force | Out-Null
        }
        
        $results = [PSCustomObject]@{
            CollectionDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
            CollectionType = $CollectionType
            ComputerName = $env:COMPUTERNAME
            OutputPath = $collectionPath
            ArtifactsCollected = @()
            Errors = @()
            TotalSize = 0
            Status = 'In Progress'
        }
        
        $logFile = Join-Path $collectionPath "Collection.log"
        
        function Write-CollectionLog {
            param([string]$Message, [string]$Level = 'INFO')
            $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
            $logMessage = "[$timestamp] [$Level] $Message"
            Add-Content -Path $logFile -Value $logMessage
            Write-Verbose $Message
        }
        
        Write-CollectionLog "Forensic collection initiated - Type: $CollectionType"
    }
    
    process {
        try {
            # Collection 1: System Information (All types)
            Write-Host "`n[1/10] Collecting system information..." -ForegroundColor Cyan
            try {
                $sysInfoPath = Join-Path $collectionPath 'SystemInfo'
                
                # Basic system info
                $sysInfo = Get-SystemInfo -IncludeInstalledSoftware -IncludeHotfixes
                $sysInfo | ConvertTo-Json -Depth 5 | Out-File (Join-Path $sysInfoPath "SystemInfo.json") -Encoding UTF8
                
                # Computer information
                Get-ComputerInfo | ConvertTo-Json -Depth 5 | Out-File (Join-Path $sysInfoPath "ComputerInfo.json") -Encoding UTF8
                
                # Environment variables
                Get-ChildItem Env: | Export-Csv (Join-Path $sysInfoPath "EnvironmentVariables.csv") -NoTypeInformation
                
                # Local users and groups
                Get-LocalUser | Export-Csv (Join-Path $sysInfoPath "LocalUsers.csv") -NoTypeInformation
                Get-LocalGroup | Export-Csv (Join-Path $sysInfoPath "LocalGroups.csv") -NoTypeInformation
                
                $results.ArtifactsCollected += "System Information"
                Write-CollectionLog "Collected system information"
            }
            catch {
                $results.Errors += "System Info: $_"
                Write-CollectionLog "Error collecting system info: $_" 'ERROR'
            }
            
            # Collection 2: Running Processes (All types)
            Write-Host "[2/10] Collecting process information..." -ForegroundColor Cyan
            try {
                $procPath = Join-Path $collectionPath 'Processes'
                
                # Process list with details
                Get-Process | Select-Object Name, Id, Path, CommandLine, StartTime, CPU, WorkingSet64, Threads |
                    Export-Csv (Join-Path $procPath "Processes.csv") -NoTypeInformation
                
                # Process modules
                $procModules = Get-Process | ForEach-Object {
                    $proc = $_
                    try {
                        $_.Modules | Select-Object @{N='ProcessName';E={$proc.ProcessName}}, 
                                                   @{N='ProcessId';E={$proc.Id}},
                                                   ModuleName, FileName, Size
                    } catch {}
                }
                $procModules | Export-Csv (Join-Path $procPath "ProcessModules.csv") -NoTypeInformation
                
                # Services
                Get-Service | Export-Csv (Join-Path $procPath "Services.csv") -NoTypeInformation
                Get-CimInstance Win32_Service | Select-Object Name, DisplayName, PathName, StartMode, State, StartName |
                    Export-Csv (Join-Path $procPath "ServicesDetailed.csv") -NoTypeInformation
                
                # Scheduled tasks
                Get-ScheduledTask | Export-Csv (Join-Path $procPath "ScheduledTasks.csv") -NoTypeInformation
                
                $results.ArtifactsCollected += "Process Information"
                Write-CollectionLog "Collected process information"
            }
            catch {
                $results.Errors += "Processes: $_"
                Write-CollectionLog "Error collecting processes: $_" 'ERROR'
            }
            
            # Collection 3: Network Information (All types)
            Write-Host "[3/10] Collecting network information..." -ForegroundColor Cyan
            try {
                $netPath = Join-Path $collectionPath 'Network'
                
                # Network adapters
                Get-NetAdapter | Export-Csv (Join-Path $netPath "NetworkAdapters.csv") -NoTypeInformation
                Get-NetIPAddress | Export-Csv (Join-Path $netPath "IPAddresses.csv") -NoTypeInformation
                Get-NetRoute | Export-Csv (Join-Path $netPath "Routes.csv") -NoTypeInformation
                
                # Active connections
                Get-NetTCPConnection | Export-Csv (Join-Path $netPath "TCPConnections.csv") -NoTypeInformation
                Get-NetUDPEndpoint | Export-Csv (Join-Path $netPath "UDPEndpoints.csv") -NoTypeInformation
                
                # DNS cache
                Get-DnsClientCache | Export-Csv (Join-Path $netPath "DNSCache.csv") -NoTypeInformation
                
                # Firewall rules
                Get-NetFirewallRule | Export-Csv (Join-Path $netPath "FirewallRules.csv") -NoTypeInformation
                Get-NetFirewallProfile | Export-Csv (Join-Path $netPath "FirewallProfiles.csv") -NoTypeInformation
                
                # ARP cache
                Get-NetNeighbor | Export-Csv (Join-Path $netPath "ARPCache.csv") -NoTypeInformation
                
                # Network shares
                Get-SmbShare | Export-Csv (Join-Path $netPath "Shares.csv") -NoTypeInformation
                Get-SmbSession | Export-Csv (Join-Path $netPath "SMBSessions.csv") -NoTypeInformation
                
                $results.ArtifactsCollected += "Network Information"
                Write-CollectionLog "Collected network information"
            }
            catch {
                $results.Errors += "Network: $_"
                Write-CollectionLog "Error collecting network info: $_" 'ERROR'
            }
            
            # Collection 4: Event Logs (Standard and Comprehensive)
            if ($CollectionType -in @('Standard', 'Comprehensive')) {
                Write-Host "[4/10] Collecting event logs..." -ForegroundColor Cyan
                try {
                    $eventPath = Join-Path $collectionPath 'EventLogs'
                    
                    # Security events (last 7 days)
                    Get-WinEvent -FilterHashtable @{LogName='Security'; StartTime=(Get-Date).AddDays(-7)} -MaxEvents 10000 -ErrorAction SilentlyContinue |
                        Select-Object TimeCreated, Id, LevelDisplayName, Message |
                        Export-Csv (Join-Path $eventPath "Security_Recent.csv") -NoTypeInformation
                    
                    # System events (last 7 days)
                    Get-WinEvent -FilterHashtable @{LogName='System'; StartTime=(Get-Date).AddDays(-7)} -MaxEvents 10000 -ErrorAction SilentlyContinue |
                        Select-Object TimeCreated, Id, LevelDisplayName, Message |
                        Export-Csv (Join-Path $eventPath "System_Recent.csv") -NoTypeInformation
                    
                    # Application events (last 7 days)
                    Get-WinEvent -FilterHashtable @{LogName='Application'; StartTime=(Get-Date).AddDays(-7)} -MaxEvents 10000 -ErrorAction SilentlyContinue |
                        Select-Object TimeCreated, Id, LevelDisplayName, Message |
                        Export-Csv (Join-Path $eventPath "Application_Recent.csv") -NoTypeInformation
                    
                    # PowerShell logs
                    Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; StartTime=(Get-Date).AddDays(-7)} -MaxEvents 5000 -ErrorAction SilentlyContinue |
                        Select-Object TimeCreated, Id, Message |
                        Export-Csv (Join-Path $eventPath "PowerShell_Recent.csv") -NoTypeInformation
                    
                    $results.ArtifactsCollected += "Event Logs"
                    Write-CollectionLog "Collected event logs"
                }
                catch {
                    $results.Errors += "Event Logs: $_"
                    Write-CollectionLog "Error collecting event logs: $_" 'ERROR'
                }
            }
            else {
                Write-Host "[4/10] Event logs: SKIPPED (Quick mode)" -ForegroundColor Yellow
            }
            
            # Collection 5: Registry Artifacts (Standard and Comprehensive)
            if ($CollectionType -in @('Standard', 'Comprehensive')) {
                Write-Host "[5/10] Collecting registry artifacts..." -ForegroundColor Cyan
                try {
                    $regPath = Join-Path $collectionPath 'Registry'
                    
                    # Run keys
                    $runKeys = @(
                        'HKLM:\Software\Microsoft\Windows\CurrentVersion\Run',
                        'HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce',
                        'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run',
                        'HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce'
                    )
                    
                    $runEntries = foreach ($key in $runKeys) {
                        if (Test-Path $key) {
                            Get-ItemProperty -Path $key | Select-Object PSPath, PSChildName, *
                        }
                    }
                    $runEntries | Export-Csv (Join-Path $regPath "RunKeys.csv") -NoTypeInformation
                    
                    # Installed software
                    $software = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
                        Where-Object { $_.DisplayName } |
                        Select-Object DisplayName, Publisher, InstallDate, DisplayVersion
                    $software | Export-Csv (Join-Path $regPath "InstalledSoftware.csv") -NoTypeInformation
                    
                    # USB history
                    $usb = Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Enum\USBSTOR\* -ErrorAction SilentlyContinue |
                        Select-Object PSChildName, FriendlyName
                    $usb | Export-Csv (Join-Path $regPath "USBHistory.csv") -NoTypeInformation
                    
                    $results.ArtifactsCollected += "Registry Artifacts"
                    Write-CollectionLog "Collected registry artifacts"
                }
                catch {
                    $results.Errors += "Registry: $_"
                    Write-CollectionLog "Error collecting registry: $_" 'ERROR'
                }
            }
            else {
                Write-Host "[5/10] Registry artifacts: SKIPPED (Quick mode)" -ForegroundColor Yellow
            }
            
            # Collection 6: File System Artifacts (Comprehensive only)
            if ($CollectionType -eq 'Comprehensive' -or $IncludeDiskArtifacts) {
                Write-Host "[6/10] Collecting file system artifacts..." -ForegroundColor Cyan
                try {
                    $fsPath = Join-Path $collectionPath 'FileSystem'
                    
                    # Recent files in temp directories
                    $tempPaths = @("$env:TEMP", "$env:SystemRoot\Temp", "$env:LOCALAPPDATA\Temp")
                    $recentFiles = foreach ($temp in $tempPaths) {
                        if (Test-Path $temp) {
                            Get-ChildItem -Path $temp -File -Recurse -ErrorAction SilentlyContinue |
                                Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } |
                                Select-Object FullName, Name, Length, CreationTime, LastWriteTime
                        }
                    }
                    $recentFiles | Export-Csv (Join-Path $fsPath "RecentTempFiles.csv") -NoTypeInformation
                    
                    # Prefetch files
                    if (Test-Path "$env:SystemRoot\Prefetch") {
                        Get-ChildItem "$env:SystemRoot\Prefetch" -Filter *.pf |
                            Select-Object Name, Length, CreationTime, LastWriteTime, LastAccessTime |
                            Export-Csv (Join-Path $fsPath "Prefetch.csv") -NoTypeInformation
                    }
                    
                    # Recent downloads
                    $downloadsPath = "$env:USERPROFILE\Downloads"
                    if (Test-Path $downloadsPath) {
                        Get-ChildItem $downloadsPath -File -Recurse -ErrorAction SilentlyContinue |
                            Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-30) } |
                            Select-Object FullName, Name, Length, CreationTime, LastWriteTime |
                            Export-Csv (Join-Path $fsPath "RecentDownloads.csv") -NoTypeInformation
                    }
                    
                    $results.ArtifactsCollected += "File System Artifacts"
                    Write-CollectionLog "Collected file system artifacts"
                }
                catch {
                    $results.Errors += "File System: $_"
                    Write-CollectionLog "Error collecting file system: $_" 'ERROR'
                }
            }
            else {
                Write-Host "[6/10] File system artifacts: SKIPPED" -ForegroundColor Yellow
            }
            
            # Collection 7: Security Analysis (Standard and Comprehensive)
            if ($CollectionType -in @('Standard', 'Comprehensive')) {
                Write-Host "[7/10] Running security analysis..." -ForegroundColor Cyan
                try {
                    $secPath = Join-Path $collectionPath 'SecurityAnalysis'
                    New-Item -Path $secPath -ItemType Directory -Force | Out-Null
                    
                    # Persistence mechanisms
                    $persistence = Find-PersistenceMechanisms
                    $persistence | ConvertTo-Json -Depth 5 | Out-File (Join-Path $secPath "Persistence.json") -Encoding UTF8
                    
                    # Network anomalies
                    $network = Find-NetworkAnomalies -IncludeEstablished
                    $network | ConvertTo-Json -Depth 5 | Out-File (Join-Path $secPath "NetworkAnomalies.json") -Encoding UTF8
                    
                    # Authentication analysis
                    $auth = Find-SuspiciousAuthentication -Hours 168
                    $auth | ConvertTo-Json -Depth 5 | Out-File (Join-Path $secPath "Authentication.json") -Encoding UTF8
                    
                    $results.ArtifactsCollected += "Security Analysis"
                    Write-CollectionLog "Completed security analysis"
                }
                catch {
                    $results.Errors += "Security Analysis: $_"
                    Write-CollectionLog "Error in security analysis: $_" 'ERROR'
                }
            }
            else {
                Write-Host "[7/10] Security analysis: SKIPPED (Quick mode)" -ForegroundColor Yellow
            }
            
            # Collection 8: Memory Dump (if requested)
            if ($IncludeMemoryDump) {
                Write-Host "[8/10] Creating memory dump..." -ForegroundColor Cyan
                Write-Warning "Memory dump requires significant disk space and time"
                try {
                    $memPath = Join-Path $collectionPath 'Memory'
                    Write-CollectionLog "Memory dump requested but requires external tools (e.g., WinPMEM, DumpIt)" 'WARNING'
                    
                    # Note: Full memory dump requires external tools
                    $note = @"
Memory dump collection requires external tools such as:
- WinPMEM (Rekall)
- DumpIt (Comae)
- Magnet RAM Capture
- FTK Imager
 
Please use appropriate forensic tools for memory acquisition.
"@

                    $note | Out-File (Join-Path $memPath "MemoryDump_Instructions.txt")
                    
                    $results.ArtifactsCollected += "Memory Dump Instructions"
                }
                catch {
                    $results.Errors += "Memory: $_"
                    Write-CollectionLog "Memory dump: $_" 'ERROR'
                }
            }
            else {
                Write-Host "[8/10] Memory dump: SKIPPED" -ForegroundColor Yellow
            }
            
            # Collection 9: Timeline Generation
            Write-Host "[9/10] Generating timeline..." -ForegroundColor Cyan
            try {
                $timelinePath = Join-Path $collectionPath 'Timeline'
                
                $timeline = @()
                
                # Process start times
                Get-Process | ForEach-Object {
                    try {
                        if ($_.StartTime) {
                            $timeline += [PSCustomObject]@{
                                Timestamp = $_.StartTime
                                Type = 'ProcessStart'
                                Description = "$($_.ProcessName) (PID: $($_.Id))"
                                Details = $_.Path
                            }
                        }
                    } catch {}
                }
                
                # Recent file modifications
           
  # Recent file modifications
if ($null -ne (Get-Variable -Name 'recentFiles' -ErrorAction SilentlyContinue) -and $recentFiles) {
    $recentFiles | Where-Object { $_ } | ForEach-Object {
        $timeline += [PSCustomObject]@{
            Timestamp = $_.LastWriteTime
            Type = 'FileModified'
            Description = $_.Name
            Details = $_.FullName
        }
    }
}

                
                $timeline | Sort-Object Timestamp -Descending |
                    Export-Csv (Join-Path $timelinePath "Timeline.csv") -NoTypeInformation
                
                $results.ArtifactsCollected += "Timeline"
                Write-CollectionLog "Generated timeline"
            }
            catch {
                $results.Errors += "Timeline: $_"
                Write-CollectionLog "Error generating timeline: $_" 'ERROR'
            }
            
            # Collection 10: Collection Summary
            Write-Host "[10/10] Finalizing collection..." -ForegroundColor Cyan
            
            # Calculate total size
            $totalSize = (Get-ChildItem $collectionPath -Recurse -File | Measure-Object -Property Length -Sum).Sum
            $results.TotalSize = [math]::Round($totalSize / 1MB, 2)
            $results.Status = 'Completed'
            
            # Create hash manifest for integrity
            $hashManifest = Get-ChildItem $collectionPath -Recurse -File | ForEach-Object {
                [PSCustomObject]@{
                    Path = $_.FullName.Replace($collectionPath, '')
                    SHA256 = (Get-FileHash $_.FullName -Algorithm SHA256).Hash
                    Size = $_.Length
                }
            }
            $hashManifest | Export-Csv (Join-Path $collectionPath "HashManifest.csv") -NoTypeInformation
            
            Write-CollectionLog "Collection completed successfully"
            
        }
        catch {
            $results.Status = 'Failed'
            $results.Errors += "Fatal: $_"
            Write-CollectionLog "Collection failed: $_" 'ERROR'
            throw
        }
    }
    
    end {
        # Generate collection report
        $report = @"
=== FORENSIC COLLECTION REPORT ===
Collection Date: $($results.CollectionDate)
Collection Type: $($results.CollectionType)
Computer Name: $($results.ComputerName)
Status: $($results.Status)
 
ARTIFACTS COLLECTED:
$($results.ArtifactsCollected | ForEach-Object { " - $_" } | Out-String)
 
TOTAL SIZE: $($results.TotalSize) MB
 
ERRORS: $($results.Errors.Count)
$($results.Errors | ForEach-Object { " - $_" } | Out-String)
 
OUTPUT PATH: $($results.OutputPath)
 
CHAIN OF CUSTODY:
- Collected by: $env:USERNAME
- Computer: $env:COMPUTERNAME
- Date/Time: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
- Hash manifest created for integrity verification
 
NEXT STEPS:
1. Review HashManifest.csv for file integrity
2. Preserve evidence using write-blocker if needed
3. Create forensic image of collected data
4. Document chain of custody
5. Begin analysis using appropriate forensic tools
"@

        
        $report | Out-File (Join-Path $collectionPath "CollectionReport.txt")
        
        Write-Host "`n=== FORENSIC COLLECTION COMPLETE ===" -ForegroundColor Green
        Write-Host "Status: $($results.Status)" -ForegroundColor $(if ($results.Status -eq 'Completed') { 'Green' } else { 'Red' })
        Write-Host "Total Size: $($results.TotalSize) MB" -ForegroundColor Cyan
        Write-Host "Artifacts: $($results.ArtifactsCollected.Count)" -ForegroundColor Cyan
        Write-Host "Errors: $($results.Errors.Count)" -ForegroundColor $(if ($results.Errors.Count -eq 0) { 'Green' } else { 'Yellow' })
        Write-Host "Output: $($results.OutputPath)" -ForegroundColor Cyan
        
        return $results
    }
}