Загрузка данных


$ErrorActionPreference = "SilentlyContinue"
$ProgressPreference = "SilentlyContinue"

# ============================================================
# SFT / Gazprombank Internet Bank / Edge IE Mode diagnostics
# READ-ONLY — ничего в системе не изменяет
# ============================================================

$Stamp = Get-Date -Format "yyyyMMdd_HHmmss"
$Desktop = [Environment]::GetFolderPath("Desktop")
$OutDir = Join-Path $Desktop "SFT_Diag_$env:COMPUTERNAME`_$Stamp"
New-Item -ItemType Directory -Path $OutDir -Force | Out-Null

$Summary = Join-Path $OutDir "SUMMARY.txt"
$Transcript = Join-Path $OutDir "FULL_TRANSCRIPT.txt"

Start-Transcript -Path $Transcript -Force | Out-Null

function H {
    param([string]$Text)
    "`r`n============================================================" | Tee-Object -FilePath $Summary -Append
    $Text | Tee-Object -FilePath $Summary -Append
    "============================================================" | Tee-Object -FilePath $Summary -Append
}

function L {
    param([string]$Text)
    $Text | Tee-Object -FilePath $Summary -Append
}

function Safe-Reg {
    param([string]$Path)
    if (Test-Path $Path) {
        Get-ItemProperty $Path |
            Select-Object * -ExcludeProperty PSPath,PSParentPath,PSChildName,PSDrive,PSProvider |
            Format-List | Out-String
    } else {
        "NOT FOUND: $Path"
    }
}

function Get-FileMagic {
    param([string]$Path)

    $o = [ordered]@{
        Path        = $Path
        Length      = $null
        Modified    = $null
        First16Hex  = $null
        PDFOffset   = $null
        Detected    = "UNKNOWN"
    }

    try {
        $fi = Get-Item -LiteralPath $Path -Force
        $o.Length = $fi.Length
        $o.Modified = $fi.LastWriteTime

        if ($fi.Length -gt 0) {
            $bytes = [IO.File]::ReadAllBytes($Path)
            $n = [Math]::Min(16,$bytes.Length)
            $head = $bytes[0..($n-1)]
            $o.First16Hex = ($head | ForEach-Object { $_.ToString("X2") }) -join " "

            $searchLen = [Math]::Min(1024,$bytes.Length)
            $ascii = [Text.Encoding]::ASCII.GetString($bytes,0,$searchLen)
            $pdf = $ascii.IndexOf("%PDF-")

            if ($pdf -ge 0) {
                $o.PDFOffset = $pdf
                if ($pdf -eq 0) {
                    $o.Detected = "PDF"
                } else {
                    $o.Detected = "PREFIX + PDF"
                }
            }
            elseif ($ascii -match '(?i)<html|<!doctype') {
                $o.Detected = "HTML"
            }
            elseif ($ascii -match '^\{\\rtf') {
                $o.Detected = "RTF"
            }
            elseif ($bytes.Length -ge 4 -and
                    $bytes[0] -eq 0x50 -and
                    $bytes[1] -eq 0x4B -and
                    $bytes[2] -eq 0x03 -and
                    $bytes[3] -eq 0x04) {
                $o.Detected = "ZIP/OFFICE"
            }
            elseif ($bytes.Length -ge 2 -and
                    $bytes[0] -eq 0x4D -and
                    $bytes[1] -eq 0x5A) {
                $o.Detected = "PE EXE/DLL"
            }
        }
    } catch {}

    [pscustomobject]$o
}


# ------------------------------------------------------------
# 1. SYSTEM
# ------------------------------------------------------------

H "1. SYSTEM / USER"

$os = Get-CimInstance Win32_OperatingSystem

L "Computer        : $env:COMPUTERNAME"
L "User            : $env:USERDOMAIN\$env:USERNAME"
L "Windows         : $($os.Caption)"
L "Version         : $($os.Version)"
L "Build           : $($os.BuildNumber)"
L "Architecture    : $env:PROCESSOR_ARCHITECTURE"
L "PowerShell      : $($PSVersionTable.PSVersion)"
L "Date            : $(Get-Date)"
L "64-bit OS       : $([Environment]::Is64BitOperatingSystem)"
L "64-bit PS       : $([Environment]::Is64BitProcess)"


# ------------------------------------------------------------
# 2. EDGE VERSION
# ------------------------------------------------------------

H "2. MICROSOFT EDGE"

$EdgePaths = @(
    "$env:ProgramFiles(x86)\Microsoft\Edge\Application\msedge.exe",
    "$env:ProgramFiles\Microsoft\Edge\Application\msedge.exe"
) | Select-Object -Unique

$EdgeFound = $false

foreach ($p in $EdgePaths) {
    if (Test-Path $p) {
        $EdgeFound = $true
        $v = (Get-Item $p).VersionInfo
        L "Edge path       : $p"
        L "Edge version    : $($v.ProductVersion)"
        L "File version    : $($v.FileVersion)"
    }
}

if (-not $EdgeFound) {
    L "WARNING: msedge.exe not found in standard locations."
}

$IEChooser = "$env:SystemRoot\System32\F12\IEChooser.exe"
L "IEChooser exists : $(Test-Path $IEChooser)"
L "IEChooser path   : $IEChooser"


# ------------------------------------------------------------
# 3. EDGE IE MODE POLICIES
# ------------------------------------------------------------

H "3. EDGE IE MODE POLICIES"

$EdgePolicyPaths = @(
    "HKLM:\SOFTWARE\Policies\Microsoft\Edge",
    "HKCU:\SOFTWARE\Policies\Microsoft\Edge",
    "HKLM:\SOFTWARE\Policies\Microsoft\Edge\Recommended",
    "HKCU:\SOFTWARE\Policies\Microsoft\Edge\Recommended"
)

foreach ($p in $EdgePolicyPaths) {
    L "`r`n--- $p ---"
    L (Safe-Reg $p)
}

$Integration = (
    Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Edge"
).InternetExplorerIntegrationLevel

if ($null -eq $Integration) {
    $Integration = (
        Get-ItemProperty "HKCU:\SOFTWARE\Policies\Microsoft\Edge"
    ).InternetExplorerIntegrationLevel
}

L ""
L "InternetExplorerIntegrationLevel = $Integration"

switch ($Integration) {
    1 { L "RESULT: IE Mode is explicitly ENABLED by policy." }
    0 { L "WARNING: IE integration policy is set to NONE." }
    2 { L "INFO: Policy value requests IE11 rather than IE Mode." }
    default { L "INFO: IE Mode policy value not explicitly found here." }
}


# ------------------------------------------------------------
# 4. IE / INTERNET SETTINGS / ZONES
# ------------------------------------------------------------

H "4. INTERNET EXPLORER / INTERNET SETTINGS"

$InternetKeys = @(
    "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings",
    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings",
    "HKCU:\Software\Microsoft\Internet Explorer\Main",
    "HKLM:\Software\Microsoft\Internet Explorer\Main"
)

foreach ($p in $InternetKeys) {
    L "`r`n--- $p ---"
    L (Safe-Reg $p)
}


# ------------------------------------------------------------
# 5. ZONEMAP — bankclient / gazprom
# ------------------------------------------------------------

H "5. SECURITY ZONES / ZONEMAP"

$ZoneRoots = @(
    "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap",
    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap"
)

$zoneDump = @()

foreach ($root in $ZoneRoots) {
    if (Test-Path $root) {
        Get-ChildItem $root -Recurse -ErrorAction SilentlyContinue |
            ForEach-Object {
                $props = Get-ItemProperty $_.PSPath
                $txt = ($props | Out-String)

                if ($_.Name -match '(?i)bankclient|gazprom|bank|cbs' -or
                    $txt -match '(?i)bankclient|gazprom|bank|cbs') {

                    $zoneDump += [pscustomobject]@{
                        RegistryPath = $_.Name
                        Values       = $txt.Replace("`r"," ").Replace("`n"," ")
                    }
                }
            }
    }
}

$zoneDump | Export-Csv (Join-Path $OutDir "zonemap_matches.csv") -NoTypeInformation -Encoding UTF8

if ($zoneDump.Count -eq 0) {
    L "No explicit bankclient/gazprom ZoneMap entries found."
} else {
    L "Found $($zoneDump.Count) matching ZoneMap entries."
}


# ------------------------------------------------------------
# 6. INSTALLED SOFTWARE
# ------------------------------------------------------------

H "6. INSTALLED SOFTWARE — SFT / SYNACTIS / BANK CLIENT"

$UninstallRoots = @(
    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
    "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
    "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
)

$Apps = foreach ($root in $UninstallRoots) {
    Get-ItemProperty $root |
        Where-Object DisplayName |
        Select-Object DisplayName,DisplayVersion,Publisher,InstallLocation,InstallDate,UninstallString
}

$Apps = $Apps | Sort-Object DisplayName -Unique
$Apps | Export-Csv (Join-Path $OutDir "installed_software_ALL.csv") -NoTypeInformation -Encoding UTF8

$RelevantApps = $Apps | Where-Object {
    ($_.DisplayName + " " + $_.Publisher + " " + $_.InstallLocation) -match
    '(?i)SFT|СФТ|Synactis|All.?In.?The.?Box|Gazprom|Газпром|Bank.?Client|Клиент.?Банк|Internet.?Bank|CBS'
}

$RelevantApps |
    Export-Csv (Join-Path $OutDir "installed_software_RELEVANT.csv") -NoTypeInformation -Encoding UTF8

if ($RelevantApps) {
    $RelevantApps | Format-Table -AutoSize | Out-String | Tee-Object -FilePath $Summary -Append
} else {
    L "WARNING: No obviously named SFT/Synactis/Bank Client software found in Uninstall registry."
}


# ------------------------------------------------------------
# 7. LIKELY SFT FILES / DIRECTORIES
# ------------------------------------------------------------

H "7. SFT / SYNACTIS / BANK FILES"

$SearchRoots = @(
    $env:ProgramFiles,
    ${env:ProgramFiles(x86)},
    $env:ProgramData,
    "$env:SystemRoot\Downloaded Program Files"
) | Where-Object { $_ -and (Test-Path $_) } | Select-Object -Unique

$DirMatches = @()

foreach ($root in $SearchRoots) {
    Get-ChildItem $root -Directory -Force -ErrorAction SilentlyContinue |
        Where-Object {
            $_.Name -match '(?i)SFT|СФТ|Synactis|Gazprom|Bank|Client|CBS'
        } |
        ForEach-Object {
            $DirMatches += $_.FullName
        }

    Get-ChildItem $root -Directory -Force -ErrorAction SilentlyContinue |
        ForEach-Object {
            Get-ChildItem $_.FullName -Directory -Force -ErrorAction SilentlyContinue |
                Where-Object {
                    $_.Name -match '(?i)SFT|СФТ|Synactis|Gazprom|Bank|Client|CBS'
                } |
                ForEach-Object {
                    $DirMatches += $_.FullName
                }
        }
}

$DirMatches = $DirMatches | Sort-Object -Unique
$DirMatches | Out-File (Join-Path $OutDir "relevant_directories.txt") -Encoding UTF8

if ($DirMatches) {
    $DirMatches | ForEach-Object { L $_ }
} else {
    L "No obvious vendor directories found in first two directory levels."
}


# ------------------------------------------------------------
# 8. COM / ACTIVEX / CLSID
# ------------------------------------------------------------

H "8. COM / ACTIVEX REGISTRATION"

$CLSIDRoots = @(
    "Registry::HKEY_CLASSES_ROOT\CLSID",
    "Registry::HKEY_CLASSES_ROOT\WOW6432Node\CLSID",
    "HKLM:\SOFTWARE\Classes\CLSID",
    "HKLM:\SOFTWARE\WOW6432Node\Classes\CLSID"
) | Select-Object -Unique

$ComResults = New-Object System.Collections.Generic.List[object]

foreach ($root in $CLSIDRoots) {

    if (-not (Test-Path $root)) { continue }

    foreach ($k in Get-ChildItem $root -ErrorAction SilentlyContinue) {

        $clsid = $k.PSChildName
        $friendly = (Get-ItemProperty $k.PSPath).'(default)'

        $inprocKey = Join-Path $k.PSPath "InprocServer32"
        $localKey  = Join-Path $k.PSPath "LocalServer32"
        $progKey   = Join-Path $k.PSPath "ProgID"

        $inproc = $null
        $local  = $null
        $progid = $null

        if (Test-Path $inprocKey) {
            $inproc = (Get-ItemProperty $inprocKey).'(default)'
        }

        if (Test-Path $localKey) {
            $local = (Get-ItemProperty $localKey).'(default)'
        }

        if (Test-Path $progKey) {
            $progid = (Get-ItemProperty $progKey).'(default)'
        }

        $blob = "$friendly $inproc $local $progid"

        if ($blob -match '(?i)SFT|СФТ|Synactis|All.?In.?The.?Box|Gazprom|Газпром|Bank.?Client|Клиент.?Банк|CBS') {

            $server = if ($inproc) { $inproc } else { $local }
            $exists = $null

            if ($server) {
                $candidate = [Environment]::ExpandEnvironmentVariables($server)
                $candidate = $candidate.Trim('"')

                if ($candidate -match '^([^,]+)') {
                    $candidate = $matches[1].Trim('" ')
                }

                if (Test-Path $candidate) {
                    $exists = $true
                } else {
                    $exists = $false
                }
            }

            $ComResults.Add([pscustomobject]@{
                Root        = $root
                CLSID       = $clsid
                Name        = $friendly
                ProgID      = $progid
                Inproc      = $inproc
                LocalServer = $local
                ServerExists= $exists
            })
        }
    }
}

$ComResults |
    Sort-Object CLSID -Unique |
    Export-Csv (Join-Path $OutDir "COM_ACTIVEX_relevant.csv") -NoTypeInformation -Encoding UTF8

if ($ComResults.Count -gt 0) {
    L "Found relevant COM/ActiveX registrations: $($ComResults.Count)"

    $BrokenCOM = $ComResults | Where-Object {
        $_.ServerExists -eq $false
    }

    if ($BrokenCOM) {
        L ""
        L "!!! WARNING: COM registrations whose DLL/EXE target is MISSING:"
        $BrokenCOM | Format-Table CLSID,Name,Inproc,LocalServer -AutoSize |
            Out-String | Tee-Object -FilePath $Summary -Append
    }
} else {
    L "No COM objects with obvious SFT/Synactis/Bank naming found."
}


# ------------------------------------------------------------
# 9. BROWSER HELPER OBJECTS
# ------------------------------------------------------------

H "9. IE BROWSER HELPER OBJECTS (BHO)"

$BHORoots = @(
    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects",
    "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects",
    "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects"
)

$BHO = @()

foreach ($root in $BHORoots) {
    if (Test-Path $root) {
        foreach ($k in Get-ChildItem $root) {
            $id = $k.PSChildName
            $name = $null
            $server = $null

            $clsidPaths = @(
                "Registry::HKEY_CLASSES_ROOT\CLSID\$id",
                "Registry::HKEY_CLASSES_ROOT\WOW6432Node\CLSID\$id"
            )

            foreach ($cp in $clsidPaths) {
                if (Test-Path $cp) {
                    $name = (Get-ItemProperty $cp).'(default)'

                    if (Test-Path "$cp\InprocServer32") {
                        $server = (Get-ItemProperty "$cp\InprocServer32").'(default)'
                    }

                    break
                }
            }

            $BHO += [pscustomobject]@{
                RegistryRoot = $root
                CLSID = $id
                Name = $name
                Server = $server
            }
        }
    }
}

$BHO | Export-Csv (Join-Path $OutDir "IE_BHO.csv") -NoTypeInformation -Encoding UTF8
L "Total BHO registrations found: $($BHO.Count)"

$RelevantBHO = $BHO | Where-Object {
    "$($_.Name) $($_.Server)" -match '(?i)SFT|Synactis|Gazprom|Bank|CBS|СФТ'
}

if ($RelevantBHO) {
    L ""
    L "Relevant BHO:"
    $RelevantBHO | Format-Table -AutoSize | Out-String |
        Tee-Object -FilePath $Summary -Append
}


# ------------------------------------------------------------
# 10. ACTIVEX COMPATIBILITY / BLOCK FLAGS
# ------------------------------------------------------------

H "10. ACTIVEX COMPATIBILITY / BLOCKING"

$AXRoots = @(
    "HKLM:\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility",
    "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Internet Explorer\ActiveX Compatibility",
    "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Ext\Settings",
    "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Ext\PreApproved",
    "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Ext\PreApproved"
)

$AX = @()

foreach ($root in $AXRoots) {
    if (Test-Path $root) {
        foreach ($k in Get-ChildItem $root) {
            $props = Get-ItemProperty $k.PSPath

            $AX += [pscustomobject]@{
                Root         = $root
                CLSID        = $k.PSChildName
                CompatibilityFlags = $props.CompatibilityFlags
                Flags        = $props.Flags
                Version      = $props.Version
            }
        }
    }
}

$AX | Export-Csv (Join-Path $OutDir "ActiveX_Compatibility.csv") -NoTypeInformation -Encoding UTF8

L "ActiveX compatibility/settings entries collected: $($AX.Count)"


# ------------------------------------------------------------
# 11. FILE ASSOCIATIONS
# ------------------------------------------------------------

H "11. FILE ASSOCIATIONS"

foreach ($ext in ".tmp",".pdf",".asp") {
    L "`r`n--- assoc $ext ---"
    L ((cmd /c "assoc $ext" 2>&1) | Out-String)

    $cr = "Registry::HKEY_CLASSES_ROOT\$ext"
    if (Test-Path $cr) {
        L (Safe-Reg $cr)
    }
}

L "`r`n--- PDF UserChoice ---"
L (Safe-Reg "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.pdf\UserChoice")

L "`r`n--- TMP UserChoice ---"
L (Safe-Reg "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.tmp\UserChoice")

L "`r`n--- PDF MIME mapping ---"
L (Safe-Reg "Registry::HKEY_CLASSES_ROOT\MIME\Database\Content Type\application/pdf")


# ------------------------------------------------------------
# 12. REPORT.ASP / REPORT.TMP CACHE
# ------------------------------------------------------------

H "12. BANK REPORT CACHE FILES"

$CacheRoots = @(
    "$env:LOCALAPPDATA\Microsoft\Windows\INetCache",
    "$env:LOCALAPPDATA\Temp",
    "$env:TEMP"
) | Select-Object -Unique

$ReportFiles = @()

foreach ($root in $CacheRoots) {
    if (Test-Path $root) {
        $ReportFiles += Get-ChildItem $root -Recurse -Force -File |
            Where-Object {
                $_.Name -match '(?i)^report(\..*)?$' -or
                $_.Name -match '(?i)report.*\.(tmp|asp|pdf)$'
            }
    }
}

$ReportFiles = $ReportFiles |
    Sort-Object LastWriteTime -Descending |
    Select-Object -First 30

$Magic = @()

foreach ($f in $ReportFiles) {
    $Magic += Get-FileMagic $f.FullName
}

$Magic |
    Export-Csv (Join-Path $OutDir "report_cache_analysis.csv") -NoTypeInformation -Encoding UTF8

if ($Magic) {
    $Magic | Format-Table -AutoSize | Out-String |
        Tee-Object -FilePath $Summary -Append

    $WrappedPDF = $Magic | Where-Object {
        $_.Detected -eq "PREFIX + PDF"
    }

    if ($WrappedPDF) {
        L ""
        L "IMPORTANT: report file(s) contain bytes BEFORE %PDF header."
        foreach ($w in $WrappedPDF) {
            L "  $($w.Path)"
            L "  PDF begins at byte offset: $($w.PDFOffset)"
            L "  First bytes: $($w.First16Hex)"
        }
    }
} else {
    L "No current report.asp/report.tmp files found in IE/Temp cache."
}


# ------------------------------------------------------------
# 13. EDGE / IE / BANK PROCESSES
# ------------------------------------------------------------

H "13. CURRENT PROCESSES"

$Proc = Get-CimInstance Win32_Process |
    Where-Object {
        $_.Name -match '(?i)msedge|iexplore|dllhost|rundll32|bank|sft|cbs|synact'
    } |
    Select-Object Name,ProcessId,ExecutablePath,CommandLine

$Proc |
    Export-Csv (Join-Path $OutDir "processes.csv") -NoTypeInformation -Encoding UTF8

$Proc | Format-Table Name,ProcessId,ExecutablePath -AutoSize |
    Out-String | Tee-Object -FilePath $Summary -Append


# ------------------------------------------------------------
# 14. APPLICATION EVENTS
# ------------------------------------------------------------

H "14. APPLICATION / CRASH EVENTS — LAST 24 HOURS"

$Since = (Get-Date).AddHours(-24)

$AppEvents = Get-WinEvent -FilterHashtable @{
    LogName   = "Application"
    StartTime = $Since
} -ErrorAction SilentlyContinue |
Where-Object {
    $_.ProviderName -match '(?i)Application Error|Windows Error Reporting|SideBySide|\.NET Runtime|Application Hang' -or
    $_.Message -match '(?i)msedge|iexplore|SFT|СФТ|Synactis|bankclient|Gazprom|CBS|ActiveX|report\.tmp|report\.asp'
} |
Select-Object TimeCreated,Id,LevelDisplayName,ProviderName,Message

$AppEvents |
    Export-Csv (Join-Path $OutDir "events_APPLICATION.csv") -NoTypeInformation -Encoding UTF8

L "Relevant Application events: $($AppEvents.Count)"


# ------------------------------------------------------------
# 15. CODE INTEGRITY
# ------------------------------------------------------------

H "15. CODE INTEGRITY / DLL BLOCKS"

$CIEvents = @()

$CILog = "Microsoft-Windows-CodeIntegrity/Operational"

if (Get-WinEvent -ListLog $CILog -ErrorAction SilentlyContinue) {

    $CIEvents = Get-WinEvent -FilterHashtable @{
        LogName   = $CILog
        StartTime = $Since
    } -ErrorAction SilentlyContinue |
    Where-Object {
        $_.Message -match '(?i)msedge|iexplore|bank|sft|synact|cbs|dll|ocx'
    } |
    Select-Object TimeCreated,Id,LevelDisplayName,Message

    $CIEvents |
        Export-Csv (Join-Path $OutDir "events_CODE_INTEGRITY.csv") -NoTypeInformation -Encoding UTF8

    L "Relevant Code Integrity events: $($CIEvents.Count)"
} else {
    L "Code Integrity Operational log unavailable."
}


# ------------------------------------------------------------
# 16. APPLOCKER
# ------------------------------------------------------------

H "16. APPLOCKER — EXE/DLL"

$AppLockerEvents = @()

$ALLogs = @(
    "Microsoft-Windows-AppLocker/EXE and DLL",
    "Microsoft-Windows-AppLocker/MSI and Script"
)

foreach ($log in $ALLogs) {

    if (Get-WinEvent -ListLog $log -ErrorAction SilentlyContinue) {

        $tmp = Get-WinEvent -FilterHashtable @{
            LogName   = $log
            StartTime = $Since
        } -ErrorAction SilentlyContinue |
        Where-Object {
            $_.Message -match '(?i)edge|iexplore|bank|sft|synact|cbs|dll|ocx'
        } |
        Select-Object TimeCreated,Id,LevelDisplayName,
                      @{N="Log";E={$log}},Message

        $AppLockerEvents += $tmp
    }
}

$AppLockerEvents |
    Export-Csv (Join-Path $OutDir "events_APPLOCKER.csv") -NoTypeInformation -Encoding UTF8

L "Relevant AppLocker events: $($AppLockerEvents.Count)"


# ------------------------------------------------------------
# 17. QUICK AUTOMATIC ASSESSMENT
# ------------------------------------------------------------

H "17. QUICK ASSESSMENT"

if ($Integration -eq 1) {
    L "[OK] Edge IE Mode policy = enabled."
} else {
    L "[CHECK] IE Mode policy does not clearly equal 1 in the inspected policy locations."
}

if ($RelevantApps) {
    L "[OK] Relevant SFT/Bank software is registered as installed."
} else {
    L "[CHECK] No obviously named SFT/Synactis package appears in Programs registry."
}

if ($ComResults.Count -gt 0) {
    L "[INFO] Relevant COM/ActiveX objects detected: $($ComResults.Count)"
} else {
    L "[CHECK] No obvious SFT/Synactis COM/ActiveX registration detected."
}

$BrokenCOM = $ComResults | Where-Object { $_.ServerExists -eq $false }

if ($BrokenCOM) {
    L "[HIGH] Found COM registration(s) pointing to missing DLL/EXE."
}

if ($RelevantBHO) {
    L "[INFO] Relevant Browser Helper Object detected."
}

if ($CIEvents.Count -gt 0) {
    L "[HIGH] Code Integrity produced relevant events. Inspect events_CODE_INTEGRITY.csv."
}

if ($AppLockerEvents.Count -gt 0) {
    L "[HIGH] AppLocker produced relevant events. Inspect events_APPLOCKER.csv."
}

if ($WrappedPDF) {
    L "[INFO] A downloaded report contains a non-PDF prefix before %PDF."
    L "       This is important for comparison with a WORKING workstation."
}

if (-not $WrappedPDF -and $Magic) {
    $normalPDF = $Magic | Where-Object { $_.Detected -eq "PDF" }
    if ($normalPDF) {
        L "[INFO] At least one cached report begins directly with %PDF."
    }
}

L ""
L "Best comparison:"
L "Run this SAME script on a workstation where Print/Preview still works."
L "Compare especially:"
L "  installed_software_RELEVANT.csv"
L "  COM_ACTIVEX_relevant.csv"
L "  IE_BHO.csv"
L "  ActiveX_Compatibility.csv"
L "  report_cache_analysis.csv"
L "  SUMMARY.txt"


# ------------------------------------------------------------
# FINISH / ZIP
# ------------------------------------------------------------

Stop-Transcript | Out-Null

$Zip = "$OutDir.zip"

Compress-Archive -Path "$OutDir\*" -DestinationPath $Zip -Force

Write-Host ""
Write-Host "============================================================" -ForegroundColor Cyan
Write-Host "DIAGNOSTICS COMPLETE" -ForegroundColor Green
Write-Host "============================================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "Folder:" -ForegroundColor Yellow
Write-Host $OutDir
Write-Host ""
Write-Host "ZIP:" -ForegroundColor Yellow
Write-Host $Zip
Write-Host ""
Write-Host "Пришли сюда ZIP целиком." -ForegroundColor Green