#requires -RunAsAdministrator
<#
.SYNOPSIS
    Fix PDF preview issues in Windows Explorer for Glaztech Industries

.DESCRIPTION
    Resolves PDF preview failures caused by Windows security updates (KB5066791/KB5066835)
    by unblocking PDF files and configuring trusted zones for Glaztech network resources.

.PARAMETER UnblockPaths
    Array of paths where PDFs should be unblocked. Supports UNC paths and local paths.
    Default: User Desktop, Downloads, Documents, and common network paths

.PARAMETER ServerNames
    Array of server hostnames/IPs to add to trusted Intranet zone
    Add Glaztech file servers here when identified

.PARAMETER WhatIf
    Shows what changes would be made without actually making them

.EXAMPLE
    .\Fix-PDFPreview-Glaztech.ps1
    Run with defaults, unblock PDFs and configure zones

.EXAMPLE
    .\Fix-PDFPreview-Glaztech.ps1 -UnblockPaths "\\fileserver\shared","C:\Data" -ServerNames "fileserver01","192.168.1.10"
    Specify custom paths and servers

.NOTES
    Company: Glaztech Industries
    Domain: glaztech.com
    Network: 192.168.0.0/24 through 192.168.9.0/24 (10 sites)
    Issue: Windows 10/11 security updates block PDF preview from network shares
    Deployment: GPO or remote PowerShell

    Version: 1.0
    Date: 2026-01-27
#>

[CmdletBinding(SupportsShouldProcess)]
param(
    [string[]]$UnblockPaths = @(),

    [string[]]$ServerNames = @(
        # TODO: Add Glaztech file server names/IPs here when identified
        # Example: "fileserver01", "192.168.1.50", "\\glaztech-fs01"
    )
)

$ErrorActionPreference = "Continue"
$Script:ChangesMade = 0

# Logging function
function Write-Log {
    param([string]$Message, [string]$Level = "INFO")

    $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $Color = switch ($Level) {
        "ERROR"   { "Red" }
        "WARNING" { "Yellow" }
        "SUCCESS" { "Green" }
        default   { "White" }
    }

    $LogMessage = "[$Timestamp] [$Level] $Message"
    Write-Host $LogMessage -ForegroundColor $Color

    # Log to file
    $LogPath = "C:\Temp\Glaztech-PDF-Fix.log"
    if (-not (Test-Path "C:\Temp")) { New-Item -ItemType Directory -Path "C:\Temp" -Force | Out-Null }
    Add-Content -Path $LogPath -Value $LogMessage
}

Write-Log "========================================"
Write-Log "Glaztech PDF Preview Fix Script"
Write-Log "Computer: $env:COMPUTERNAME"
Write-Log "User: $env:USERNAME"
Write-Log "========================================"

# Function to unblock files
function Remove-ZoneIdentifier {
    param([string]$Path, [string]$Filter = "*.pdf")

    if (-not (Test-Path $Path)) {
        Write-Log "Path not found: $Path" "WARNING"
        return 0
    }

    Write-Log "Scanning for PDFs in: $Path"

    try {
        $Files = Get-ChildItem -Path $Path -Filter $Filter -Recurse -File -ErrorAction SilentlyContinue
        $UnblockedCount = 0

        foreach ($File in $Files) {
            try {
                # Check if file has Zone.Identifier
                $ZoneId = Get-Item -Path $File.FullName -Stream Zone.Identifier -ErrorAction SilentlyContinue

                if ($ZoneId) {
                    if ($PSCmdlet.ShouldProcess($File.FullName, "Unblock file")) {
                        Unblock-File -Path $File.FullName -ErrorAction Stop
                        $UnblockedCount++
                        Write-Log "  Unblocked: $($File.FullName)" "SUCCESS"
                    }
                }
            } catch {
                Write-Log "  Failed to unblock: $($File.FullName) - $($_.Exception.Message)" "WARNING"
            }
        }

        Write-Log "Unblocked $UnblockedCount PDF files in $Path"
        return $UnblockedCount

    } catch {
        Write-Log "Error scanning path: $Path - $($_.Exception.Message)" "ERROR"
        return 0
    }
}

# Function to add sites to Intranet Zone
function Add-ToIntranetZone {
    param([string]$Site)

    $ZonePath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains"

    try {
        # Parse site for registry path creation
        if ($Site -match "^(\d+\.){3}\d+$") {
            # IP address - add to ESC Domains
            $EscPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\EscDomains\$Site"

            if (-not (Test-Path $EscPath)) {
                if ($PSCmdlet.ShouldProcess($Site, "Add IP to Intranet Zone")) {
                    New-Item -Path $EscPath -Force | Out-Null
                    Set-ItemProperty -Path $EscPath -Name "*" -Value 1 -Type DWord
                    Write-Log "  Added IP to Intranet Zone: $Site" "SUCCESS"
                    $Script:ChangesMade++
                }
            } else {
                Write-Log "  IP already in Intranet Zone: $Site"
            }
        } elseif ($Site -match "^\\\\(.+)$") {
            # UNC path - extract hostname
            $Hostname = $Matches[1] -replace "\\.*", ""
            Add-ToIntranetZone -Site $Hostname
        } else {
            # Hostname/domain
            $Parts = $Site -split "\."
            $BasePath = $ZonePath

            # Build registry path (reverse domain order)
            for ($i = $Parts.Count - 1; $i -ge 0; $i--) {
                $BasePath = Join-Path $BasePath $Parts[$i]
            }

            if (-not (Test-Path $BasePath)) {
                if ($PSCmdlet.ShouldProcess($Site, "Add domain to Intranet Zone")) {
                    New-Item -Path $BasePath -Force | Out-Null
                    Set-ItemProperty -Path $BasePath -Name "*" -Value 1 -Type DWord
                    Write-Log "  Added domain to Intranet Zone: $Site" "SUCCESS"
                    $Script:ChangesMade++
                }
            } else {
                Write-Log "  Domain already in Intranet Zone: $Site"
            }
        }
    } catch {
        Write-Log "  Failed to add $Site to Intranet Zone: $($_.Exception.Message)" "ERROR"
    }
}

# Function to configure PDF preview handler
function Enable-PDFPreview {
    $PreviewHandlerPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PreviewHandlers"
    $PDFPreviewCLSID = "{DC6EFB56-9CFA-464D-8880-44885D7DC193}"

    try {
        if ($PSCmdlet.ShouldProcess("PDF Preview Handler", "Enable")) {
            # Ensure preview handler is registered
            $HandlerExists = Get-ItemProperty -Path $PreviewHandlerPath -Name $PDFPreviewCLSID -ErrorAction SilentlyContinue

            if (-not $HandlerExists) {
                Write-Log "PDF Preview Handler not found in registry" "WARNING"
            } else {
                Write-Log "PDF Preview Handler is registered"
            }

            # Enable previews in Explorer
            Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "ShowPreviewHandlers" -Value 1 -Type DWord -ErrorAction Stop
            Write-Log "Enabled preview handlers in Windows Explorer" "SUCCESS"
            $Script:ChangesMade++
        }
    } catch {
        Write-Log "Failed to enable PDF preview: $($_.Exception.Message)" "ERROR"
    }
}

# MAIN EXECUTION
Write-Log "========================================"
Write-Log "STEP 1: Unblocking PDF Files"
Write-Log "========================================"

# Default paths to check
$DefaultPaths = @(
    "$env:USERPROFILE\Desktop",
    "$env:USERPROFILE\Downloads",
    "$env:USERPROFILE\Documents"
)

# Combine default and custom paths
$AllPaths = $DefaultPaths + $UnblockPaths | Select-Object -Unique

$TotalUnblocked = 0
foreach ($Path in $AllPaths) {
    $TotalUnblocked += Remove-ZoneIdentifier -Path $Path
}

Write-Log "Total PDFs unblocked: $TotalUnblocked" "SUCCESS"

Write-Log ""
Write-Log "========================================"
Write-Log "STEP 2: Configuring Trusted Zones"
Write-Log "========================================"

# Add Glaztech domain
Write-Log "Adding Glaztech domain to Intranet Zone..."
Add-ToIntranetZone -Site "glaztech.com"
Add-ToIntranetZone -Site "*.glaztech.com"

# Add all 10 Glaztech site IP ranges (192.168.0.0/24 through 192.168.9.0/24)
Write-Log "Adding Glaztech site IP ranges to Intranet Zone..."
for ($i = 0; $i -le 9; $i++) {
    $Network = "192.168.$i.*"
    Add-ToIntranetZone -Site $Network
}

# Add specific servers if provided
if ($ServerNames.Count -gt 0) {
    Write-Log "Adding specified servers to Intranet Zone..."
    foreach ($Server in $ServerNames) {
        Add-ToIntranetZone -Site $Server
    }
} else {
    Write-Log "No specific servers provided - add them with -ServerNames parameter" "WARNING"
}

Write-Log ""
Write-Log "========================================"
Write-Log "STEP 3: Enabling PDF Preview"
Write-Log "========================================"
Enable-PDFPreview

Write-Log ""
Write-Log "========================================"
Write-Log "STEP 4: Configuring Security Policies"
Write-Log "========================================"

# Disable SmartScreen for Intranet Zone
try {
    if ($PSCmdlet.ShouldProcess("Intranet Zone", "Disable SmartScreen")) {
        $IntranetZonePath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1"
        if (-not (Test-Path $IntranetZonePath)) {
            New-Item -Path $IntranetZonePath -Force | Out-Null
        }

        # Zone 1 = Local Intranet
        # 2702 = Use SmartScreen Filter (0 = Disable, 1 = Enable)
        Set-ItemProperty -Path $IntranetZonePath -Name "2702" -Value 0 -Type DWord -ErrorAction Stop
        Write-Log "Disabled SmartScreen for Intranet Zone" "SUCCESS"
        $Script:ChangesMade++
    }
} catch {
    Write-Log "Failed to configure SmartScreen: $($_.Exception.Message)" "ERROR"
}

Write-Log ""
Write-Log "========================================"
Write-Log "SUMMARY"
Write-Log "========================================"
Write-Log "PDFs Unblocked: $TotalUnblocked"
Write-Log "Configuration Changes: $Script:ChangesMade"
Write-Log ""

if ($Script:ChangesMade -gt 0 -or $TotalUnblocked -gt 0) {
    Write-Log "Changes applied - restarting Windows Explorer..." "WARNING"

    try {
        # Stop Explorer
        Stop-Process -Name explorer -Force -ErrorAction Stop
        Write-Log "Windows Explorer stopped" "SUCCESS"

        # Wait a moment for processes to clean up
        Start-Sleep -Seconds 2

        # Explorer will auto-restart, but we can force it if needed
        $ExplorerRunning = Get-Process -Name explorer -ErrorAction SilentlyContinue
        if (-not $ExplorerRunning) {
            Start-Process explorer.exe
            Write-Log "Windows Explorer restarted" "SUCCESS"
        }
    } catch {
        Write-Log "Could not restart Explorer automatically: $($_.Exception.Message)" "WARNING"
        Write-Log "Please restart Explorer manually: Stop-Process -Name explorer -Force" "WARNING"
    }

    Write-Log ""
    Write-Log "COMPLETED SUCCESSFULLY" "SUCCESS"
} else {
    Write-Log "No changes needed - system already configured" "SUCCESS"
}

Write-Log "Log file: C:\Temp\Glaztech-PDF-Fix.log"
Write-Log "========================================"

# Return summary object
[PSCustomObject]@{
    ComputerName = $env:COMPUTERNAME
    PDFsUnblocked = $TotalUnblocked
    ConfigChanges = $Script:ChangesMade
    Success = ($TotalUnblocked -gt 0 -or $Script:ChangesMade -gt 0)
    LogPath = "C:\Temp\Glaztech-PDF-Fix.log"
}
