#Requires -Version 5.1 # ============================================================================= # MEPRO MIS PKL AUTO-DEPLOY - GUI Edition (WinForms) # PT Meprofarm - MIS PKL Deployment Automation # Author : MIS PKL KATAPANG | Version : 2.1 (ASCII-Safe Edition) # # Pemanggilan one-liner: # irm nekahost.com/deploy.ps1 | iex # ============================================================================= $ProgressPreference = 'SilentlyContinue' $ErrorActionPreference = 'SilentlyContinue' # --- Auto-Elevasi ke Administrator --- if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator)) { try { $tempFile = "$env:TEMP\MeproAutoDeploy_GUI.ps1" if ($PSCommandPath -and (Test-Path $PSCommandPath)) { Copy-Item $PSCommandPath $tempFile -Force } else { $MyInvocation.MyCommand.Definition | Out-File -FilePath $tempFile -Encoding ASCII -Force } Start-Process powershell.exe ` -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$tempFile`"" ` -Verb RunAs } catch { } exit } # --- Load Assembly WinForms & Drawing --- Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing [System.Windows.Forms.Application]::EnableVisualStyles() [System.Windows.Forms.Application]::SetCompatibleTextRenderingDefault($false) # --- Palet Warna Dark Theme --- $C = @{ Bg0 = [System.Drawing.Color]::FromArgb(10, 10, 20) Bg1 = [System.Drawing.Color]::FromArgb(18, 18, 34) Bg2 = [System.Drawing.Color]::FromArgb(26, 26, 46) Bg3 = [System.Drawing.Color]::FromArgb(38, 38, 64) Accent = [System.Drawing.Color]::FromArgb(45, 190, 255) Green = [System.Drawing.Color]::FromArgb(48, 210, 105) Red = [System.Drawing.Color]::FromArgb(255, 75, 75) Yellow = [System.Drawing.Color]::FromArgb(255, 200, 45) Purple = [System.Drawing.Color]::FromArgb(185, 95, 255) TextPri = [System.Drawing.Color]::FromArgb(222, 222, 240) TextSec = [System.Drawing.Color]::FromArgb(130, 130, 165) Border = [System.Drawing.Color]::FromArgb(45, 45, 75) LogBg = [System.Drawing.Color]::FromArgb(5, 5, 12) BtnExec = [System.Drawing.Color]::FromArgb(20, 130, 58) BtnSel = [System.Drawing.Color]::FromArgb(20, 75, 145) BtnDesel = [System.Drawing.Color]::FromArgb(125, 30, 30) AccentBr = [System.Drawing.Color]::FromArgb(0, 220, 255) } # ============================================================================= # BACKEND EXECUTION SCRIPTBLOCK # ============================================================================= $BackendScriptBlock = { param( [string[]]$SelectedTasks, [System.Collections.Concurrent.ConcurrentQueue[string]]$Queue ) $ProgressPreference = 'SilentlyContinue' $ErrorActionPreference = 'SilentlyContinue' function lLog { param($t, $c = "White") $Queue.Enqueue("$t|$c") } function lStep { param($m) lLog "[>>] $m" "Yellow" } function lOK { param($m) lLog " [OK] $m" "Green" } function lFail { param($m) lLog " [!!] $m" "Red" } function lInfo { param($m) lLog " [--] $m" "Cyan" } function lSect { param($m) lLog "`n ==== $m ====" "Purple" } function Invoke-WingetBootstrap { lSect "WINGET BOOTSTRAPPER" $wg = Get-Command winget -ErrorAction SilentlyContinue if ($wg) { lOK "Winget tersedia di sistem." return } lStep "Winget tidak ditemukan. Mengunduh dari GitHub Microsoft..." try { $url = "https://github.com/microsoft/winget-cli/releases/latest/download/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" $dest = "$env:TEMP\WingetInstaller.msixbundle" Invoke-WebRequest -Uri $url -OutFile $dest -UseBasicParsing -ErrorAction Stop Add-AppxPackage -Path $dest -ErrorAction Stop Remove-Item $dest -Force -ErrorAction SilentlyContinue lOK "Winget berhasil diinstal." } catch { lFail "Gagal menginstal Winget: $_" } } function Install-Winget { param([string]$Id, [string]$Name, [string]$Src = "winget") lStep "Menginstal $Name ($Id)..." $null = winget install --id $Id --source $Src --silent --accept-package-agreements --accept-source-agreements --disable-interactivity 2>&1 if ($LASTEXITCODE -eq 0 -or $LASTEXITCODE -eq -1978335189) { lOK "$Name - Selesai." } else { lFail "$Name - Winget exit code: $LASTEXITCODE" } } function Install-Spark { lStep "Mengunduh Spark Messenger 2.7.7 dari server internal..." $url = "https://nekahost.com/installer/spark_2_7_7.exe" $dest = "$env:TEMP\spark_setup.exe" try { Invoke-WebRequest -Uri $url -OutFile $dest -UseBasicParsing -ErrorAction Stop lStep "Menjalankan silent install..." $proc = Start-Process $dest -ArgumentList "-q" -Wait -PassThru -ErrorAction Stop if ($proc.ExitCode -le 1) { lOK "Spark Messenger 2.7.7 - Selesai." } else { lFail "Spark Messenger - ExitCode: $($proc.ExitCode)" } } catch { lFail "Gagal menginstal Spark Messenger: $_" } finally { if (Test-Path $dest) { Remove-Item $dest -Force -ErrorAction SilentlyContinue } } } function Enable-SMB1Client { lStep "Mengaktifkan SMB 1.0 Client..." try { Enable-WindowsOptionalFeature -Online -FeatureName "SMB1Protocol-Client" -NoRestart -ErrorAction Stop | Out-Null lOK "SMB 1.0 Client - Berhasil diaktifkan." } catch { lFail "SMB 1.0 Client: $_" } } function Install-WMICCapability { lStep "Menginstal WMIC (Windows Capability)..." try { Add-WindowsCapability -Online -Name "WMIC~~~~" -ErrorAction Stop | Out-Null lOK "WMIC - Berhasil diinstal." } catch { if ($_ -match "already") { lOK "WMIC - Sudah terinstal." } else { lFail "WMIC: $_" } } } function Set-DarkWallpaper { lStep "Mengatur wallpaper ke Dark Theme..." try { $wpPath = "$env:SystemRoot\Web\Wallpaper\Windows\img0.jpg" if (-not (Test-Path $wpPath)) { return } Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "Wallpaper" -Value $wpPath -ErrorAction Stop Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class WPSetter { [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni); } "@ -ErrorAction SilentlyContinue [WPSetter]::SystemParametersInfo(20, 0, $wpPath, 3) | Out-Null lOK "Wallpaper - Diatur ke Dark Theme." } catch { lFail "Wallpaper: $_" } } function Set-VFXCustomMode { lStep "Menerapkan Visual Effects (Custom Mode)..." try { $ve = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects" $dt = "HKCU:\Control Panel\Desktop" if (-not (Test-Path $ve)) { New-Item $ve -Force | Out-Null } Set-ItemProperty $ve -Name "VisualFXSetting" -Value 3 -Type DWord -ErrorAction Stop Set-ItemProperty $dt -Name "UserPreferencesMask" -Value ([byte[]](0x90, 0x12, 0x03, 0x80, 0x10, 0x00, 0x00, 0x00)) -Type Binary -ErrorAction Stop lOK "Visual Effects - Custom mode diterapkan." } catch { lFail "Visual Effects: $_" } } function Enable-FontSmoothing { lStep "Mengaktifkan Font Smoothing..." try { $dt = "HKCU:\Control Panel\Desktop" Set-ItemProperty $dt -Name "FontSmoothing" -Value 2 -Type String -ErrorAction Stop Set-ItemProperty $dt -Name "FontSmoothingType" -Value 2 -Type DWord -ErrorAction Stop lOK "Font Smoothing - Aktif." } catch { lFail "Font Smoothing: $_" } } function Enable-ThumbnailView { lStep "Mengaktifkan Thumbnail Preview..." try { Set-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "IconsOnly" -Value 0 -Type DWord -ErrorAction Stop lOK "Thumbnail Preview - Aktif." } catch { lFail "Thumbnail View: $_" } } function Enable-TranslucentSelection { lStep "Mengaktifkan Translucent Selection..." try { Set-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "ListviewAlphaSelect" -Value 1 -Type DWord -ErrorAction Stop lOK "Translucent Selection - Aktif." } catch { lFail "Translucent Selection: $_" } } function Enable-DragFullWindows { lStep "Mengaktifkan Show Window Contents While Dragging..." try { Set-ItemProperty "HKCU:\Control Panel\Desktop" -Name "DragFullWindows" -Value 1 -Type String -ErrorAction Stop lOK "Show Window Contents While Dragging - Aktif." } catch { lFail "Drag Full Windows: $_" } } function Restart-ExplorerSilent { lStep "Merestart Windows Explorer..." try { Stop-Process -Name "explorer" -Force -ErrorAction SilentlyContinue Start-Sleep -Milliseconds 1800 if (-not (Get-Process "explorer" -ErrorAction SilentlyContinue)) { Start-Process "explorer.exe" } lOK "Windows Explorer - Berhasil direstart." } catch { lFail "Explorer restart: $_" } } $taskMap = [ordered]@{ "chrome" = { Install-Winget "Google.Chrome" "Google Chrome" } "firefox" = { Install-Winget "Mozilla.Firefox" "Mozilla Firefox" } "openoffice" = { Install-Winget "Apache.OpenOffice" "Apache OpenOffice" } "wps" = { Install-Winget "Kingsoft.WPSOffice" "Kingsoft WPS Office" } "7zip" = { Install-Winget "7zip.7zip" "7-Zip" } "adobereader" = { Install-Winget "Adobe.Acrobat.Reader.64-bit" "Adobe Acrobat Reader" } "thunderbird" = { Install-Winget "Mozilla.Thunderbird" "Mozilla Thunderbird" } "avg" = { Install-Winget "XP8BX2DWV7TF50" "AVG AntiVirus Free" "msstore" } "spark" = { Install-Spark } "smb1" = { Enable-SMB1Client } "wmic" = { Install-WMICCapability } "wallpaper" = { Set-DarkWallpaper } "vfx" = { Set-VFXCustomMode } "fontsmooth" = { Enable-FontSmoothing } "thumbnails" = { Enable-ThumbnailView } "alphaselect" = { Enable-TranslucentSelection } "dragfull" = { Enable-DragFullWindows } } $visualTweakKeys = @("vfx", "fontsmooth", "thumbnails", "alphaselect", "dragfull") lSect "DEPLOYMENT DIMULAI" Invoke-WingetBootstrap $needExplorerRestart = $false foreach ($key in $taskMap.Keys) { if ($key -in $SelectedTasks) { & $taskMap[$key] if ($key -in $visualTweakKeys) { $needExplorerRestart = $true } } } if ($needExplorerRestart) { Restart-ExplorerSilent } lSect "DEPLOYMENT SELESAI" $Queue.Enqueue("__DONE__") } # ============================================================================= # GUI SETUP # ============================================================================= $script:ExecQueue = $null $script:ExecPS = $null $script:ExecRS = $null $script:ExecAsync = $null $script:ExecTimer = $null $script:TxtLog = $null $AllCheckBoxes = [System.Collections.Generic.List[System.Windows.Forms.CheckBox]]::new() function New-AppCheckBox { param([string]$Label, [string]$TaskKey, [int]$X, [int]$Y, [int]$W = 248) $cb = New-Object System.Windows.Forms.CheckBox $cb.Name = $TaskKey $cb.Text = " $Label" $cb.Checked = $true $cb.Location = New-Object System.Drawing.Point($X, $Y) $cb.Size = New-Object System.Drawing.Size($W, 23) $cb.ForeColor = [System.Drawing.Color]::White $cb.BackColor = [System.Drawing.Color]::Transparent $cb.Font = New-Object System.Drawing.Font("Segoe UI", 9) $cb.FlatStyle = [System.Windows.Forms.FlatStyle]::Standard $AllCheckBoxes.Add($cb) return $cb } function New-DarkGroupBox { param([string]$Title, [int]$X, [int]$Y, [int]$W, [int]$H) $gb = New-Object System.Windows.Forms.GroupBox $gb.Text = " $Title" $gb.Location = New-Object System.Drawing.Point($X, $Y) $gb.Size = New-Object System.Drawing.Size($W, $H) $gb.ForeColor = $C.Accent $gb.BackColor = $C.Bg2 $gb.Font = New-Object System.Drawing.Font("Segoe UI Semibold", 9) return $gb } function New-FlatButton { param([string]$Label, [int]$X, [int]$Y, [int]$W, [int]$H, [System.Drawing.Color]$Bg, [System.Drawing.Color]$Fg, [float]$FontPt = 9.5) $btn = New-Object System.Windows.Forms.Button $btn.Text = $Label $btn.Location = New-Object System.Drawing.Point($X, $Y) $btn.Size = New-Object System.Drawing.Size($W, $H) $btn.BackColor = $Bg $btn.ForeColor = $Fg $btn.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat $btn.FlatAppearance.BorderSize = 1 $btn.FlatAppearance.BorderColor = $Fg $btn.Font = New-Object System.Drawing.Font("Segoe UI Semibold", $FontPt) $btn.Cursor = [System.Windows.Forms.Cursors]::Hand $btn.UseVisualStyleBackColor = $false return $btn } function Append-Log { param([string]$Text, [System.Drawing.Color]$Color) if ($null -eq $script:TxtLog) { return } $script:TxtLog.SelectionStart = $script:TxtLog.TextLength $script:TxtLog.SelectionLength = 0 $script:TxtLog.SelectionColor = $Color $script:TxtLog.AppendText("$Text`n") $script:TxtLog.ScrollToCaret() } function New-SubLabel { param([string]$Text, [int]$X, [int]$Y, [int]$W = 350) $lbl = New-Object System.Windows.Forms.Label $lbl.Text = $Text $lbl.ForeColor = $C.Yellow $lbl.BackColor = [System.Drawing.Color]::Transparent $lbl.Font = New-Object System.Drawing.Font("Segoe UI", 8.5, [System.Drawing.FontStyle]::Italic) $lbl.Location = New-Object System.Drawing.Point($X, $Y) $lbl.Size = New-Object System.Drawing.Size($W, 18) return $lbl } # --- FORM SETUP --- $form = New-Object System.Windows.Forms.Form $form.Text = "Mepro Auto-Deploy - PT Meprofarm MIS PKL" $form.ClientSize = New-Object System.Drawing.Size(820, 832) $form.StartPosition = "CenterScreen" $form.BackColor = $C.Bg0 $form.ForeColor = $C.TextPri $form.Font = New-Object System.Drawing.Font("Segoe UI", 9) $form.FormBorderStyle = "FixedSingle" $form.MaximizeBox = $false # Header Panel $pHeader = New-Object System.Windows.Forms.Panel $pHeader.Size = New-Object System.Drawing.Size(820, 88) $pHeader.Location = New-Object System.Drawing.Point(0, 0) $pHeader.BackColor = $C.Bg1 $lblTitle = New-Object System.Windows.Forms.Label $lblTitle.Text = " MEPRO MIS PKL AUTO-DEPLOY" $lblTitle.Font = New-Object System.Drawing.Font("Consolas", 20, [System.Drawing.FontStyle]::Bold) $lblTitle.ForeColor = $C.AccentBr $lblTitle.Location = New-Object System.Drawing.Point(10, 6) $lblTitle.Size = New-Object System.Drawing.Size(780, 44) $lblTitle.BackColor = [System.Drawing.Color]::Transparent $lblSub = New-Object System.Windows.Forms.Label $lblSub.Text = " PT Meprofarm - MIS PKL - Corporate Deployment Automation - v2.1" $lblSub.Font = New-Object System.Drawing.Font("Segoe UI", 8.5) $lblSub.ForeColor = $C.TextSec $lblSub.Location = New-Object System.Drawing.Point(10, 52) $lblSub.Size = New-Object System.Drawing.Size(795, 20) $lblSub.BackColor = [System.Drawing.Color]::Transparent $pHeader.Controls.AddRange(@($lblTitle, $lblSub)) $form.Controls.Add($pHeader) $sepTop = New-Object System.Windows.Forms.Panel $sepTop.Size = New-Object System.Drawing.Size(820, 2) $sepTop.Location = New-Object System.Drawing.Point(0, 88) $sepTop.BackColor = $C.Accent $form.Controls.Add($sepTop) # Scroll Panel $pScroll = New-Object System.Windows.Forms.Panel $pScroll.Location = New-Object System.Drawing.Point(0, 90) $pScroll.Size = New-Object System.Drawing.Size(820, 458) $pScroll.BackColor = $C.Bg0 $pScroll.AutoScroll = $true $form.Controls.Add($pScroll) # GroupBoxes $gbBrowser = New-DarkGroupBox "[+] BROWSER" 8 8 248 95 $cbChrome = New-AppCheckBox "Google Chrome" "chrome" 10 26 $cbFirefox = New-AppCheckBox "Mozilla Firefox" "firefox" 10 54 $gbBrowser.Controls.AddRange(@($cbChrome, $cbFirefox)) $pScroll.Controls.Add($gbBrowser) $gbOffice = New-DarkGroupBox "[+] OFFICE SUITE" 265 8 248 95 $cbOpenOff = New-AppCheckBox "Apache OpenOffice" "openoffice" 10 26 $cbWPS = New-AppCheckBox "Kingsoft WPS Office" "wps" 10 54 $gbOffice.Controls.AddRange(@($cbOpenOff, $cbWPS)) $pScroll.Controls.Add($gbOffice) $gbUtility = New-DarkGroupBox "[+] UTILITY" 522 8 288 122 $cb7Zip = New-AppCheckBox "7-Zip" "7zip" 10 26 265 $cbAdobe = New-AppCheckBox "Adobe Acrobat Reader" "adobereader" 10 54 265 $cbThunder = New-AppCheckBox "Mozilla Thunderbird" "thunderbird" 10 82 265 $gbUtility.Controls.AddRange(@($cb7Zip, $cbAdobe, $cbThunder)) $pScroll.Controls.Add($gbUtility) $gbSecurity = New-DarkGroupBox "[+] SECURITY" 8 113 248 65 $cbAVG = New-AppCheckBox "AVG AntiVirus Free" "avg" 10 28 230 $gbSecurity.Controls.AddRange(@($cbAVG)) $pScroll.Controls.Add($gbSecurity) $gbInternal = New-DarkGroupBox "[+] APLIKASI INTERNAL" 265 113 248 65 $cbSpark = New-AppCheckBox "Spark Messenger 2.7.7" "spark" 10 28 230 $gbInternal.Controls.AddRange(@($cbSpark)) $pScroll.Controls.Add($gbInternal) $gbTweaks = New-DarkGroupBox "[+] WINDOWS TWEAKS & KONFIGURASI" 8 188 802 265 $lblSysCol = New-SubLabel "--- Fitur Sistem" 12 26 $cbSMB1 = New-AppCheckBox "Enable SMB 1.0 Client" "smb1" 12 50 270 $cbWMIC = New-AppCheckBox "Install WMIC (Legacy CLI)" "wmic" 12 78 270 $cbWallpaper = New-AppCheckBox "Set Wallpaper Default Dark" "wallpaper" 12 106 270 $lblVFXCol = New-SubLabel "--- Visual Effects (Custom Mode)" 415 26 $cbVFX = New-AppCheckBox "Apply Custom Performance Mode" "vfx" 415 50 290 $cbFontSmooth = New-AppCheckBox "Font Smoothing (ClearType)" "fontsmooth" 415 78 290 $cbThumbs = New-AppCheckBox "Thumbnail Preview (vs. Icons only)" "thumbnails" 415 106 290 $cbAlpha = New-AppCheckBox "Translucent Selection Rectangle" "alphaselect" 415 134 290 $cbDragFull = New-AppCheckBox "Show Window Contents While Dragging" "dragfull" 415 162 290 $lblTip = New-Object System.Windows.Forms.Label $lblTip.Text = " [i] Perubahan Visual Effects akan memicu restart Windows Explorer secara otomatis." $lblTip.ForeColor = $C.TextSec $lblTip.BackColor = [System.Drawing.Color]::Transparent $lblTip.Font = New-Object System.Drawing.Font("Segoe UI", 8, [System.Drawing.FontStyle]::Italic) $lblTip.Location = New-Object System.Drawing.Point(12, 234) $lblTip.Size = New-Object System.Drawing.Size(780, 18) $gbTweaks.Controls.AddRange(@($lblSysCol, $cbSMB1, $cbWMIC, $cbWallpaper, $lblVFXCol, $cbVFX, $cbFontSmooth, $cbThumbs, $cbAlpha, $cbDragFull, $lblTip)) $pScroll.Controls.Add($gbTweaks) # Buttons $pBtnRow = New-Object System.Windows.Forms.Panel $pBtnRow.Location = New-Object System.Drawing.Point(0, 550) $pBtnRow.Size = New-Object System.Drawing.Size(820, 54) $pBtnRow.BackColor = $C.Bg1 $btnSelAll = New-FlatButton "[v] Pilih Semua" 10 11 158 32 $C.BtnSel $C.Accent $btnDeselAll = New-FlatButton "[ ] Hapus Semua" 178 11 158 32 $C.BtnDesel $C.Red $btnExec = New-FlatButton ">>> EKSEKUSI DEPLOYMENT" 388 8 422 38 $C.BtnExec $C.TextPri 11.5 $btnExec.FlatAppearance.BorderColor = $C.Green $pBtnRow.Controls.AddRange(@($btnSelAll, $btnDeselAll, $btnExec)) $form.Controls.Add($pBtnRow) $sepMid = New-Object System.Windows.Forms.Panel $sepMid.Size = New-Object System.Drawing.Size(820, 2) $sepMid.Location = New-Object System.Drawing.Point(0, 604) $sepMid.BackColor = $C.Border $form.Controls.Add($sepMid) # Log Console $pLogHdr = New-Object System.Windows.Forms.Panel $pLogHdr.Size = New-Object System.Drawing.Size(820, 26) $pLogHdr.Location = New-Object System.Drawing.Point(0, 606) $pLogHdr.BackColor = $C.Bg1 $lblLogHdr = New-Object System.Windows.Forms.Label $lblLogHdr.Text = " [Log] DEPLOYMENT LOG CONSOLE - Real-time output" $lblLogHdr.Font = New-Object System.Drawing.Font("Segoe UI Semibold", 8.5) $lblLogHdr.ForeColor = $C.TextSec $lblLogHdr.BackColor = [System.Drawing.Color]::Transparent $lblLogHdr.Location = New-Object System.Drawing.Point(0, 5) $lblLogHdr.Size = New-Object System.Drawing.Size(600, 18) $pLogHdr.Controls.Add($lblLogHdr) $form.Controls.Add($pLogHdr) $txtLog = New-Object System.Windows.Forms.RichTextBox $txtLog.Location = New-Object System.Drawing.Point(0, 632) $txtLog.Size = New-Object System.Drawing.Size(820, 200) $txtLog.BackColor = $C.LogBg $txtLog.ForeColor = $C.TextPri $txtLog.Font = New-Object System.Drawing.Font("Consolas", 9) $txtLog.ReadOnly = $true $txtLog.ScrollBars = "ForcedVertical" $txtLog.BorderStyle = [System.Windows.Forms.BorderStyle]::None $txtLog.WordWrap = $false $form.Controls.Add($txtLog) $script:TxtLog = $txtLog Append-Log " ==============================================================================" $C.Border Append-Log " Mepro Auto-Deploy - PT Meprofarm MIS PKL - v2.1 ASCII Edition" $C.AccentBr Append-Log " ==============================================================================" $C.Border Append-Log " Semua komponen dicentang secara default. Gunakan tombol Pilih/Hapus jika perlu." $C.TextSec Append-Log " Winget Bootstrapper akan berjalan otomatis di awal setiap eksekusi." $C.TextSec Append-Log " ------------------------------------------------------------------------------" $C.Border # --- EVENT HANDLERS --- $btnSelAll.Add_Click({ foreach ($cb in $AllCheckBoxes) { $cb.Checked = $true } }) $btnDeselAll.Add_Click({ foreach ($cb in $AllCheckBoxes) { $cb.Checked = $false } }) $btnExec.Add_MouseEnter({ if ($btnExec.Enabled) { $btnExec.BackColor = [System.Drawing.Color]::FromArgb(30, 165, 72) } }) $btnExec.Add_MouseLeave({ if ($btnExec.Enabled) { $btnExec.BackColor = $C.BtnExec } }) $btnSelAll.Add_MouseEnter({ $btnSelAll.BackColor = $C.Bg3 }) $btnSelAll.Add_MouseLeave({ $btnSelAll.BackColor = $C.BtnSel }) $btnDeselAll.Add_MouseEnter({ $btnDeselAll.BackColor = $C.Bg3 }) $btnDeselAll.Add_MouseLeave({ $btnDeselAll.BackColor = $C.BtnDesel }) $btnExec.Add_Click({ $selectedTasks = @($AllCheckBoxes | Where-Object { $_.Checked } | ForEach-Object { $_.Name }) if ($selectedTasks.Count -eq 0) { [System.Windows.Forms.MessageBox]::Show("Tidak ada komponen yang dipilih!`nSilakan centang minimal satu item.", "Warning", 0, 48) | Out-Null return } $btnExec.Enabled = $false; $btnExec.Text = " ... Sedang Berjalan ..."; $btnExec.BackColor = $C.Bg3 $btnSelAll.Enabled = $false; $btnDeselAll.Enabled = $false foreach ($cb in $AllCheckBoxes) { $cb.Enabled = $false } Append-Log "" $C.TextSec Append-Log " ==== EKSEKUSI DIMULAI ======================================================" $C.AccentBr Append-Log (" Task terpilih (" + $selectedTasks.Count + "): " + ($selectedTasks -join ", ")) $C.TextSec Append-Log " ------------------------------------------------------------------------------" $C.Border $script:ExecQueue = [System.Collections.Concurrent.ConcurrentQueue[string]]::new() $script:ExecRS = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace() $script:ExecRS.ApartmentState = [System.Threading.ApartmentState]::STA $script:ExecRS.ThreadOptions = [System.Management.Automation.Runspaces.PSThreadOptions]::ReuseThread $script:ExecRS.Open() $script:ExecPS = [System.Management.Automation.PowerShell]::Create() $script:ExecPS.Runspace = $script:ExecRS $script:ExecPS.AddScript($BackendScriptBlock) | Out-Null $script:ExecPS.AddArgument($selectedTasks) | Out-Null $script:ExecPS.AddArgument($script:ExecQueue) | Out-Null $script:ExecAsync = $script:ExecPS.BeginInvoke() $script:ExecTimer = New-Object System.Windows.Forms.Timer $script:ExecTimer.Interval = 150 $script:ExecTimer.Add_Tick({ $colorMap = @{ "Green"=$C.Green; "Red"=$C.Red; "Yellow"=$C.Yellow; "Cyan"=$C.Accent; "Purple"=$C.Purple; "White"=$C.TextPri } $msg = [string]::Empty while ($script:ExecQueue.TryDequeue([ref]$msg)) { if ($msg -eq "__DONE__") { $script:ExecTimer.Stop(); $script:ExecTimer.Dispose(); $script:ExecTimer = $null try { $script:ExecPS.EndInvoke($script:ExecAsync) } catch { } $script:ExecPS.Dispose(); $script:ExecPS = $null $script:ExecRS.Close(); $script:ExecRS.Dispose(); $script:ExecRS = $null Append-Log " ------------------------------------------------------------------------------" $C.Border Append-Log " *** SEMUA INSTALASI SELESAI! ***" $C.Green Append-Log " ------------------------------------------------------------------------------" $C.Border $btnExec.Enabled = $true; $btnExec.Text = ">>> EKSEKUSI DEPLOYMENT"; $btnExec.BackColor = $C.BtnExec $btnSelAll.Enabled = $true; $btnDeselAll.Enabled = $true foreach ($cb in $AllCheckBoxes) { $cb.Enabled = $true } [System.Windows.Forms.MessageBox]::Show("Instalasi Selesai!`n`nHarap Restart PC.", "Mepro IT Auto-Deploy", 0, 64) | Out-Null return } if ($msg -match "^(.*)\|(\w+)$") { $txt = $matches[1]; $col = if ($colorMap.ContainsKey($matches[2])) { $colorMap[$matches[2]] } else { $C.TextPri } } else { $txt = $msg; $col = $C.TextPri } Append-Log $txt $col } }) $script:ExecTimer.Start() }) $form.Add_FormClosing({ if ($null -ne $script:ExecTimer) { $script:ExecTimer.Stop(); $script:ExecTimer.Dispose() } if ($null -ne $script:ExecPS) { try { $script:ExecPS.Stop() } catch { }; $script:ExecPS.Dispose() } if ($null -ne $script:ExecRS) { $script:ExecRS.Close(); $script:ExecRS.Dispose() } }) [System.Windows.Forms.Application]::Run($form)