Update 8x8_Work_Updater.ps1
This commit is contained in:
+123
-38
@@ -1,9 +1,8 @@
|
||||
# ==============================================================================
|
||||
# Script Name: 8x8_Work_Updater.ps1
|
||||
# Description: Downloads 8x8 with a progress bar, schedules and launches an unclosable
|
||||
# VBScript interactive countdown directly in the user session,
|
||||
# waits for user confirmation or 1-hour timeout, silently installs,
|
||||
# and relaunches 8x8 Work seamlessly.
|
||||
# Description: Downloads 8x8 with a progress bar, launches an unclosable HTA
|
||||
# countdown prompt in the user's session (no X button), waits for
|
||||
# user action or 1-hour timeout, installs silently, and relaunches 8x8.
|
||||
# ==============================================================================
|
||||
|
||||
# Ensure script is running elevated
|
||||
@@ -16,7 +15,7 @@ Add-Type -AssemblyName System.Net.Http
|
||||
|
||||
$workDir = "C:\ProgramData\JCT600_8x8Update"
|
||||
$flagFile = Join-Path $workDir "8x8_Update_Proceed.flag"
|
||||
$vbsScript = Join-Path $workDir "Show-8x8Prompt.vbs"
|
||||
$htaPromptPath = Join-Path $workDir "Show-8x8Prompt.hta"
|
||||
$installerPath = Join-Path $workDir "8x8_Work_Installer.msi"
|
||||
|
||||
if (-not (Test-Path $workDir)) {
|
||||
@@ -71,45 +70,131 @@ try {
|
||||
}
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Step 2: Generate Persistent VBScript UI Dialog (Cannot be dismissed via X)
|
||||
# Step 2: Generate Unclosable HTA Countdown Dialog (No Close/X Button)
|
||||
# --------------------------------------------------------------------------
|
||||
Write-Host "[2/4] Generating user dialog..." -ForegroundColor Cyan
|
||||
Write-Host "[2/4] Generating unclosable dialog..." -ForegroundColor Cyan
|
||||
|
||||
$vbsContent = @"
|
||||
Set objShell = CreateObject("WScript.Shell")
|
||||
Set objFSO = CreateObject("Scripting.FileSystemObject")
|
||||
$htaContent = @"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>JCT600 IT Support — 8x8 Work Update</title>
|
||||
<HTA:APPLICATION
|
||||
ID="o8x8Update"
|
||||
APPLICATIONNAME="JCT600 8x8 Work Update"
|
||||
BORDER="dialog"
|
||||
BORDERSTYLE="normal"
|
||||
CAPTION="yes"
|
||||
CONTEXTMENU="no"
|
||||
ICON=""
|
||||
INNERBORDER="no"
|
||||
MAXIMIZEBUTTON="no"
|
||||
MINIMIZEBUTTON="no"
|
||||
NAVIGABLE="no"
|
||||
SCROLL="no"
|
||||
SCROLLFLAT="no"
|
||||
SELECTION="no"
|
||||
SHOWINTASKBAR="yes"
|
||||
SINGLEINSTANCE="yes"
|
||||
SYSMENU="no"
|
||||
WINDOWSTATE="normal"
|
||||
/>
|
||||
<style>
|
||||
body {
|
||||
background-color: #F0F2F5;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
}
|
||||
.header {
|
||||
color: #002B49;
|
||||
font-size: 17px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.message {
|
||||
color: #333333;
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.timer {
|
||||
color: #C00000;
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 18px;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
.btn-update {
|
||||
background-color: #002B49;
|
||||
color: #FFFFFF;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
padding: 10px 32px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn-update:hover {
|
||||
background-color: #004B7D;
|
||||
}
|
||||
</style>
|
||||
<script language="javascript">
|
||||
var totalSeconds = 3600;
|
||||
|
||||
strMsg = "An automatic update for 8x8 Work has been scheduled by IT Support." & vbCrLf & vbCrLf & _
|
||||
"Please save your active work and finish ongoing calls." & vbCrLf & vbCrLf & _
|
||||
"Click OK to update now, or the update will proceed automatically in 60 minutes."
|
||||
function initWindow() {
|
||||
window.resizeTo(480, 270);
|
||||
window.moveTo((screen.width - 480) / 2, (screen.height - 270) / 2);
|
||||
updateDisplay();
|
||||
setInterval(tick, 1000);
|
||||
}
|
||||
|
||||
startTime = Timer
|
||||
totalSeconds = 3600
|
||||
function tick() {
|
||||
if (totalSeconds > 0) {
|
||||
totalSeconds--;
|
||||
updateDisplay();
|
||||
} else {
|
||||
proceedUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
Do
|
||||
elapsed = Timer - startTime
|
||||
If elapsed < 0 Then elapsed = elapsed + 86400 ' Handle midnight rollover
|
||||
remaining = Int(totalSeconds - elapsed)
|
||||
function updateDisplay() {
|
||||
var mins = Math.floor(totalSeconds / 60);
|
||||
var secs = totalSeconds % 60;
|
||||
var formattedMins = mins < 10 ? "0" + mins : mins;
|
||||
var formattedSecs = secs < 10 ? "0" + secs : secs;
|
||||
document.getElementById("timerDisplay").innerText = formattedMins + ":" + formattedSecs;
|
||||
}
|
||||
|
||||
If remaining <= 0 Then Exit Do
|
||||
|
||||
' 64 = Information Icon, 4096 = System Modal (Always on Top)
|
||||
intReturn = objShell.Popup(strMsg, remaining, "JCT600 IT Support - 8x8 Work Update", 64 + 4096)
|
||||
|
||||
' If user clicked OK (1), break loop
|
||||
If intReturn = 1 Then Exit Do
|
||||
Loop
|
||||
|
||||
' Create flag file to signal main script
|
||||
Set objFile = objFSO.CreateTextFile("$flagFile", True)
|
||||
objFile.WriteLine("proceed")
|
||||
objFile.Close
|
||||
function proceedUpdate() {
|
||||
try {
|
||||
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
var file = fso.CreateTextFile("$($flagFile.Replace('\', '\\'))", true);
|
||||
file.WriteLine("proceed");
|
||||
file.Close();
|
||||
} catch(e) {}
|
||||
window.close();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="initWindow()">
|
||||
<div class="header">JCT600 — IT SUPPORT</div>
|
||||
<div class="message">
|
||||
An automatic update for 8x8 Work has been scheduled.<br>
|
||||
Please save active work or click <b>Update Now</b> to begin.
|
||||
</div>
|
||||
<div class="timer" id="timerDisplay">60:00</div>
|
||||
<button class="btn-update" onclick="proceedUpdate()">Update Now</button>
|
||||
</body>
|
||||
</html>
|
||||
"@
|
||||
|
||||
[System.IO.File]::WriteAllText($vbsScript, $vbsContent, [System.Text.Encoding]::ASCII)
|
||||
[System.IO.File]::WriteAllText($htaPromptPath, $htaContent, [System.Text.Encoding]::ASCII)
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Step 3: Launch Native Dialog inside Active User Session
|
||||
# Step 3: Launch Unclosable Dialog in Active User Session
|
||||
# --------------------------------------------------------------------------
|
||||
Write-Host "[3/4] Launching prompt on logged-in user desktop..." -ForegroundColor Cyan
|
||||
|
||||
@@ -120,10 +205,11 @@ objFile.Close
|
||||
} else {
|
||||
$taskName = "JCT600_8x8_UpdatePrompt"
|
||||
|
||||
schtasks.exe /Create /TN $taskName /TR "wscript.exe `"$vbsScript`"" /SC ONCE /ST 00:00 /IT /RU "$loggedUser" /F | Out-Null
|
||||
# mshta.exe runs the HTML Application natively inside the user's interactive desktop
|
||||
schtasks.exe /Create /TN $taskName /TR "mshta.exe `"$htaPromptPath`"" /SC ONCE /ST 00:00 /IT /RU "$loggedUser" /F | Out-Null
|
||||
schtasks.exe /Run /TN $taskName | Out-Null
|
||||
|
||||
Write-Host "Prompt sent to $loggedUser. Waiting for user confirmation or 1-hour expiration..." -ForegroundColor Yellow
|
||||
Write-Host "Prompt active for $loggedUser. Waiting for user action or timer expiration..." -ForegroundColor Yellow
|
||||
while (-not (Test-Path $flagFile)) {
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
@@ -175,9 +261,8 @@ objFile.Close
|
||||
if ($exePath) {
|
||||
if (-not [string]::IsNullOrWhiteSpace($loggedUser)) {
|
||||
$launchTask = "JCT600_8x8_Launch"
|
||||
|
||||
# Using explorer.exe inside the scheduled task ensures the UI process spawns detached into the user shell
|
||||
$taskRunCmd = "explorer.exe `"$exePath`""
|
||||
|
||||
schtasks.exe /Create /TN $launchTask /TR "$taskRunCmd" /SC ONCE /ST 00:00 /IT /RU "$loggedUser" /F | Out-Null
|
||||
schtasks.exe /Run /TN $launchTask | Out-Null
|
||||
|
||||
|
||||
Reference in New Issue
Block a user