{"uuid": "c906e604-4446-409d-976e-cc2791216220", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2021-34481", "type": "seen", "source": "https://gist.github.com/tamtruong90/7bb789712512d01a0ae9bf4fe71aa287", "content": "#Requires -Version 5.1\n&lt;#\n    FixSharePrinter.bundle.ps1 \u2014 File g\u1ed9p t\u1ef1 sinh b\u1edfi Build-Bundle.ps1.\n    KH\u00d4NG s\u1eeda tr\u1ef1c ti\u1ebfp file n\u00e0y \u2014 s\u1eeda trong src\\ ho\u1eb7c Gui\\ r\u1ed3i ch\u1ea1y l\u1ea1i Build-Bundle.ps1.\n    Ng\u00e0y build: 2026-09-27 23:17:02\n#&gt;\nparam([switch]$NoGui)\n$ErrorActionPreference = 'Continue'\n$Script:FSP_LogFile = Join-Path $env:TEMP \"FixSharePrinter_$(Get-Date -Format 'yyyyMMdd_HHmmss').log\"\n\n# ---- src/Logging.ps1 ----\nfunction Write-Log {\n    &lt;#\n    .SYNOPSIS\n        Ghi 1 d\u00f2ng log ra file log d\u00f9ng chung c\u1ee7a module, v\u00e0:\n          - N\u1ebfu giao di\u1ec7n WPF \u0111ang m\u1edf (Script:WpfLogBox t\u1ed3n t\u1ea1i) -&gt; \u0111\u01b0a v\u00e0o khung\n            \"NH\u1eacT K\u00dd HO\u1ea0T \u0110\u1ed8NG\" tr\u00ean GUI (Add-WpfLogLine).\n          - N\u1ebfu ch\u01b0a c\u00f3 GUI (v\u00ed d\u1ee5 \u0111ang ch\u1ea1y -NoGui, ho\u1eb7c log tr\u01b0\u1edbc khi m\u1edf c\u1eeda s\u1ed5) -&gt;\n            in ra console nh\u01b0 b\u00ecnh th\u01b0\u1eddng.\n        Nh\u1edd v\u1eady khi ch\u1ea1y ch\u1ebf \u0111\u1ed9 GUI, to\u00e0n b\u1ed9 n\u1ed9i dung \"console\" \u0111\u1ec1u d\u1ed3n h\u1ebft v\u00e0o \u00f4\n        nh\u1eadt k\u00fd c\u1ee7a c\u1eeda s\u1ed5 WPF thay v\u00ec hi\u1ec7n \u1edf c\u1eeda s\u1ed5 console (c\u1eeda s\u1ed5 console l\u00fac \u0111\u00f3\n        \u0111\u00e3 b\u1ecb \u1ea9n \u2014 xem Set-ConsoleWindowVisibility trong Gui\\WpfShell.ps1).\n    #&gt;\n    param([string]$Message, [string]$Level = 'INFO')\n    $line = \"[{0}] [{1}] {2}\" -f (Get-Date -Format 'HH:mm:ss'), $Level, $Message\n    $color = switch ($Level) {\n        'OK'    { 'Green' }\n        'WARN'  { 'Yellow' }\n        'ERR'   { 'Red' }\n        default { 'Gray' }\n    }\n    if ($Script:FSP_LogFile) {\n        Add-Content -Path $Script:FSP_LogFile -Value $line -ErrorAction SilentlyContinue\n    }\n    if ($Script:WpfLogBox -and (Get-Command -Name Add-WpfLogLine -ErrorAction SilentlyContinue)) {\n        Add-WpfLogLine -Text $line -Color $color\n    } else {\n        Write-Host $line -ForegroundColor $color\n    }\n}\n\n\n# ---- src/Admin.ps1 ----\nfunction Test-IsAdmin {\n    &lt;#\n    .SYNOPSIS\n        Tr\u1ea3 v\u1ec1 $true n\u1ebfu ti\u1ebfn tr\u00ecnh hi\u1ec7n t\u1ea1i \u0111ang ch\u1ea1y v\u1edbi quy\u1ec1n Administrator.\n    #&gt;\n    $id = [Security.Principal.WindowsIdentity]::GetCurrent()\n    $p  = New-Object Security.Principal.WindowsPrincipal($id)\n    return $p.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)\n}\n\nfunction Invoke-SelfElevate {\n    &lt;#\n    .SYNOPSIS\n        N\u1ebfu ti\u1ebfn tr\u00ecnh ch\u01b0a ch\u1ea1y Admin, t\u1ef1 kh\u1edfi \u0111\u1ed9ng l\u1ea1i ch\u00ednh script hi\u1ec7n t\u1ea1i (PSCommandPath)\n        v\u1edbi quy\u1ec1n Administrator (UAC prompt), r\u1ed3i tho\u00e1t ti\u1ebfn tr\u00ecnh hi\u1ec7n t\u1ea1i.\n    .PARAMETER ScriptPath\n        \u0110\u01b0\u1eddng d\u1eabn script c\u1ea7n ch\u1ea1y l\u1ea1i v\u1edbi quy\u1ec1n admin. M\u1eb7c \u0111\u1ecbnh d\u00f9ng $PSCommandPath c\u1ee7a caller.\n    .PARAMETER Arguments\n        C\u00e1c tham s\u1ed1 d\u00f2ng l\u1ec7nh kh\u00e1c c\u1ea7n truy\u1ec1n ti\u1ebfp (v\u00ed d\u1ee5 -NoGui).\n    #&gt;\n    param(\n        [string]$ScriptPath = $MyInvocation.PSCommandPath,\n        [string[]]$Arguments = @()\n    )\n\n    if (Test-IsAdmin) { return $true }\n\n    Write-Host \"\u0110ang y\u00eau c\u1ea7u quy\u1ec1n Qu\u1ea3n tr\u1ecb vi\u00ean (Administrator)...\" -ForegroundColor Yellow\n    try {\n        $target = if ($ScriptPath) { $ScriptPath } else { $PSCommandPath }\n        $argLine = \"-NoProfile -ExecutionPolicy Bypass -File `\"$target`\"\"\n        if ($Arguments -and $Arguments.Count -gt 0) { $argLine += \" \" + ($Arguments -join ' ') }\n        # -WindowStyle Hidden \u0111\u1ec3 gi\u1ea3m vi\u1ec7c ch\u1edbp c\u1eeda s\u1ed5 console tr\u01b0\u1edbc khi ti\u1ebfn tr\u00ecnh m\u1edbi t\u1ef1 \u1ea9n n\u00f3 \u0111i.\n        Start-Process powershell -ArgumentList $argLine -Verb RunAs -WindowStyle Hidden\n    } catch {\n        Write-Host \"Ng\u01b0\u1eddi d\u00f9ng t\u1eeb ch\u1ed1i c\u1ea5p quy\u1ec1n Admin ho\u1eb7c l\u1ed7i khi elevate: $($_.Exception.Message)\" -ForegroundColor Red\n    }\n    return $false\n}\n\n\nif (-not (Test-IsAdmin)) {\n    $extraArgs = @(); if ($NoGui) { $extraArgs += '-NoGui' }\n    Invoke-SelfElevate -ScriptPath $PSCommandPath -Arguments $extraArgs\n    exit\n}\n\n# ---- src/Clear-StalePrinterPorts.ps1 ----\nfunction Clear-StalePrinterPorts {\n    &lt;#\n    .SYNOPSIS\n        D\u1eebng Spooler + kill ti\u1ebfn tr\u00ecnh driver h\u00e3ng m\u00e1y in \u0111ang treo c\u1ed5ng, sau \u0111\u00f3 xo\u00e1 c\u00e1c\n        c\u1ed5ng USB \u1ea3o (USB*/CNUSB*) kh\u00f4ng c\u00f2n m\u00e1y in n\u00e0o tr\u1ecf t\u1edbi, r\u1ed3i rescan l\u1ea1i thi\u1ebft b\u1ecb.\n    #&gt;\n    Write-Log \"\u0110ang d\u1ecdn d\u1eb9p c\u1ed5ng USB \u1ea3o / treo kh\u00f4ng s\u1eed d\u1ee5ng...\"\n    try {\n        Write-Log \"  T\u1ea1m d\u1eebng Spooler &amp; gi\u1ea3i ph\u00f3ng ti\u1ebfn tr\u00ecnh driver h\u00e3ng m\u00e1y in...\"\n        Stop-Service -Name Spooler -Force -ErrorAction SilentlyContinue\n        Get-Process -Name \"Capn*\", \"CPCA*\", \"BrMs*\", \"HPCus*\", \"E_I*\" -ErrorAction SilentlyContinue |\n            Stop-Process -Force -ErrorAction SilentlyContinue\n        Start-Sleep -Seconds 1\n        Start-Service -Name Spooler -ErrorAction Stop\n\n        Write-Log \"  L\u1ecdc v\u00e0 xo\u00e1 c\u00e1c c\u1ed5ng USB kh\u00f4ng c\u00f3 m\u00e1y in s\u1eed d\u1ee5ng...\"\n        $dsPort = Get-PrinterPort -ErrorAction SilentlyContinue | Where-Object { $_.Name -like \"USB*\" -or $_.Name -like \"CNUSB*\" }\n        $portDangDung = (Get-Printer -ErrorAction SilentlyContinue).PortName\n\n        foreach ($port in $dsPort) {\n            if ($portDangDung -notcontains $port.Name) {\n                try {\n                    Remove-PrinterPort -Name $port.Name -ErrorAction Stop\n                    Write-Log \"  + \u0110\u00e3 xo\u00e1 c\u1ed5ng kh\u00f4ng d\u00f9ng: $($port.Name)\" \"OK\"\n                } catch {\n                    Write-Log \"  + Kh\u00f4ng xo\u00e1 \u0111\u01b0\u1ee3c c\u1ed5ng '$($port.Name)': $($_.Exception.Message)\" \"WARN\"\n                }\n            }\n        }\n\n        pnputil /scan-devices | Out-Null\n        Write-Log \"Ho\u00e0n t\u1ea5t d\u1ecdn d\u1eb9p c\u1ed5ng m\u00e1y in.\" \"OK\"\n    } catch {\n        Write-Log \"Clear-StalePrinterPorts: $($_.Exception.Message)\" \"ERR\"\n    }\n}\n\n\n# ---- src/Disable-PrinterWorkOfflineMode.ps1 ----\nfunction Disable-PrinterWorkOfflineMode {\n    &lt;#\n    .SYNOPSIS\n        B\u1ecf ch\u1ebf \u0111\u1ed9 \"Work Offline\" cho t\u1ea5t c\u1ea3 m\u00e1y in \u0111ang b\u1eadt ch\u1ebf \u0111\u1ed9 n\u00e0y, chuy\u1ec3n ch\u00fang v\u1ec1 ONLINE.\n    #&gt;\n    Write-Log \"\u0110ang ki\u1ec3m tra m\u00e1y in \u0111ang \u1edf ch\u1ebf \u0111\u1ed9 Work Offline...\"\n    try {\n        $dsMayInOffline = Get-Printer -ErrorAction SilentlyContinue | Where-Object { $_.WorkOffline -eq $true }\n        if (-not $dsMayInOffline) {\n            Write-Log \"T\u1ea5t c\u1ea3 m\u00e1y in \u0111\u1ec1u \u0111ang \u1edf ch\u1ebf \u0111\u1ed9 ONLINE.\" \"OK\"\n            return\n        }\n        foreach ($mayIn in $dsMayInOffline) {\n            try {\n                Set-Printer -Name $mayIn.Name -WorkOffline $false -ErrorAction Stop\n                Write-Log \"  + \u0110\u00e3 chuy\u1ec3n '$($mayIn.Name)' v\u1ec1 ONLINE.\" \"OK\"\n            } catch {\n                Write-Log \"  + Kh\u00f4ng chuy\u1ec3n \u0111\u01b0\u1ee3c '$($mayIn.Name)': $($_.Exception.Message)\" \"WARN\"\n            }\n        }\n        Write-Log \"\u0110\u00e3 chuy\u1ec3n to\u00e0n b\u1ed9 m\u00e1y in v\u1ec1 ch\u1ebf \u0111\u1ed9 ONLINE.\" \"OK\"\n    } catch {\n        Write-Log \"Disable-PrinterWorkOfflineMode: $($_.Exception.Message)\" \"ERR\"\n    }\n}\n\n\n# ---- src/Enable-GuestAndNullSessionAccess.ps1 ----\nfunction Enable-GuestAndNullSessionAccess {\n    &lt;#\n    .SYNOPSIS\n        Cho ph\u00e9p truy c\u1eadp ki\u1ec3u Guest/Null-session \u2014 c\u1ea7n thi\u1ebft khi share m\u00e1y in/file ki\u1ec3u\n        workgroup kh\u00f4ng d\u00f9ng t\u00e0i kho\u1ea3n \u0111\u00edch danh (ai trong m\u1ea1ng LAN c\u0169ng k\u1ebft n\u1ed1i \u0111\u01b0\u1ee3c).\n    .L\u01afU \u00dd\n        C\u00e1c thi\u1ebft l\u1eadp n\u00e0y l\u00e0m gi\u1ea3m m\u1ee9c b\u1ea3o m\u1eadt. Ch\u1ec9 n\u00ean d\u00f9ng trong m\u1ea1ng LAN n\u1ed9i b\u1ed9 tin c\u1eady,\n        kh\u00f4ng expose m\u00e1y ra Internet.\n    #&gt;\n    Write-Log \"\u0110ang c\u1ea5u h\u00ecnh Guest/Null-session access cho chia s\u1ebb ki\u1ec3u workgroup...\"\n    try {\n        Set-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Parameters' -Name 'RestrictNullSessAccess' -Value 0 -Type DWord -Force\n        Set-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa' -Name 'EveryoneIncludesAnonymous' -Value 1 -Type DWord -Force\n        Set-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa' -Name 'limitblankpassworduse' -Value 0 -Type DWord -Force\n        Set-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa' -Name 'ForceGuest' -Value 1 -Type DWord -Force\n\n        net user Guest /active:yes *&gt; $null\n        net localgroup Guests Guest /add *&gt; $null\n\n        Write-Log \"\u0110\u00e3 b\u1eadt Guest account + n\u1edbi Null-session/Anonymous access.\" \"OK\"\n        Write-Log \"  (C\u00e2n nh\u1eafc: ch\u1ec9 n\u00ean b\u1eadt khi m\u1ea1ng LAN n\u1ed9i b\u1ed9 tin c\u1eady, kh\u00f4ng expose ra Internet.)\" \"WARN\"\n    } catch {\n        Write-Log \"L\u1ed7i khi c\u1ea5u h\u00ecnh Guest/Null-session: $($_.Exception.Message)\" \"WARN\"\n    }\n}\n\n\n# ---- src/Enable-NetworkDiscoveryAndSharing.ps1 ----\nfunction Enable-NetworkDiscoveryAndSharing {\n    &lt;#\n    .SYNOPSIS\n        B\u1eadt Network Discovery + File and Printer Sharing tr\u00ean firewall,\n        v\u00e0 chuy\u1ec3n network profile hi\u1ec7n t\u1ea1i t\u1eeb Public sang Private n\u1ebfu c\u1ea7n.\n    #&gt;\n    Write-Log \"\u0110ang b\u1eadt Network Discovery + File and Printer Sharing...\"\n    try {\n        Set-NetFirewallRule -DisplayGroup \"Network Discovery\" -Enabled True -ErrorAction SilentlyContinue\n        Set-NetFirewallRule -DisplayGroup \"File and Printer Sharing\" -Enabled True -ErrorAction SilentlyContinue\n\n        Get-NetConnectionProfile | ForEach-Object {\n            if ($_.NetworkCategory -eq 'Public') {\n                try {\n                    Set-NetConnectionProfile -InterfaceIndex $_.InterfaceIndex -NetworkCategory Private -ErrorAction SilentlyContinue\n                    Write-Log \"  + \u0110\u00e3 chuy\u1ec3n network '$($_.Name)' t\u1eeb Public sang Private.\" \"OK\"\n                } catch {\n                    Write-Log \"  + Kh\u00f4ng \u0111\u1ed5i \u0111\u01b0\u1ee3c profile m\u1ea1ng '$($_.Name)' (c\u00f3 th\u1ec3 do domain policy).\" \"WARN\"\n                }\n            }\n        }\n        Write-Log \"Network Discovery / File and Printer Sharing \u0111\u00e3 b\u1eadt.\" \"OK\"\n    } catch {\n        Write-Log \"L\u1ed7i khi b\u1eadt Network Discovery: $($_.Exception.Message)\" \"WARN\"\n    }\n}\n\n\n# ---- src/Enable-RequiredServices.ps1 ----\nfunction Enable-RequiredServices {\n    &lt;#\n    .SYNOPSIS\n        B\u1eadt (StartupType + Start-Service) c\u00e1c d\u1ecbch v\u1ee5 Windows c\u1ea7n thi\u1ebft cho\n        chia s\u1ebb file/m\u00e1y in v\u00e0 kh\u00e1m ph\u00e1 m\u1ea1ng (Network Discovery) trong LAN.\n    #&gt;\n    Write-Log \"\u0110ang b\u1eadt c\u00e1c d\u1ecbch v\u1ee5 c\u1ea7n thi\u1ebft cho chia s\u1ebb m\u00e1y in/m\u1ea1ng LAN...\"\n    $services = @(\n        @{Name='Spooler';           Note='Print Spooler'},\n        @{Name='FDResPub';          Note='Function Discovery Resource Publication'},\n        @{Name='fdPHost';           Note='Function Discovery Provider Host'},\n        @{Name='LanmanServer';      Note='Server (chia s\u1ebb file/m\u00e1y in)'},\n        @{Name='LanmanWorkstation'; Note='Workstation (SMB client)'},\n        @{Name='RpcSs';             Note='Remote Procedure Call (RPC)'},\n        @{Name='RpcEptMapper';      Note='RPC Endpoint Mapper'},\n        @{Name='DcomLaunch';        Note='DCOM Server Process Launcher'},\n        @{Name='SSDPSRV';           Note='SSDP Discovery'},\n        @{Name='upnphost';          Note='UPnP Device Host'},\n        @{Name='Dnscache';          Note='DNS Client'},\n        @{Name='LmHosts';           Note='TCP/IP NetBIOS Helper'}\n    )\n    foreach ($svc in $services) {\n        try {\n            $s = Get-Service -Name $svc.Name -ErrorAction SilentlyContinue\n            if ($s) {\n                if ($s.StartType -eq 'Disabled') { Set-Service -Name $svc.Name -StartupType Manual }\n                if ($s.Status -ne 'Running') { Start-Service -Name $svc.Name -ErrorAction SilentlyContinue }\n                Write-Log (\"  + {0} ({1}) OK\" -f $svc.Name, $svc.Note) \"OK\"\n            }\n        } catch {\n            Write-Log (\"  + Kh\u00f4ng b\u1eadt \u0111\u01b0\u1ee3c {0}: {1}\" -f $svc.Name, $_.Exception.Message) \"WARN\"\n        }\n    }\n}\n\n\n# ---- src/Enable-SMB1CifsSharing.ps1 ----\nfunction Enable-SMB1CifsSharing {\n    &lt;#\n    .SYNOPSIS\n        B\u1eadt chia s\u1ebb m\u00e1y in/file qua giao th\u1ee9c SMB1/CIFS (d\u00f9ng cho thi\u1ebft b\u1ecb \u0111\u1eddi c\u0169:\n        Windows XP/Server 2003, NAS/m\u00e1y in c\u0169 ch\u1ec9 h\u1ed7 tr\u1ee3 SMB1).\n    #&gt;\n    Write-Log \"=== B\u1eaeT \u0110\u1ea6U C\u1ea4U H\u00ccNH CHIA S\u1eba QUA SMB1/CIFS (GIAO TH\u1ee8C C\u0168) ===\" \"WARN\"\n\n    try {\n        $feature = Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -ErrorAction SilentlyContinue\n        if ($feature -and $feature.State -ne 'Enabled') {\n            Write-Log \"\u0110ang b\u1eadt Windows Feature: SMB1Protocol (y\u00eau c\u1ea7u c\u00f3 th\u1ec3 kh\u1edfi \u0111\u1ed9ng l\u1ea1i m\u00e1y)...\"\n            Enable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -All -NoRestart -ErrorAction Stop | Out-Null\n            Write-Log \"\u0110\u00e3 b\u1eadt SMB1Protocol. C\u00f3 th\u1ec3 c\u1ea7n RESTART m\u00e1y \u0111\u1ec3 c\u00f3 hi\u1ec7u l\u1ef1c ho\u00e0n to\u00e0n.\" \"OK\"\n        } else {\n            Write-Log \"SMB1Protocol \u0111\u00e3 \u0111\u01b0\u1ee3c b\u1eadt s\u1eb5n.\" \"OK\"\n        }\n    } catch {\n        Write-Log \"Kh\u00f4ng b\u1eadt \u0111\u01b0\u1ee3c SMB1Protocol qua DISM: $($_.Exception.Message)\" \"WARN\"\n        Write-Log \"Th\u1eed b\u1eadt b\u1eb1ng Set-SmbServerConfiguration...\"\n    }\n\n    try {\n        Set-SmbServerConfiguration -EnableSMB1Protocol $true -Force -ErrorAction SilentlyContinue\n        Set-ItemProperty -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\Services\\LanmanWorkstation\" -Name \"DependOnService\" -Value @(\"Bowser\",\"MRxSmb20\",\"MRxSmb10\",\"NSI\") -Type MultiString -ErrorAction SilentlyContinue\n        Write-Log \"\u0110\u00e3 b\u1eadt SMB1 ph\u00eda Server (Set-SmbServerConfiguration).\" \"OK\"\n    } catch {\n        Write-Log \"Kh\u00f4ng set \u0111\u01b0\u1ee3c SMB1 qua Set-SmbServerConfiguration: $($_.Exception.Message)\" \"WARN\"\n    }\n\n    try {\n        $gpoPath = \"HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\LanmanWorkstation\"\n        if (-not (Test-Path $gpoPath)) { New-Item -Path $gpoPath -Force | Out-Null }\n        Set-ItemProperty -Path $gpoPath -Name \"AllowInsecureGuestAuth\" -Value 1 -Type DWord -Force\n\n        $lanmanWkParamPath = \"HKLM:\\SYSTEM\\CurrentControlSet\\Services\\LanmanWorkstation\\Parameters\"\n        if (-not (Test-Path $lanmanWkParamPath)) { New-Item -Path $lanmanWkParamPath -Force | Out-Null }\n        Set-ItemProperty -Path $lanmanWkParamPath -Name \"AllowInsecureGuestAuth\" -Value 1 -Type DWord -Force\n\n        Write-Log \"\u0110\u00e3 b\u1eadt AllowInsecureGuestAuth=1 (c\u1ea3 GPO path v\u00e0 Parameters path) \u2014 cho ph\u00e9p guest logon qua SMB1.\" \"OK\"\n    } catch {\n        Write-Log \"Kh\u00f4ng set \u0111\u01b0\u1ee3c AllowInsecureGuestAuth: $($_.Exception.Message)\" \"WARN\"\n    }\n\n    try {\n        $lsaPath = \"HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa\"\n        Set-ItemProperty -Path $lsaPath -Name \"LmCompatibilityLevel\" -Value 1 -Type DWord -Force\n        Write-Log \"\u0110\u00e3 h\u1ea1 LmCompatibilityLevel=1 \u0111\u1ec3 t\u01b0\u01a1ng th\u00edch m\u00e1y/NAS \u0111\u1eddi c\u0169.\" \"OK\"\n    } catch {\n        Write-Log \"Kh\u00f4ng set \u0111\u01b0\u1ee3c LmCompatibilityLevel: $($_.Exception.Message)\" \"WARN\"\n    }\n\n    Write-Log \"=== HO\u00c0N T\u1ea4T C\u1ea4U H\u00ccNH SMB1/CIFS. Khuy\u1ebfn ngh\u1ecb RESTART m\u00e1y \u0111\u1ec3 \u00e1p d\u1ee5ng \u0111\u1ea7y \u0111\u1ee7. ===\" \"WARN\"\n}\n\n\n# ---- src/Enable-SMB2Sharing.ps1 ----\nfunction Enable-SMB2Sharing {\n    &lt;#\n    .SYNOPSIS\n        B\u1eadt chia s\u1ebb m\u00e1y in/file qua giao th\u1ee9c SMB2/SMB3 (khuy\u1ebfn ngh\u1ecb cho m\u1ea1ng LAN\n        hi\u1ec7n \u0111\u1ea1i, Windows 7 SP1 tr\u1edf l\u00ean), \u0111\u1ed3ng th\u1eddi t\u1eaft SMB1 \u0111\u1ec3 t\u0103ng b\u1ea3o m\u1eadt.\n    #&gt;\n    Write-Log \"=== B\u1eaeT \u0110\u1ea6U C\u1ea4U H\u00ccNH CHIA S\u1eba QUA SMB2/SMB3 (GIAO TH\u1ee8C M\u1edaI, KHUY\u1ebeN NGH\u1eca) ===\" \"OK\"\n\n    try {\n        Set-SmbServerConfiguration -EnableSMB2Protocol $true -Force -ErrorAction SilentlyContinue\n        Write-Log \"\u0110\u00e3 b\u1eadt SMB2/SMB3 ph\u00eda Server.\" \"OK\"\n    } catch {\n        Write-Log \"Kh\u00f4ng set \u0111\u01b0\u1ee3c EnableSMB2Protocol: $($_.Exception.Message)\" \"WARN\"\n    }\n\n    try {\n        $gpoPath = \"HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\LanmanWorkstation\"\n        if (-not (Test-Path $gpoPath)) { New-Item -Path $gpoPath -Force | Out-Null }\n        Set-ItemProperty -Path $gpoPath -Name \"AllowInsecureGuestAuth\" -Value 1 -Type DWord -Force\n        Write-Log \"\u0110\u00e3 b\u1eadt AllowInsecureGuestAuth=1 cho SMB2 (h\u1ed7 tr\u1ee3 workgroup kh\u00f4ng d\u00f9ng t\u00e0i kho\u1ea3n).\" \"OK\"\n    } catch {\n        Write-Log \"Kh\u00f4ng set \u0111\u01b0\u1ee3c AllowInsecureGuestAuth cho SMB2: $($_.Exception.Message)\" \"WARN\"\n    }\n\n    try {\n        $feature = Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -ErrorAction SilentlyContinue\n        if ($feature -and $feature.State -eq 'Enabled') {\n            Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart -ErrorAction SilentlyContinue | Out-Null\n            Write-Log \"\u0110\u00e3 t\u1eaft SMB1Protocol (b\u1ea3o m\u1eadt h\u01a1n khi \u0111\u00e3 d\u00f9ng SMB2).\" \"OK\"\n        }\n        Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force -ErrorAction SilentlyContinue\n    } catch {\n        Write-Log \"Kh\u00f4ng t\u1eaft \u0111\u01b0\u1ee3c SMB1 (b\u1ecf qua, kh\u00f4ng \u1ea3nh h\u01b0\u1edfng SMB2): $($_.Exception.Message)\" \"WARN\"\n    }\n\n    try {\n        Set-SmbServerConfiguration -RequireSecuritySignature $false -Force -ErrorAction SilentlyContinue\n        Write-Log \"\u0110\u00e3 \u0111\u1eb7t RequireSecuritySignature=false \u0111\u1ec3 tr\u00e1nh l\u1ed7i k\u1ebft n\u1ed1i trong m\u1ea1ng LAN n\u1ed9i b\u1ed9.\" \"OK\"\n    } catch {\n        Write-Log \"Kh\u00f4ng set \u0111\u01b0\u1ee3c RequireSecuritySignature: $($_.Exception.Message)\" \"WARN\"\n    }\n\n    Write-Log \"=== HO\u00c0N T\u1ea4T C\u1ea4U H\u00ccNH SMB2/SMB3. ===\" \"OK\"\n}\n\n\n# ---- src/Fix-Error0x0000011b.ps1 ----\nfunction Fix-Error0x0000011b {\n    &lt;#\n    .SYNOPSIS\n        V\u00e1 l\u1ed7i 0x0000011b \"Operation could not be completed\" ph\u00e1t sinh sau b\u1ea3n v\u00e1\n        b\u1ea3o m\u1eadt Point and Print / RPC hardening c\u1ee7a Microsoft (CVE-2021-34481 v\u00e0 li\u00ean quan).\n    #&gt;\n    Write-Log \"\u0110ang v\u00e1 l\u1ed7i 0x0000011b (Point and Print / RPC hardening)...\"\n    $paths = @(\n        'HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\Printers',\n        'HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\Printers\\RPC',\n        'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Print'\n    )\n    foreach ($p in $paths) {\n        if (-not (Test-Path $p)) { New-Item -Path $p -Force | Out-Null }\n    }\n    try {\n        # Set \u1edf c\u1ea3 3 v\u1ecb tr\u00ed registry: v\u1ecb tr\u00ed Policy (\u00e1p d\u1ee5ng khi c\u00f3 domain GPO)\n        # v\u00e0 v\u1ecb tr\u00ed Control\\Print (\u00e1p d\u1ee5ng m\u00e1y standalone/workgroup).\n        Set-ItemProperty -Path 'HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\Printers' -Name 'RpcAuthnLevelPrivacyEnabled' -Value 0 -Type DWord -Force\n        Set-ItemProperty -Path 'HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\Printers\\RPC' -Name 'RpcAuthnLevelPrivacyEnabled' -Value 0 -Type DWord -Force\n        Set-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Print' -Name 'RpcAuthnLevelPrivacyEnabled' -Value 0 -Type DWord -Force\n\n        $ppPath = 'HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint'\n        if (-not (Test-Path $ppPath)) { New-Item -Path $ppPath -Force | Out-Null }\n        Set-ItemProperty -Path $ppPath -Name 'RestrictDriverInstallationToAdministrators' -Value 0 -Type DWord -Force\n        Set-ItemProperty -Path $ppPath -Name 'NoWarningNoElevationOnInstall' -Value 1 -Type DWord -Force\n        Set-ItemProperty -Path $ppPath -Name 'UpdatePromptSettings' -Value 2 -Type DWord -Force\n\n        Write-Log \"\u0110\u00e3 set RpcAuthnLevelPrivacyEnabled=0 (c\u1ea3 3 v\u1ecb tr\u00ed registry) v\u00e0 n\u1edbi l\u1ecfng Point and Print policy.\" \"OK\"\n    } catch {\n        Write-Log \"L\u1ed7i khi v\u00e1 0x0000011b: $($_.Exception.Message)\" \"ERR\"\n    }\n}\n\n\n# ---- src/Fix-Error0x00000709.ps1 ----\nfunction Fix-Error0x00000709 {\n    &lt;#\n    .SYNOPSIS\n        V\u00e1 l\u1ed7i 0x00000709 \"Windows could not set the default printer\".\n    #&gt;\n    Write-Log \"\u0110ang v\u00e1 l\u1ed7i 0x00000709 (kh\u00f4ng set \u0111\u01b0\u1ee3c m\u00e1y in m\u1eb7c \u0111\u1ecbnh)...\"\n    try {\n        $wnKey = 'HKCU:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows'\n        if (Test-Path $wnKey) {\n            Set-ItemProperty -Path $wnKey -Name 'LegacyDefaultPrinterMode' -Value 1 -Type DWord -Force\n            Write-Log \"\u0110\u00e3 b\u1eadt LegacyDefaultPrinterMode=1 (d\u00f9ng c\u01a1 ch\u1ebf set default printer ki\u1ec3u c\u0169).\" \"OK\"\n        }\n        Restart-PrintSpoolerSafe\n    } catch {\n        Write-Log \"L\u1ed7i khi v\u00e1 0x00000709: $($_.Exception.Message)\" \"WARN\"\n    }\n}\n\n\n# ---- src/Fix-RpcNamedPipeAndExtendedErrors.ps1 ----\nfunction Fix-RpcNamedPipeAndExtendedErrors {\n    &lt;#\n    .SYNOPSIS\n        V\u00e1 l\u1ed7i 0x00000040 / 0x000006e4 \u2014 RPC qua Named Pipes b\u1ecb ch\u1eb7n,\n        th\u01b0\u1eddng g\u1eb7p tr\u00ean Windows 11 khi k\u1ebft n\u1ed1i m\u00e1y in m\u1ea1ng.\n    #&gt;\n    Write-Log \"\u0110ang v\u00e1 l\u1ed7i RPC Named Pipes (0x00000040 / 0x000006e4)...\"\n    try {\n        $rpcPath = 'HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\Printers\\RPC'\n        if (-not (Test-Path $rpcPath)) { New-Item -Path $rpcPath -Force | Out-Null }\n        Set-ItemProperty -Path $rpcPath -Name 'RpcUseNamedPipesAuth' -Value 1 -Type DWord -Force\n        Set-ItemProperty -Path $rpcPath -Name 'RpcProtocols' -Value 7 -Type DWord -Force\n        Set-ItemProperty -Path $rpcPath -Name 'RpcTcpPort' -Value 0 -Type DWord -Force\n        Write-Log \"\u0110\u00e3 b\u1eadt RpcUseNamedPipesAuth=1, RpcProtocols=7, RpcTcpPort=0.\" \"OK\"\n    } catch {\n        Write-Log \"L\u1ed7i khi v\u00e1 RPC Named Pipes: $($_.Exception.Message)\" \"WARN\"\n    }\n}\n\n\n# ---- src/Fix-RpcServerUnavailable.ps1 ----\nfunction Fix-RpcServerUnavailable {\n    &lt;#\n    .SYNOPSIS\n        M\u1edf firewall cho RPC (port 135 + d\u1ea3i dynamic port DCOM) \u0111\u1ec3 kh\u1eafc ph\u1ee5c\n        l\u1ed7i \"The RPC server is unavailable\" khi add/k\u1ebft n\u1ed1i m\u00e1y in qua m\u1ea1ng.\n    #&gt;\n    Write-Log \"\u0110ang v\u00e1 l\u1ed7i RPC server unavailable...\"\n    try {\n        netsh advfirewall firewall set rule group=\"Windows Management Instrumentation (WMI)\" new enable=yes | Out-Null\n        netsh advfirewall firewall set rule group=\"Remote Administration\" new enable=yes | Out-Null\n        New-NetFirewallRule -DisplayName \"RPC Endpoint Mapper (TCP-In) Custom\" -Direction Inbound -Protocol TCP -LocalPort 135 -Action Allow -ErrorAction SilentlyContinue | Out-Null\n        New-NetFirewallRule -DisplayName \"RPC Dynamic Ports (TCP-In) Custom\" -Direction Inbound -Protocol TCP -LocalPort 49152-65535 -Action Allow -ErrorAction SilentlyContinue | Out-Null\n        Write-Log \"\u0110\u00e3 m\u1edf port RPC 135 v\u00e0 d\u1ea3i dynamic port tr\u00ean firewall.\" \"OK\"\n    } catch {\n        Write-Log \"L\u1ed7i khi c\u1ea5u h\u00ecnh firewall RPC: $($_.Exception.Message)\" \"WARN\"\n    }\n}\n\n\n# ---- src/Get-LocalPrinters.ps1 ----\nfunction Get-LocalPrinters {\n    &lt;#\n    .SYNOPSIS\n        Tr\u1ea3 v\u1ec1 danh s\u00e1ch to\u00e0n b\u1ed9 m\u00e1y in local (Get-Printer), d\u00f9ng cho c\u1ea3 console l\u1eabn GUI.\n    #&gt;\n    return Get-Printer -ErrorAction SilentlyContinue\n}\n\n\n# ---- src/Invoke-FixCommonPrinterErrors.ps1 ----\nfunction Invoke-FixCommonPrinterErrors {\n    &lt;#\n    .SYNOPSIS\n        Ch\u1ea1y to\u00e0n b\u1ed9 c\u00e1c b\u01b0\u1edbc v\u00e1 l\u1ed7i d\u00f9ng chung (RPC, 0x0000011b, 0x00000709,\n        Named Pipes, Guest/Null-session) \u2014 kh\u00f4ng \u0111\u1ed5i c\u1ea5u h\u00ecnh SMB1/SMB2.\n        D\u00f9ng cho c\u1ea3 2 l\u1ef1a ch\u1ecdn giao th\u1ee9c v\u00e0 cho t\u00f9y ch\u1ecdn \"ch\u1ec9 v\u00e1 l\u1ed7i\".\n    #&gt;\n    Enable-RequiredServices\n    Fix-RpcServerUnavailable\n    Fix-Error0x0000011b\n    Fix-RpcNamedPipeAndExtendedErrors\n    Fix-Error0x00000709\n    Enable-GuestAndNullSessionAccess\n    Enable-NetworkDiscoveryAndSharing\n}\n\n\n# ---- src/Invoke-SetupSmb1Sharing.ps1 ----\nfunction Invoke-SetupSmb1Sharing {\n    &lt;#\n    .SYNOPSIS\n        Ch\u1ea1y to\u00e0n b\u1ed9 quy tr\u00ecnh: v\u00e1 l\u1ed7i d\u00f9ng chung + b\u1eadt chia s\u1ebb qua SMB1/CIFS (giao th\u1ee9c c\u0169).\n    #&gt;\n    Invoke-FixCommonPrinterErrors\n    Enable-SMB1CifsSharing\n    Write-Log \"&gt;&gt;&gt; N\u1ebfu v\u1eeba b\u1eadt SMB1 l\u1ea7n \u0111\u1ea7u, h\u00e3y RESTART m\u00e1y r\u1ed3i th\u1eed l\u1ea1i. &lt;&lt;&lt;\" \"WARN\"\n}\n\n\n# ---- src/Invoke-SetupSmb2Sharing.ps1 ----\nfunction Invoke-SetupSmb2Sharing {\n    &lt;#\n    .SYNOPSIS\n        Ch\u1ea1y to\u00e0n b\u1ed9 quy tr\u00ecnh: v\u00e1 l\u1ed7i d\u00f9ng chung + b\u1eadt chia s\u1ebb qua SMB2/SMB3 (giao th\u1ee9c m\u1edbi).\n    #&gt;\n    Invoke-FixCommonPrinterErrors\n    Enable-SMB2Sharing\n}\n\n\n# ---- src/Remove-OfflinePrinterCopies.ps1 ----\nfunction Remove-OfflinePrinterCopies {\n    &lt;#\n    .SYNOPSIS\n        Xo\u00e1 c\u00e1c m\u00e1y in c\u00f3 h\u1eadu t\u1ed1 \"Copy\"/\"B\u1ea3n sao\" (th\u01b0\u1eddng do Windows t\u1ef1 t\u1ea1o khi c\u00e0i driver\n        l\u1ed7i/tr\u00f9ng) m\u00e0 \u0111ang \u1edf tr\u1ea1ng th\u00e1i offline. Kh\u00f4ng \u0111\u1ee5ng t\u1edbi c\u00e1c m\u00e1y in Copy \u0111ang online.\n    #&gt;\n    Write-Log \"\u0110ang d\u00f2 c\u00e1c m\u00e1y in Copy/B\u1ea3n sao \u0111ang offline...\"\n    try {\n        $regexCopy = '(\\(?Copy\\s*\\d+\\)?|\\(?B\u1ea3n sao\\s*\\d+\\)?|copy\\d+)$'\n        $dsMayIn = Get-Printer -ErrorAction SilentlyContinue | Where-Object { $_.Name -match $regexCopy }\n\n        if (-not $dsMayIn) {\n            Write-Log \"Kh\u00f4ng t\u00ecm th\u1ea5y m\u00e1y in n\u00e0o c\u00f3 h\u1eadu t\u1ed1 Copy/B\u1ea3n sao.\" \"WARN\"\n            return\n        }\n\n        foreach ($mayIn in $dsMayIn) {\n            if ($mayIn.WorkOffline -eq $true -or $mayIn.PrinterStatus -eq 'Offline') {\n                try {\n                    Remove-Printer -Name $mayIn.Name -ErrorAction Stop\n                    Write-Log \"\u0110\u00e3 xo\u00e1 m\u00e1y in offline: $($mayIn.Name)\" \"OK\"\n                } catch {\n                    Write-Log \"Kh\u00f4ng xo\u00e1 \u0111\u01b0\u1ee3c m\u00e1y in '$($mayIn.Name)': $($_.Exception.Message)\" \"WARN\"\n                }\n            }\n        }\n        Write-Log \"Ho\u00e0n t\u1ea5t x\u1eed l\u00fd m\u00e1y in Copy/B\u1ea3n sao offline.\" \"OK\"\n    } catch {\n        Write-Log \"Remove-OfflinePrinterCopies: $($_.Exception.Message)\" \"ERR\"\n    }\n}\n\n\n# ---- src/Restart-PrintSpoolerSafe.ps1 ----\nfunction Restart-PrintSpoolerSafe {\n    &lt;#\n    .SYNOPSIS\n        D\u1eebng Spooler, xo\u00e1 job in b\u1ecb k\u1eb9t trong h\u00e0ng \u0111\u1ee3i, r\u1ed3i kh\u1edfi \u0111\u1ed9ng l\u1ea1i Spooler.\n    #&gt;\n    Write-Log \"\u0110ang kh\u1edfi \u0111\u1ed9ng l\u1ea1i d\u1ecbch v\u1ee5 Print Spooler...\"\n    try {\n        Stop-Service -Name Spooler -Force -ErrorAction SilentlyContinue\n        Start-Sleep -Seconds 2\n        $spoolPath = \"$env:SystemRoot\\System32\\spool\\PRINTERS\"\n        if (Test-Path $spoolPath) {\n            Get-ChildItem $spoolPath -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue\n        }\n        Set-Service -Name Spooler -StartupType Automatic\n        Start-Service -Name Spooler\n        Write-Log \"Print Spooler \u0111\u00e3 ch\u1ea1y l\u1ea1i th\u00e0nh c\u00f4ng.\" \"OK\"\n    } catch {\n        Write-Log \"Kh\u00f4ng th\u1ec3 kh\u1edfi \u0111\u1ed9ng l\u1ea1i Spooler: $($_.Exception.Message)\" \"ERR\"\n    }\n}\n\n\n# ---- src/Set-PrinterSharedByName.ps1 ----\nfunction Set-PrinterSharedByName {\n    &lt;#\n    .SYNOPSIS\n        B\u1eadt chia s\u1ebb (Shared=$true) cho 1 m\u00e1y in theo t\u00ean, t\u1ef1 sinh ShareName h\u1ee3p l\u1ec7.\n    .PARAMETER PrinterName\n        T\u00ean m\u00e1y in (Name trong Get-Printer) c\u1ea7n chia s\u1ebb.\n    #&gt;\n    param([Parameter(Mandatory)][string]$PrinterName)\n    try {\n        $shareName = ($PrinterName -replace '[\\\\\\/:\\*\\?\"&lt;&gt;\\|]', '_')\n        Set-Printer -Name $PrinterName -Shared $true -ShareName $shareName -ErrorAction Stop\n        Write-Log \"\u0110\u00e3 chia s\u1ebb m\u00e1y in '$PrinterName' v\u1edbi t\u00ean share '$shareName'.\" \"OK\"\n        return $true\n    } catch {\n        Write-Log \"Kh\u00f4ng chia s\u1ebb \u0111\u01b0\u1ee3c m\u00e1y in '$PrinterName': $($_.Exception.Message)\" \"ERR\"\n        return $false\n    }\n}\n\n\n# ---- src/Set-SharePermissionsEveryoneReadWrite.ps1 ----\nfunction Set-SharePermissionsEveryoneReadWrite {\n    &lt;#\n    .SYNOPSIS\n        C\u1ea5p quy\u1ec1n Full cho 'Everyone' tr\u00ean 1 share (d\u00f9ng cho m\u1ea1ng LAN n\u1ed9i b\u1ed9 tin c\u1eady).\n    .PARAMETER ShareName\n        T\u00ean share c\u1ea7n c\u1ea5p quy\u1ec1n.\n    #&gt;\n    param([string]$ShareName)\n    try {\n        Grant-SmbShareAccess -Name $ShareName -AccountName \"Everyone\" -AccessRight Full -Force -ErrorAction SilentlyContinue | Out-Null\n        Write-Log \"\u0110\u00e3 c\u1ea5p quy\u1ec1n Full cho 'Everyone' tr\u00ean share '$ShareName' (khuy\u1ebfn ngh\u1ecb si\u1ebft l\u1ea1i quy\u1ec1n NTFS n\u1ebfu c\u1ea7n b\u1ea3o m\u1eadt h\u01a1n).\" \"OK\"\n    } catch {\n        Write-Log \"Kh\u00f4ng set \u0111\u01b0\u1ee3c quy\u1ec1n share '$ShareName': $($_.Exception.Message)\" \"WARN\"\n    }\n}\n\n\n# ---- src/Show-ConsolePrinterShareMenu.ps1 ----\nfunction Show-ConsolePrinterShareMenu {\n    &lt;#\n    .SYNOPSIS\n        Li\u1ec7t k\u00ea m\u00e1y in local ch\u01b0a chia s\u1ebb ra console, cho ng\u01b0\u1eddi d\u00f9ng ch\u1ecdn r\u1ed3i g\u1ecdi\n        Set-PrinterSharedByName. D\u00f9ng cho ch\u1ebf \u0111\u1ed9 console (kh\u00f4ng GUI).\n    #&gt;\n    Write-Log \"\u0110ang li\u1ec7t k\u00ea m\u00e1y in local \u0111\u1ec3 chia s\u1ebb...\"\n    $printers = Get-LocalPrinters | Where-Object { -not $_.Shared -and $_.Type -eq 'Local' }\n    if (-not $printers) {\n        Write-Log \"Kh\u00f4ng t\u00ecm th\u1ea5y m\u00e1y in local n\u00e0o ch\u01b0a \u0111\u01b0\u1ee3c chia s\u1ebb (ho\u1eb7c t\u1ea5t c\u1ea3 \u0111\u00e3 share s\u1eb5n).\" \"WARN\"\n        $all = Get-LocalPrinters\n        if ($all) {\n            Write-Host \"`nDanh s\u00e1ch m\u00e1y in hi\u1ec7n c\u00f3:\" -ForegroundColor Cyan\n            $all | Format-Table Name, Shared, ShareName, Type -AutoSize\n        }\n        return\n    }\n\n    Write-Host \"`nC\u00e1c m\u00e1y in local ch\u01b0a chia s\u1ebb:\" -ForegroundColor Cyan\n    for ($i = 0; $i -lt $printers.Count; $i++) {\n        Write-Host \"  [$i] $($printers[$i].Name)\"\n    }\n    $sel = Read-Host \"`nNh\u1eadp s\u1ed1 th\u1ee9 t\u1ef1 m\u00e1y in mu\u1ed1n chia s\u1ebb (Enter \u0111\u1ec3 chia s\u1ebb T\u1ea4T C\u1ea2)\"\n\n    $targets = if ([string]::IsNullOrWhiteSpace($sel)) { $printers } else { @($printers[[int]$sel]) }\n\n    foreach ($pr in $targets) {\n        Set-PrinterSharedByName -PrinterName $pr.Name\n    }\n}\n\n\n# ---- Gui/WpfShell.ps1 ----\n# ====================================================================\n# GIAO DI\u1ec6N WPF (shell ch\u00ednh) \u2014 theo m\u1eabu WpfShell.ps1, b\u1ecdc c\u00e1c h\u00e0m module\n# FixSharePrinter (\u0111\u00e3 Import-Module tr\u01b0\u1edbc khi g\u1ecdi Show-WpfShell). Kh\u00f4ng \u0111\u1ed5i\n# logic x\u1eed l\u00fd trong module \u2014 file n\u00e0y ch\u1ec9 v\u1ebd giao di\u1ec7n v\u00e0 g\u1ecdi h\u00e0m module.\n# ====================================================================\nAdd-Type -AssemblyName PresentationFramework\n\n$Script:WpfWindow     = $null\n$Script:WpfLogBox     = $null\n$Script:WpfStatus     = $null\n$Script:WpfBusyPanel  = $null\n$Script:WpfBusyDesc   = $null\n$Script:WpfBusy       = $false\n$Script:WpfLogNoNl    = $false\n$Script:WpfPages      = @{}\n$Script:WpfNavButtons = @{}\n\nfunction Get-WpfLogBrush {\n    param($Color)\n    $hex = switch (\"$Color\") {\n        'Green'     { '#34D399' }\n        'Red'       { '#F87171' }\n        'Yellow'    { '#FBBF24' }\n        'DarkYellow'{ '#F59E0B' }\n        'Cyan'      { '#22D3EE' }\n        'DarkCyan'  { '#06B6D4' }\n        'Blue'      { '#60A5FA' }\n        'Magenta'   { '#E879F9' }\n        'DarkGray'  { '#94A3B8' }\n        'Gray'      { '#94A3B8' }\n        'White'     { '#E5E7EB' }\n        default     { '#CBD5E1' }\n    }\n    return [Windows.Media.BrushConverter]::new().ConvertFromString($hex)\n}\n\nfunction Set-ConsoleWindowVisibility {\n    &lt;#\n    .SYNOPSIS\n        \u1ea8n/hi\u1ec7n c\u1eeda s\u1ed5 console (n\u1ebfu ti\u1ebfn tr\u00ecnh \u0111\u01b0\u1ee3c ch\u1ea1y t\u1eeb powershell.exe -File n\u00ean\n        c\u00f3 1 c\u1eeda s\u1ed5 console ri\u00eang). D\u00f9ng \u0111\u1ec3 \u1ea9n h\u1eb3n console khi m\u1edf GUI, ch\u1ec9 \u0111\u1ec3 l\u1ea1i\n        1 c\u1eeda s\u1ed5 WPF duy nh\u1ea5t; to\u00e0n b\u1ed9 output console l\u00fac \u0111\u00f3 \u0111\u00e3 \u0111\u01b0\u1ee3c Write-Log \u0111\u01b0a\n        v\u00e0o khung nh\u1eadt k\u00fd c\u1ee7a GUI thay v\u00ec in ra console.\n    #&gt;\n    param([Parameter(Mandatory)][bool]$Visible)\n    try {\n        if (-not ('FixSharePrinter.NativeMethods' -as [type])) {\n            Add-Type -Namespace FixSharePrinter -Name NativeMethods -MemberDefinition @'\n[System.Runtime.InteropServices.DllImport(\"kernel32.dll\")]\npublic static extern System.IntPtr GetConsoleWindow();\n[System.Runtime.InteropServices.DllImport(\"user32.dll\")]\npublic static extern bool ShowWindow(System.IntPtr hWnd, int nCmdShow);\n'@ -ErrorAction Stop\n        }\n        $handle = [FixSharePrinter.NativeMethods]::GetConsoleWindow()\n        if ($handle -eq [System.IntPtr]::Zero) { return $false }\n        [void][FixSharePrinter.NativeMethods]::ShowWindow($handle, $(if ($Visible) { 5 } else { 0 }))\n        return $true\n    } catch {\n        return $false\n    }\n}\n\nfunction Pump-WpfDispatcher {\n    if (-not $Script:WpfWindow) { return }\n    try {\n        $Script:WpfWindow.Dispatcher.Invoke([Action]{}, 'Background')\n    } catch { }\n}\n\nfunction ConvertTo-WpfLogText {\n    param([string]$Text)\n    if ($null -eq $Text) { return '' }\n    $s = [string]$Text\n    $esc = [char]27\n    $s = [regex]::Replace($s, \"$esc\\[[0-9;]*m\", '')\n    return $s\n}\n\nfunction Add-WpfLogLine {\n    param(\n        [string]$Text,\n        $Color = 'Gray',\n        [switch]$NoNewline\n    )\n    if (-not $Script:WpfLogBox) { return }\n    try {\n        $box = $Script:WpfLogBox\n        $raw = ConvertTo-WpfLogText $Text\n        $isProgress = $raw.IndexOf([char]13) -ge 0\n        $raw = $raw -replace \"`r`n\", \"`n\" -replace \"`r\", ''\n        $brush = Get-WpfLogBrush $Color\n\n        $apply = {\n            param($tb, $chunk, $br, $mode)\n            $run = New-Object Windows.Documents.Run $chunk\n            $run.Foreground = $br\n            $para = $null\n            if ($tb.Document.Blocks.Count -gt 0) {\n                $para = $tb.Document.Blocks.LastBlock\n            }\n            if (-not $para -or $para -isnot [Windows.Documents.Paragraph]) {\n                $para = New-Object Windows.Documents.Paragraph\n                $para.Margin = New-Object Windows.Thickness 0\n                [void]$tb.Document.Blocks.Add($para)\n            }\n\n            if ($mode -eq 'replace') {\n                $para.Inlines.Clear()\n                [void]$para.Inlines.Add($run)\n            } elseif ($mode -eq 'close') {\n                $p2 = New-Object Windows.Documents.Paragraph\n                $p2.Margin = New-Object Windows.Thickness 0\n                [void]$tb.Document.Blocks.Add($p2)\n            } else {\n                [void]$para.Inlines.Add($run)\n                if ($mode -eq 'append') {\n                    $p3 = New-Object Windows.Documents.Paragraph\n                    $p3.Margin = New-Object Windows.Thickness 0\n                    [void]$tb.Document.Blocks.Add($p3)\n                }\n            }\n\n            $tb.ScrollToEnd()\n            while ($tb.Document.Blocks.Count -gt 800) {\n                $tb.Document.Blocks.Remove($tb.Document.Blocks.FirstBlock)\n            }\n        }\n\n        if ([string]::IsNullOrEmpty($raw)) {\n            if ($NoNewline) { return }\n            $mode = if ($Script:WpfLogNoNl) { 'close' } else { 'append' }\n            $chunk = ''\n        } elseif ($isProgress) {\n            $mode = 'replace'\n            $chunk = if ($raw.Contains(\"`n\")) { ($raw -split \"`n\" | Select-Object -Last 1) } else { $raw }\n        } elseif ($NoNewline) {\n            $mode = 'partial'\n            $chunk = $raw\n        } else {\n            $mode = 'append'\n            $chunk = $raw\n        }\n\n        if ($Script:WpfWindow.Dispatcher.CheckAccess()) {\n            &amp; $apply $box $chunk $brush $mode\n        } else {\n            $Script:WpfWindow.Dispatcher.Invoke($apply, $box, $chunk, $brush, $mode)\n        }\n        $Script:WpfLogNoNl = ($mode -eq 'partial')\n        Pump-WpfDispatcher\n    } catch { }\n}\n\nfunction Set-WpfBusy {\n    param(\n        [bool]$Busy,\n        [string]$Status = '',\n        [string]$Description = '',\n        [string]$DescriptionColor = '#94A3B8'\n    )\n    $Script:WpfBusy = $Busy\n    if ($Script:WpfBusyPanel) {\n        $Script:WpfBusyPanel.Visibility = if ($Busy) {\n            [Windows.Visibility]::Visible\n        } else {\n            [Windows.Visibility]::Collapsed\n        }\n        $Script:WpfBusyPanel.IsHitTestVisible = $Busy\n    }\n    if ($Script:WpfBusyDesc) {\n        if ($Busy -and $Description) {\n            $Script:WpfBusyDesc.Text = $Description\n            $Script:WpfBusyDesc.Foreground = [Windows.Media.BrushConverter]::new().ConvertFromString($DescriptionColor)\n            $Script:WpfBusyDesc.Visibility = [Windows.Visibility]::Visible\n        } else {\n            $Script:WpfBusyDesc.Text = ''\n            $Script:WpfBusyDesc.Visibility = [Windows.Visibility]::Collapsed\n        }\n    }\n    if ($Script:WpfWindow) { $Script:WpfWindow.IsEnabled = -not $Busy }\n    if ($Script:WpfStatus -and $Status) { $Script:WpfStatus.Text = $Status }\n    elseif ($Script:WpfStatus -and -not $Busy) { $Script:WpfStatus.Text = 'S\u1eb5n s\u00e0ng' }\n    Pump-WpfDispatcher\n}\n\nfunction Confirm-WpfAction {\n    param([string]$Title, [string]$Message)\n    $owner = $Script:WpfWindow\n    $r = if ($owner -and $owner.IsVisible) {\n        [System.Windows.MessageBox]::Show(\n            $owner, $Message, $Title,\n            [System.Windows.MessageBoxButton]::YesNo,\n            [System.Windows.MessageBoxImage]::Warning\n        )\n    } else {\n        [System.Windows.MessageBox]::Show(\n            $Message, $Title,\n            [System.Windows.MessageBoxButton]::YesNo,\n            [System.Windows.MessageBoxImage]::Warning\n        )\n    }\n    return ($r -eq [System.Windows.MessageBoxResult]::Yes)\n}\n\nfunction Show-WpfNotice {\n    param([Parameter(Mandatory)][string]$Message)\n    if ($Script:WpfWindow) {\n        [void][System.Windows.MessageBox]::Show($Script:WpfWindow, $Message, 'Fix Share Printer',\n            [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)\n    }\n}\n\nfunction Invoke-WpfAction {\n    param(\n        [Parameter(Mandatory)][string]$Title,\n        [Parameter(Mandatory)][scriptblock]$Action,\n        [switch]$Confirm,\n        [string]$ConfirmMessage = '',\n        [string]$Description = '',\n        [string]$DescriptionColor = '#94A3B8'\n    )\n    if ($Script:WpfBusy) { return }\n    if ($Confirm) {\n        $msg = if ($ConfirmMessage) { $ConfirmMessage } else { \"Ch\u1ea1y t\u00e1c v\u1ee5: $Title ?\" }\n        if (-not (Confirm-WpfAction -Title $Title -Message $msg)) { return }\n    }\n\n    Set-WpfBusy $true \"\u0110ang ch\u1ea1y: $Title\" -Description $Description -DescriptionColor $DescriptionColor\n    Add-WpfLogLine -Text \"\" -Color Gray\n    Add-WpfLogLine -Text \"=== $Title ===\" -Color Cyan\n    $sw = [System.Diagnostics.Stopwatch]::StartNew()\n    try {\n        &amp; $Action\n        $sw.Stop()\n        Add-WpfLogLine -Text (\"Ho\u00e0n t\u1ea5t: {0}  ({1:N1}s)\" -f $Title, $sw.Elapsed.TotalSeconds) -Color Green\n        if ($Script:WpfStatus) { $Script:WpfStatus.Text = \"Xong: $Title\" }\n    } catch {\n        $sw.Stop()\n        $message = $_.Exception.ToString()\n        Add-WpfLogLine -Text \"L\u1ed7i: $message\" -Color Red\n        Write-Log \"WPF action '$Title': $message\" -Level ERR\n        if ($Script:WpfStatus) { $Script:WpfStatus.Text = \"L\u1ed7i: $Title\" }\n    } finally {\n        Set-WpfBusy $false\n    }\n}\n\nfunction Show-WpfPage {\n    param([Parameter(Mandatory)][string]$Name)\n    foreach ($key in $Script:WpfPages.Keys) {\n        $Script:WpfPages[$key].Visibility = if ($key -eq $Name) {\n            [Windows.Visibility]::Visible\n        } else {\n            [Windows.Visibility]::Collapsed\n        }\n    }\n    foreach ($key in $Script:WpfNavButtons.Keys) {\n        $btn = $Script:WpfNavButtons[$key]\n        if ($key -eq $Name) {\n            $btn.Background = [Windows.Media.BrushConverter]::new().ConvertFromString('#123044')\n            $btn.BorderBrush = [Windows.Media.BrushConverter]::new().ConvertFromString('#22D3EE')\n        } else {\n            $btn.Background = [Windows.Media.Brushes]::Transparent\n            $btn.BorderBrush = [Windows.Media.Brushes]::Transparent\n        }\n    }\n}\n\nfunction Update-WpfPrintersList {\n    &lt;# N\u1ea1p l\u1ea1i danh s\u00e1ch m\u00e1y in v\u00e0o ListBox 'PrintersList' c\u1ee7a trang Qu\u1ea3n l\u00fd m\u00e1y in. #&gt;\n    $listBox = $Script:WpfWindow.FindName('PrintersList')\n    if (-not $listBox) { return }\n    $listBox.Items.Clear()\n    $printers = Get-LocalPrinters\n    if (-not $printers) {\n        Add-WpfLogLine -Text \"Kh\u00f4ng t\u00ecm th\u1ea5y m\u00e1y in n\u00e0o tr\u00ean m\u00e1y n\u00e0y.\" -Color Yellow\n        return\n    }\n    foreach ($pr in $printers) {\n        $cb = New-Object Windows.Controls.CheckBox\n        $label = \"$($pr.Name)\"\n        if ($pr.Shared) { $label += \"  [\u0111ang chia s\u1ebb: $($pr.ShareName)]\" }\n        $cb.Content = $label\n        $cb.Tag = $pr.Name\n        $cb.Foreground = [Windows.Media.BrushConverter]::new().ConvertFromString('#E2E8F0')\n        $cb.Margin = New-Object Windows.Thickness 4\n        [void]$listBox.Items.Add($cb)\n    }\n}\n\nfunction Get-WpfMainWindowXaml {\n    return @'\n\n  \n    \n    \n    \n      \n      \n      \n      \n      \n      \n      \n      \n      \n      \n        \n          \n            \n              \n            \n          \n        \n      \n    \n    \n      \n      \n      \n      \n      \n      \n      \n      \n      \n      \n        \n          \n            \n              \n            \n            \n              \n                \n                \n              \n            \n          \n        \n      \n    \n    \n      \n      \n      \n      \n      \n      \n        \n          \n            \n              \n            \n          \n        \n      \n    \n    \n      \n      \n      \n    \n  \n\n  \n    \n      \n      \n    \n    \n      \n      \n      \n    \n\n    \n      \n        \n          \n          \n            \n          \n        \n        \n      \n    \n\n    \n      \n        \n          \n        \n        \n          \n          \n          \n          \n          \n          \n        \n      \n    \n\n    \n      \n        \n        \n        \n      \n\n      \n      \n        \n          \n          \n        \n        \n          \n          \n        \n        \n          \n            \n              \n              \n            \n          \n          \n            \n              \n              \n            \n          \n          \n            \n              \n              \n            \n          \n        \n      \n\n      \n      \n        \n          \n          \n        \n        \n          \n          \n        \n        \n          \n            \n              \n              \n            \n          \n          \n            \n              \n              \n            \n          \n          \n            \n              \n              \n            \n          \n        \n      \n\n      \n      \n        \n          \n          \n        \n        \n          \n          \n        \n        \n          \n            \n              \n              \n            \n          \n          \n            \n              \n              \n            \n          \n          \n            \n              \n              \n            \n          \n          \n            \n              \n              \n            \n          \n        \n      \n\n      \n      \n        \n          \n          \n          \n          \n        \n        \n        \n          Ch\u1ecdn m\u00e1y in c\u1ea7n chia s\u1ebb r\u1ed3i b\u1ea5m \"Chia s\u1ebb \u0111\u00e3 ch\u1ecdn\". B\u1ea5m \"L\u00e0m m\u1edbi\" \u0111\u1ec3 t\u1ea3i l\u1ea1i danh s\u00e1ch.\n        \n        \n          \n        \n        \n          \n          \n        \n      \n\n      \n      \n        \n          \n          \n            Fix Share Printer \u2014 c\u00f4ng c\u1ee5 kh\u1eafc ph\u1ee5c l\u1ed7i chia s\u1ebb m\u00e1y in n\u1ed9i b\u1ed9 (RPC, 0x0000011b, 0x00000709...)\n            v\u00e0 b\u1eadt chia s\u1ebb qua SMB1/CIFS ho\u1eb7c SMB2/SMB3. Kh\u00f4ng c\u00f3 c\u00f4ng c\u1ee5 n\u00e0o \u0111\u1ea3m b\u1ea3o gi\u1ea3i quy\u1ebft 100% m\u1ecdi\n            t\u00ecnh hu\u1ed1ng trong m\u1ecdi m\u00f4i tr\u01b0\u1eddng (c\u00f2n ph\u1ee5 thu\u1ed9c driver m\u00e1y in, GPO domain, ph\u1ea7n c\u1ee9ng...).\n          \n          \n        \n      \n\n      \n\n      \n        \n          \n            \n            \n          \n          \n            \n              \n                \n              \n            \n          \n        \n      \n    \n\n    \n      \n        \n        \n      \n    \n\n    \n      \n        \n          \n            \n              \n            \n          \n          \n        \n        \n        \n      \n    \n  \n\n'@\n}\n\nfunction Show-WpfShell {\n    &lt;# Kh\u1edfi t\u1ea1o c\u1eeda s\u1ed5 WPF, wire c\u00e1c n\u00fat b\u1ea5m v\u00e0o h\u00e0m module, r\u1ed3i ShowDialog(). #&gt;\n    try {\n        Add-Type -AssemblyName PresentationFramework -ErrorAction Stop\n        Add-Type -AssemblyName PresentationCore -ErrorAction Stop\n        Add-Type -AssemblyName WindowsBase -ErrorAction Stop\n        Add-Type -AssemblyName System.Xaml -ErrorAction Stop\n    } catch {\n        Write-Warning \"Kh\u00f4ng n\u1ea1p \u0111\u01b0\u1ee3c WPF: $($_.Exception.Message)\"\n        return $false\n    }\n\n    $xamlText = Get-WpfMainWindowXaml\n    try {\n        $xml = New-Object System.Xml.XmlDocument\n        $xml.LoadXml($xamlText)\n        $reader = New-Object System.Xml.XmlNodeReader $xml\n        $window = [Windows.Markup.XamlReader]::Load($reader)\n    } catch {\n        Write-Warning \"L\u1ed7i XAML WPF: $($_.Exception.Message)\"\n        return $false\n    }\n\n    $Script:WpfWindow    = $window\n    $Script:WpfLogBox    = $window.FindName('LogBox')\n    $Script:WpfStatus    = $window.FindName('StatusText')\n    $Script:WpfBusyPanel = $window.FindName('BusyPanel')\n    $Script:WpfBusyDesc  = $window.FindName('BusyDesc')\n\n    $hdr = $window.FindName('HdrMeta')\n    if ($hdr) { $hdr.Text = \"PowerShell $($PSVersionTable.PSVersion)\" }\n\n    $logPath = $window.FindName('TxtLogPath')\n    if ($logPath) { $logPath.Text = \"Log: $Script:FSP_LogFile\" }\n    $infoLogPath = $window.FindName('TxtInfoLogPath')\n    if ($infoLogPath) { $infoLogPath.Text = \"File log phi\u00ean hi\u1ec7n t\u1ea1i: $Script:FSP_LogFile\" }\n\n    # \u0110\u0103ng k\u00fd c\u00e1c trang + n\u00fat \u0111i\u1ec1u h\u01b0\u1edbng\n    $Script:WpfPages = @{\n        Home     = $window.FindName('PageHome')\n        Share    = $window.FindName('PageShare')\n        FixPrint = $window.FindName('PageFixPrint')\n        Printers = $window.FindName('PagePrinters')\n        Info     = $window.FindName('PageInfo')\n    }\n    $Script:WpfNavButtons = @{\n        Home     = $window.FindName('NavHome')\n        Share    = $window.FindName('NavShare')\n        FixPrint = $window.FindName('NavFixPrint')\n        Printers = $window.FindName('NavPrinters')\n        Info     = $window.FindName('NavInfo')\n    }\n\n    # --- \u0110i\u1ec1u h\u01b0\u1edbng ---\n    $window.FindName('NavHome').Add_Click({ Show-WpfPage Home })\n    $window.FindName('NavShare').Add_Click({ Show-WpfPage Share })\n    $window.FindName('NavFixPrint').Add_Click({ Show-WpfPage FixPrint })\n    $window.FindName('NavPrinters').Add_Click({ Show-WpfPage Printers; Update-WpfPrintersList })\n    $window.FindName('NavInfo').Add_Click({ Show-WpfPage Info })\n\n    # --- Card \u1edf trang T\u1ed5ng quan: \u0111i\u1ec1u h\u01b0\u1edbng sang trang t\u01b0\u01a1ng \u1ee9ng ---\n    $window.FindName('CardShare').Add_Click({ Show-WpfPage Share })\n    $window.FindName('CardFixPrint').Add_Click({ Show-WpfPage FixPrint })\n    $window.FindName('CardSmb1').Add_Click({\n        Invoke-WpfAction -Title \"V\u00e1 l\u1ed7i + B\u1eadt SMB1/CIFS\" -Confirm `\n            -ConfirmMessage \"SMB1 c\u00f3 l\u1ed7 h\u1ed5ng b\u1ea3o m\u1eadt \u0111\u00e3 bi\u1ebft. Ch\u1ec9 b\u1eadt khi thi\u1ebft b\u1ecb b\u1eaft bu\u1ed9c d\u00f9ng SMB1. Ti\u1ebfp t\u1ee5c?\" `\n            -Description \"D\u00f9ng khi m\u00e1y in ho\u1eb7c thi\u1ebft b\u1ecb kh\u00e1c trong m\u1ea1ng LAN \u0111\u1eddi c\u0169 (Windows XP, Server 2003, NAS/\u0111\u1ea7u thu m\u1ea1ng c\u0169) ch\u1ec9 h\u1ed7 tr\u1ee3 SMB1 v\u00e0 kh\u00f4ng th\u1ec3 n\u00e2ng c\u1ea5p. S\u1ebd b\u1eadt SMB1Protocol, guest-logon, h\u1ea1 m\u1ee9c b\u1ea3o m\u1eadt LAN Manager, \u0111\u1ed3ng th\u1eddi v\u00e1 l\u1ed7i RPC/0x0000011b/0x00000709 tr\u01b0\u1edbc. SMB1 c\u00f3 l\u1ed7 h\u1ed5ng b\u1ea3o m\u1eadt \u0111\u00e3 bi\u1ebft \u2014 ch\u1ec9 d\u00f9ng khi b\u1eaft bu\u1ed9c.\" `\n            -DescriptionColor \"#FCA5A5\" `\n            -Action { Invoke-SetupSmb1Sharing }\n    })\n    $window.FindName('CardSmb2').Add_Click({\n        Invoke-WpfAction -Title \"V\u00e1 l\u1ed7i + B\u1eadt SMB2/SMB3\" `\n            -Description \"Khuy\u1ebfn ngh\u1ecb cho m\u1ea1ng LAN hi\u1ec7n \u0111\u1ea1i (Windows 7 SP1 tr\u1edf l\u00ean). S\u1ebd b\u1eadt SMB2/3, t\u1eaft SMB1 \u0111\u1ec3 an to\u00e0n h\u01a1n, n\u1edbi security signature \u0111\u1ec3 tr\u00e1nh l\u1ed7i k\u1ebft n\u1ed1i trong LAN n\u1ed9i b\u1ed9, \u0111\u1ed3ng th\u1eddi v\u00e1 l\u1ed7i RPC/0x0000011b/0x00000709 tr\u01b0\u1edbc.\" `\n            -DescriptionColor \"#6EE7B7\" `\n            -Action { Invoke-SetupSmb2Sharing }\n    })\n    $window.FindName('CardFix').Add_Click({\n        Invoke-WpfAction -Title \"V\u00e1 l\u1ed7i RPC/0x0000011b/0x00000709\" `\n            -Description \"V\u00e1 c\u00e1c l\u1ed7i RPC server unavailable, 0x0000011b (Point and Print / RPC hardening), 0x00000709 (kh\u00f4ng set \u0111\u01b0\u1ee3c default printer) v\u00e0 RPC Named Pipes (0x00000040 / 0x000006e4), kh\u00f4ng \u0111\u1ed5i c\u1ea5u h\u00ecnh SMB1/SMB2 hi\u1ec7n t\u1ea1i.\" `\n            -DescriptionColor \"#93C5FD\" `\n            -Action { Invoke-FixCommonPrinterErrors }\n    })\n    $window.FindName('CardPrinters').Add_Click({ Show-WpfPage Printers; Update-WpfPrintersList })\n\n    # --- Trang S\u1eeda l\u1ed7i in: 4 card ch\u1ea1y tr\u1ef1c ti\u1ebfp ---\n    $window.FindName('CardRemoveCopies').Add_Click({\n        Invoke-WpfAction -Title \"Xo\u00e1 m\u00e1y in Copy offline\" `\n            -Description \"Xo\u00e1 c\u00e1c m\u00e1y in c\u00f3 h\u1eadu t\u1ed1 'Copy'/'B\u1ea3n sao' (th\u01b0\u1eddng do Windows t\u1ef1 t\u1ea1o khi c\u00e0i driver l\u1ed7i/tr\u00f9ng) \u0111ang \u1edf tr\u1ea1ng th\u00e1i offline. Kh\u00f4ng \u0111\u1ee5ng t\u1edbi c\u00e1c m\u00e1y in Copy \u0111ang online.\" `\n            -DescriptionColor \"#FDBA74\" `\n            -Action { Remove-OfflinePrinterCopies }\n    })\n    $window.FindName('CardClearPorts').Add_Click({\n        Invoke-WpfAction -Title \"D\u1ecdn c\u1ed5ng USB \u1ea3o\" -Confirm `\n            -ConfirmMessage \"Thao t\u00e1c s\u1ebd t\u1ea1m d\u1eebng Spooler, kill ti\u1ebfn tr\u00ecnh driver h\u00e3ng m\u00e1y in \u0111ang ch\u1ea1y, v\u00e0 xo\u00e1 c\u1ed5ng USB kh\u00f4ng d\u00f9ng. Ti\u1ebfp t\u1ee5c?\" `\n            -Description \"D\u1eebng Spooler + gi\u1ea3i ph\u00f3ng ti\u1ebfn tr\u00ecnh driver h\u00e3ng m\u00e1y in \u0111ang treo c\u1ed5ng, xo\u00e1 c\u00e1c c\u1ed5ng USB \u1ea3o (USB*/CNUSB*) kh\u00f4ng c\u00f2n m\u00e1y in n\u00e0o tr\u1ecf t\u1edbi, r\u1ed3i rescan l\u1ea1i thi\u1ebft b\u1ecb.\" `\n            -DescriptionColor \"#A5B4FC\" `\n            -Action { Clear-StalePrinterPorts }\n    })\n    $window.FindName('CardDisableOffline').Add_Click({\n        Invoke-WpfAction -Title \"B\u1ecf Work Offline\" `\n            -Description \"Chuy\u1ec3n to\u00e0n b\u1ed9 m\u00e1y in \u0111ang \u1edf ch\u1ebf \u0111\u1ed9 'Work Offline' v\u1ec1 ONLINE.\" `\n            -DescriptionColor \"#6EE7B7\" `\n            -Action { Disable-PrinterWorkOfflineMode }\n    })\n    $window.FindName('CardSpooler').Add_Click({\n        Invoke-WpfAction -Title \"Kh\u1edfi \u0111\u1ed9ng l\u1ea1i Print Spooler\" `\n            -Description \"Xo\u00e1 job in b\u1ecb k\u1eb9t v\u00e0 restart d\u1ecbch v\u1ee5 Print Spooler.\" -DescriptionColor \"#C4B5FD\" `\n            -Action { Restart-PrintSpoolerSafe }\n    })\n\n    $window.FindName('BtnRefreshPrinters').Add_Click({ Update-WpfPrintersList })\n    $window.FindName('BtnShareSelected').Add_Click({\n        $listBox = $window.FindName('PrintersList')\n        $selected = @($listBox.Items | Where-Object { $_.IsChecked })\n        if (-not $selected -or $selected.Count -eq 0) {\n            Show-WpfNotice \"Ch\u01b0a ch\u1ecdn m\u00e1y in n\u00e0o \u0111\u1ec3 chia s\u1ebb.\"\n            return\n        }\n        Invoke-WpfAction -Title \"Chia s\u1ebb m\u00e1y in \u0111\u00e3 ch\u1ecdn\" -Action {\n            foreach ($cb in $selected) {\n                Set-PrinterSharedByName -PrinterName $cb.Tag\n            }\n        }\n        Update-WpfPrintersList\n    })\n    $window.FindName('BtnClearLog').Add_Click({\n        if ($Script:WpfLogBox) { $Script:WpfLogBox.Document.Blocks.Clear() }\n    })\n\n    $window.Add_Closed({\n        $Script:WpfWindow    = $null\n        $Script:WpfLogBox    = $null\n        $Script:WpfStatus    = $null\n        $Script:WpfBusyPanel = $null\n        $Script:WpfBusy      = $false\n        # Tr\u1ea3 l\u1ea1i c\u1eeda s\u1ed5 console khi \u0111\u00f3ng GUI (ph\u00f2ng khi ch\u1ea1y t\u01b0\u01a1ng t\u00e1c t\u1eeb 1 shell c\u00f3 s\u1eb5n)\n        Set-ConsoleWindowVisibility -Visible:$true | Out-Null\n    })\n\n    Show-WpfPage Home\n    Add-WpfLogLine -Text \"Ch\u1ecdn m\u1ed9t t\u00e1c v\u1ee5 \u1edf B\u1ea3ng \u0111i\u1ec1u khi\u1ec3n ho\u1eb7c c\u00e1c th\u1ebb \u0110i\u1ec1u h\u01b0\u1edbng.\" -Color Cyan\n\n    # Ch\u1ec9 hi\u1ec7n \u0111\u00fang 1 c\u1eeda s\u1ed5 WPF \u2014 \u1ea9n h\u1eb3n c\u1eeda s\u1ed5 console ph\u00eda sau (n\u1ebfu c\u00f3).\n    Set-ConsoleWindowVisibility -Visible:$false | Out-Null\n\n    [void]$window.ShowDialog()\n    return $true\n}\n\n\nfunction Show-ConsoleMenu {\n    do {\n        Clear-Host\n        Write-Host \"=======================================================\" -ForegroundColor Cyan\n        Write-Host \"   FIX &amp; SHARE PRINTER TOOL - Khac phuc loi chia se may in\" -ForegroundColor Cyan\n        Write-Host \"=======================================================\" -ForegroundColor Cyan\n        Write-Host \" [1] Chia se qua giao thuc CU   - SMB1 / CIFS\"\n        Write-Host \" [2] Chia se qua giao thuc MOI  - SMB2 / SMB3 (khuyen nghi)\"\n        Write-Host \" [3] Chi chay va loi (RPC / 0x0000011b / 0x00000709), khong doi SMB\"\n        Write-Host \" [4] Quan ly / chia se may in\"\n        Write-Host \" [0] Thoat\"\n        Write-Host \"=======================================================\"\n        $choice = Read-Host \"Chon (0/1/2/3/4)\"\n        switch ($choice) {\n            '1' { Invoke-SetupSmb1Sharing }\n            '2' { Invoke-SetupSmb2Sharing }\n            '3' { Invoke-FixCommonPrinterErrors; Restart-PrintSpoolerSafe }\n            '4' { Show-ConsolePrinterShareMenu }\n            '0' { Write-Host \"Thoat.\" }\n            default { Write-Host \"Lua chon khong hop le.\" -ForegroundColor Red }\n        }\n        if ($choice -ne '0') {\n            Write-Host \"`nLog chi tiet da luu tai: $Script:FSP_LogFile\" -ForegroundColor Cyan\n            Read-Host \"`nNhan Enter de quay lai menu (hoac dong cua so de thoat)\"\n        }\n    } while ($choice -ne '0')\n}\n\nif (-not $NoGui) { Set-ConsoleWindowVisibility -Visible:$false | Out-Null }\nWrite-Log \"FixSharePrinter (bundle) khoi dong. Log: $Script:FSP_LogFile\"\n\nif ($NoGui) {\n    Show-ConsoleMenu\n} else {\n    $ok = Show-WpfShell\n    if (-not $ok) {\n        Set-ConsoleWindowVisibility -Visible:$true | Out-Null\n        Write-Log \"Khong mo duoc giao dien WPF, chuyen sang menu console.\" \"WARN\"\n        Show-ConsoleMenu\n    }\n}\n\n", "creation_timestamp": "2026-09-27T16:28:31.000000Z"}