Analysis/Get-FileSystemAnalysis.ps1

function Get-FileSystemAnalysis {
    <#
    .SYNOPSIS
        Analyzes file system for suspicious files and activities
    .DESCRIPTION
        Scans directories for malicious files, unauthorized changes, and suspicious patterns
    .PARAMETER Path
        Path to scan (default: system-critical directories)
    .PARAMETER Recursive
        Scan subdirectories recursively
    .PARAMETER CheckRecent
        Check for recently created/modified files
    .PARAMETER Hours
        Hours to look back for recent files (default: 24)
    .PARAMETER ExportPath
        Path to export detailed results
    .EXAMPLE
        Get-FileSystemAnalysis
        Get-FileSystemAnalysis -Path "C:\Windows\System32" -Recursive -CheckRecent -Hours 48
    .OUTPUTS
        PSCustomObject with file system analysis results
    #>

    
    [CmdletBinding()]
    param(
        [Parameter()]
        [string]$Path,
        
        [Parameter()]
        [switch]$Recursive,
        
        [Parameter()]
        [switch]$CheckRecent,
        
        [Parameter()]
        [int]$Hours = 24,
        
        [Parameter()]
        [string]$ExportPath
    )
    
    begin {
        Write-Host "Analyzing file system..." -ForegroundColor Cyan
        
        $results = [PSCustomObject]@{
            AnalysisDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
            SuspiciousFiles = @()
            RecentFiles = @()
            HiddenFiles = @()
            ExecutablesInTemp = @()
            AlternateDataStreams = @()
            Statistics = @{
                FilesScanned = 0
                SuspiciousFiles = 0
                RecentFiles = 0
                HiddenFiles = 0
                ADSFound = 0
            }
        }
        
        # Default critical paths to scan if none specified
        if (-not $Path) {
            $scanPaths = @(
                "$env:SystemRoot\Temp",
                "$env:TEMP",
                "$env:LOCALAPPDATA\Temp",
                "$env:PUBLIC",
                "$env:ProgramData"
            )
        }
        else {
            $scanPaths = @($Path)
        }
        
        # Suspicious file extensions
        $suspiciousExtensions = @(
            '.exe', '.dll', '.bat', '.cmd', '.vbs', '.js', '.ps1',
            '.scr', '.com', '.pif', '.hta', '.msi', '.jar'
        )
        
        # Known malicious file names
        $maliciousNames = @(
            'mimikatz', 'procdump', 'psexec', 'netcat', 'nc.exe',
            'pwdump', 'fgdump', 'wce.exe', 'gsecdump', 'lsass.dmp'
        )
        
        $startTime = (Get-Date).AddHours(-$Hours)
    }
    
    process {
        try {
            foreach ($scanPath in $scanPaths) {
                if (-not (Test-Path $scanPath)) {
                    Write-Warning "Path does not exist: $scanPath"
                    continue
                }
                
                Write-Verbose "Scanning path: $scanPath"
                
                # Get files
                $getChildParams = @{
                    Path = $scanPath
                    File = $true
                    Force = $true
                    ErrorAction = 'SilentlyContinue'
                }
                
                if ($Recursive) {
                    $getChildParams.Recurse = $true
                }
                
                $files = Get-ChildItem @getChildParams
                
                foreach ($file in $files) {
                    try {
                        $results.Statistics.FilesScanned++
                        
                        $isSuspicious = $false
                        $reasons = @()
                        
                        # Check 1: Hidden files
                        if ($file.Attributes -match 'Hidden') {
                            $results.HiddenFiles += [PSCustomObject]@{
                                Path = $file.FullName
                                Name = $file.Name
                                Size = [math]::Round($file.Length / 1KB, 2)
                                Created = $file.CreationTime
                                Modified = $file.LastWriteTime
                            }
                            $results.Statistics.HiddenFiles++
                            $isSuspicious = $true
                            $reasons += "Hidden file attribute"
                        }
                        
                        # Check 2: Malicious file names
                        foreach ($malName in $maliciousNames) {
                            if ($file.Name -match [regex]::Escape($malName)) {
                                $isSuspicious = $true
                                $reasons += "Matches known malicious filename: $malName"
                                break
                            }
                        }
                        
                        # Check 3: Executables in temp directories
                        if ($file.Extension -in $suspiciousExtensions -and 
                            $file.DirectoryName -match '(Temp|tmp|Temporary)') {
                            $results.ExecutablesInTemp += [PSCustomObject]@{
                                Path = $file.FullName
                                Name = $file.Name
                                Extension = $file.Extension
                                Size = [math]::Round($file.Length / 1KB, 2)
                                Created = $file.CreationTime
                            }
                            $isSuspicious = $true
                            $reasons += "Executable in temporary directory"
                        }
                        
                        # Check 4: Double extensions
                        if ($file.Name -match '\.[^.]+\.[^.]+$') {
                            $extensions = $file.Name -split '\.'
                            if ($extensions.Count -gt 2) {
                                $isSuspicious = $true
                                $reasons += "Multiple file extensions (possible masquerading)"
                            }
                        }
                        
                        # Check 5: Very recent files
                        if ($CheckRecent -and $file.CreationTime -gt $startTime) {
                            $results.RecentFiles += [PSCustomObject]@{
                                Path = $file.FullName
                                Name = $file.Name
                                Size = [math]::Round($file.Length / 1KB, 2)
                                Created = $file.CreationTime
                                Modified = $file.LastWriteTime
                            }
                            $results.Statistics.RecentFiles++
                        }
                        
                        # Check 6: Alternate Data Streams (ADS)
                        try {
                            $streams = Get-Item -Path $file.FullName -Stream * -ErrorAction SilentlyContinue | 
                                Where-Object { $_.Stream -ne ':$DATA' }
                            
                            if ($streams) {
                                foreach ($stream in $streams) {
                                    $results.AlternateDataStreams += [PSCustomObject]@{
                                        FilePath = $file.FullName
                                        FileName = $file.Name
                                        StreamName = $stream.Stream
                                        StreamSize = $stream.Length
                                    }
                                    $results.Statistics.ADSFound++
                                    $isSuspicious = $true
                                    $reasons += "Contains alternate data stream: $($stream.Stream)"
                                }
                            }
                        }
                        catch {
                            # ADS check failed
                        }
                        
                        # Check 7: Suspicious size (very small or very large executables)
                        if ($file.Extension -in @('.exe', '.dll')) {
                            if ($file.Length -lt 10KB) {
                                $isSuspicious = $true
                                $reasons += "Unusually small executable (<10KB)"
                            }
                            elseif ($file.Length -gt 50MB) {
                                $isSuspicious = $true
                                $reasons += "Unusually large executable (>50MB)"
                            }
                        }
                        
                        # Check 8: No company/product information
                        if ($file.Extension -in @('.exe', '.dll')) {
                            try {
                                $versionInfo = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($file.FullName)
                                if ([string]::IsNullOrEmpty($versionInfo.CompanyName) -and 
                                    [string]::IsNullOrEmpty($versionInfo.ProductName)) {
                                    $isSuspicious = $true
                                    $reasons += "No company or product information"
                                }
                            }
                            catch {
                                # Version info check failed
                            }
                        }
                        
                        # Add to suspicious files if flagged
                        if ($isSuspicious) {
                            $results.SuspiciousFiles += [PSCustomObject]@{
                                Path = $file.FullName
                                Name = $file.Name
                                Extension = $file.Extension
                                Size = [math]::Round($file.Length / 1KB, 2)
                                Created = $file.CreationTime
                                Modified = $file.LastWriteTime
                                Attributes = $file.Attributes
                                Reasons = ($reasons -join '; ')
                            }
                            $results.Statistics.SuspiciousFiles++
                        }
                        
                    }
                    catch {
                        Write-Verbose "Error analyzing file $($file.Name): $_"
                    }
                }
            }
            
        }
        catch {
            Write-Error "Error during file system analysis: $_"
            throw
        }
    }
    
    end {
        Write-Host "`nFile System Analysis Complete!" -ForegroundColor Green
        Write-Host "`n=== Statistics ===" -ForegroundColor Cyan
        Write-Host "Files scanned: $($results.Statistics.FilesScanned)" -ForegroundColor Yellow
        Write-Host "Suspicious files: $($results.Statistics.SuspiciousFiles)" -ForegroundColor $(if ($results.Statistics.SuspiciousFiles -gt 0) { 'Red' } else { 'Green' })
        Write-Host "Hidden files: $($results.Statistics.HiddenFiles)" -ForegroundColor Yellow
        Write-Host "Recent files: $($results.Statistics.RecentFiles)" -ForegroundColor Yellow
        Write-Host "Alternate data streams: $($results.Statistics.ADSFound)" -ForegroundColor $(if ($results.Statistics.ADSFound -gt 0) { 'Yellow' } else { 'Green' })
        
        # Export if requested
        if ($ExportPath) {
            if (-not (Test-Path $ExportPath)) {
                New-Item -Path $ExportPath -ItemType Directory -Force | Out-Null
            }
            $exportFile = Join-Path -Path $ExportPath -ChildPath "FileSystemAnalysis_$(Get-Date -Format 'yyyyMMdd_HHmmss').json"
            $results | ConvertTo-Json -Depth 5 | Out-File -FilePath $exportFile -Encoding UTF8
            Write-Host "`nResults exported to: $exportFile" -ForegroundColor Cyan
        }
        
        return $results
    }
}