@echo off
setlocal
set "ORBS_PS=%TEMP%\ORBS-Full-Support-Windows-PUSHOVER.ps1"
set "ORBS_PARAM=%TEMP%\ORBS-Full-Support-Windows-PUSHOVER.params.txt"
echo Preparing ORBS Full Support setup...
> "%ORBS_PARAM%" echo cmd_path=%~f0
>> "%ORBS_PARAM%" echo cmd_name=%~nx0
>> "%ORBS_PARAM%" echo cmd_args=%*
powershell -NoProfile -ExecutionPolicy Bypass -Command "$cmd = Get-Content -Raw -LiteralPath '%~f0'; $parts = $cmd -split '# POWERSHELL_SCRIPT_BELOW\r?\n', 2; if ($parts.Count -lt 2) { throw 'PowerShell section not found' }; Set-Content -LiteralPath '%ORBS_PS%' -Value $parts[1] -Encoding UTF8"
if errorlevel 1 (
  echo Could not prepare ORBS setup script.
  pause
  exit /b 1
)
echo Windows may ask permission to run ORBS Full Support Setup.
powershell -NoProfile -ExecutionPolicy Bypass -Command "Start-Process -FilePath 'powershell.exe' -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File \"%ORBS_PS%\" \"%ORBS_PARAM%\"' -Verb RunAs -Wait"
exit /b 0
# POWERSHELL_SCRIPT_BELOW
# ORBS Computers Full Support Setup for Windows
# Installs RustDesk service, writes ORBS self-hosted relay settings directly
# to the live user and LocalService RustDesk2.toml files, sets password,
# and saves the RustDesk ID for Don.

param(
  [string]$OrbsParamFile = ''
)

function Get-OrbsSetupParamMap {
  param([string]$Path)
  $map = @{}
  if ($Path -and (Test-Path -LiteralPath $Path)) {
    foreach ($line in Get-Content -LiteralPath $Path -ErrorAction SilentlyContinue) {
      if ($line -match '^([^=]+)=(.*)$') { $map[$matches[1]] = $matches[2] }
    }
  }
  return $map
}

function Find-OrbsWorkOrderId {
  param($ParamMap)

  # Preferred: the download page can pass ORBS_WORK_ORDER_ID or call this CMD with the ID as an argument.
  $candidates = @(
    $env:ORBS_WORK_ORDER_ID,
    $env:ORBS_WO,
    $(if ($ParamMap.ContainsKey('cmd_args')) { $ParamMap['cmd_args'] } else { '' }),
    $(if ($ParamMap.ContainsKey('cmd_name')) { $ParamMap['cmd_name'] } else { '' }),
    $(if ($ParamMap.ContainsKey('cmd_path')) { $ParamMap['cmd_path'] } else { '' })
  )

  foreach ($c in $candidates) {
    if ($c -and ($c -match '(ORBS[-_ ]?\d{6}[-_ ]?\d{3,6})')) {
      return (($matches[1] -replace '[_ ]','-') -replace 'ORBS-?', 'ORBS-')
    }
  }

  # Fallback: if a future download page drops a tiny work-order text file beside the installer, read it.
  $places = @(
    [Environment]::GetFolderPath('Desktop'),
    (Join-Path $env:USERPROFILE 'Downloads'),
    $env:TEMP
  ) | Where-Object { $_ -and (Test-Path $_) }

  foreach ($place in $places) {
    $files = Get-ChildItem -Path $place -Filter 'ORBS*Work*Order*.txt' -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 5
    foreach ($f in $files) {
      $txt = Get-Content -Raw -LiteralPath $f.FullName -ErrorAction SilentlyContinue
      if ($txt -and ($txt -match '(ORBS[-_ ]?\d{6}[-_ ]?\d{3,6})')) {
        return (($matches[1] -replace '[_ ]','-') -replace 'ORBS-?', 'ORBS-')
      }
    }
  }

  return ''
}

$OrbsParamMap = Get-OrbsSetupParamMap -Path $OrbsParamFile
$OrbsWorkOrderId = Find-OrbsWorkOrderId -ParamMap $OrbsParamMap

$ErrorActionPreference = 'Stop'
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$OrbsPhone = '970-464-5959'
$OrbsIdServer = 'onlinepclube.com'
$OrbsRelayServer = 'onlinepclube.com'
$OrbsApiServer = ''
$OrbsKey = 'QqzjKvAIOXHbTPOF3gyFRkKGBdHvW73HNAW30HOQ7dk='
$OrbsPassword = 'ORBS1one!'
$OrbsNotifyUrl = 'https://orbscomputers.com/api/rustdesk-install-notify.php'
$OrbsNotifyKey = 'ORBS-RD-s14HncUogm4akrCJIzpxON5b6QbSCWUD'
$OrbsConfigString = '=0nI9sGZ3E1TIBzMXFkTINzNXZHSkJ0RLtmUGl3ZzY0TQRlYIh1TJFkdLpmexFlI6ISeltmIsIiI6ISawFmIsISbvNmLlJWdsNGcl5Was52biojI5FGblJnIsISbvNmLlJWdsNGcl5Was52biojI0N3boJye'

$WorkDir = 'C:\ORBS\RustDeskSetup'
$Installer = Join-Path $WorkDir 'rustdesk-1.4.7-x86_64.exe'
$InstallerUrl = 'https://github.com/rustdesk/rustdesk/releases/download/1.4.7/rustdesk-1.4.7-x86_64.exe'
$ReportFile = Join-Path ([Environment]::GetFolderPath('Desktop')) 'ORBS RustDesk ID.txt'
$ConfigBackupFile = Join-Path $WorkDir 'ORBS-RustDesk-Server-Config.txt'
$LogFile = Join-Path $WorkDir 'ORBS-RustDesk-Setup-Log.txt'

function Write-Step($text) {
  Write-Host "=== $text ===" -ForegroundColor Cyan
  Add-Content -LiteralPath $LogFile -Value "[$(Get-Date -Format s)] $text" -ErrorAction SilentlyContinue
}


function Repair-OrbsRustDeskLaunchPermissions {
  param([Parameter(Mandatory=$true)][string]$ExePath)
  if (-not (Test-Path -LiteralPath $ExePath -PathType Leaf)) { throw "RustDesk permission repair cannot find: $ExePath" }
  $installDir = Split-Path -Parent $ExePath
  & icacls.exe $installDir /inheritance:e | Out-Null
  if ($LASTEXITCODE -ne 0) { throw 'RustDesk folder inheritance repair failed.' }
  & icacls.exe $installDir /grant:r '*S-1-5-32-545:(OI)(CI)(RX)' /T /C | Out-Null
  if ($LASTEXITCODE -ne 0) { throw 'RustDesk Users Read/Execute permission repair failed.' }
  $usersSid = New-Object System.Security.Principal.SecurityIdentifier('S-1-5-32-545')
  $verified = $false
  foreach ($rule in (Get-Acl -LiteralPath $ExePath).Access) {
    try {
      $sid = $rule.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value
      if ($sid -eq $usersSid.Value -and $rule.AccessControlType -eq 'Allow' -and (($rule.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::ReadAndExecute) -ne 0)) { $verified = $true }
    } catch {}
  }
  if (-not $verified) { throw 'RustDesk Users Read/Execute permission could not be verified.' }
  Add-Content -LiteralPath $LogFile -Value "[$(Get-Date -Format s)] RustDesk launch permissions VERIFIED for Builtin Users." -ErrorAction SilentlyContinue
  return $true
}
function Stop-RustDeskThings {
  Get-Process -Name 'rustdesk' -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
  Start-Sleep -Seconds 2
  try { Stop-Service -Name 'RustDesk' -Force -ErrorAction SilentlyContinue } catch {}
  Start-Sleep -Seconds 2
}

function Get-RustDeskExe {
  $candidates = @(
    "$env:ProgramFiles\RustDesk\rustdesk.exe",
    "${env:ProgramFiles(x86)}\RustDesk\rustdesk.exe",
    "$env:LOCALAPPDATA\Programs\RustDesk\rustdesk.exe"
  )
  foreach ($c in $candidates) {
    if ($c -and (Test-Path $c)) { return $c }
  }
  $found = Get-ChildItem -Path $env:ProgramFiles, ${env:ProgramFiles(x86)} -Filter rustdesk.exe -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
  if ($found) { return $found.FullName }
  return $null
}

function Write-OrbsToml($Path, [bool]$ServiceStyle) {
  $dir = Split-Path $Path -Parent
  New-Item -ItemType Directory -Path $dir -Force | Out-Null
  if (Test-Path $Path) {
    Copy-Item -LiteralPath $Path -Destination ($Path + '.orbs-backup-' + (Get-Date -Format 'yyyyMMdd-HHmmss')) -Force -ErrorAction SilentlyContinue
  }
  $rendezvous = if ($ServiceStyle) { "$OrbsIdServer`:21116" } else { 'rs-ny.rustdesk.com:21116' }
  $toml = @"
rendezvous_server = '$rendezvous'
nat_type = 1
serial = 0
unlock_pin = ''

[options]
custom-rendezvous-server = '$OrbsIdServer'
relay-server = '$OrbsRelayServer'
key = '$OrbsKey'
av1-test = 'Y'
"@
  Set-Content -LiteralPath $Path -Value $toml -Encoding UTF8 -Force
}

New-Item -ItemType Directory -Path $WorkDir -Force | Out-Null
Set-Content -LiteralPath $LogFile -Value "ORBS RustDesk setup log started $(Get-Date)" -Encoding UTF8 -Force
Add-Content -LiteralPath $LogFile -Value "Work order detected: $OrbsWorkOrderId" -ErrorAction SilentlyContinue
Set-Content -LiteralPath $ConfigBackupFile -Value $OrbsConfigString -Encoding ASCII -Force

Write-Host ''
Write-Host '=== ORBS Full Support Setup ===' -ForegroundColor Green
Write-Host 'This installs ORBS RustDesk full support for Don Reed / ORBS Computers.'
Write-Host "Call/Text Don: $OrbsPhone"
if ($OrbsWorkOrderId) { Write-Host "Work Order: $OrbsWorkOrderId" -ForegroundColor Yellow }
Write-Host ''

Write-Step 'Stopping any old RustDesk windows/service'
Stop-RustDeskThings

Write-Step 'Downloading RustDesk Windows installer if needed'
if (!(Test-Path $Installer)) {
  Invoke-WebRequest -Uri $InstallerUrl -OutFile $Installer -UseBasicParsing
}

Write-Step 'Installing RustDesk'
$proc = Start-Process -FilePath $Installer -ArgumentList '--silent-install' -PassThru -WindowStyle Hidden
if (-not $proc.WaitForExit(90)) {
  Write-Host 'Installer left RustDesk open; ORBS setup will continue.' -ForegroundColor Yellow
  Get-Process -Name 'rustdesk' -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
}
Start-Sleep -Seconds 5

$RustDeskExe = Get-RustDeskExe
if (-not $RustDeskExe) {
  throw 'Could not find installed rustdesk.exe after install.'
}
Write-Host "RustDesk program: $RustDeskExe"

Write-Step 'Repairing and verifying RustDesk launch permissions'
$null = Repair-OrbsRustDeskLaunchPermissions -ExePath $RustDeskExe

Write-Step 'Installing and starting RustDesk service'
# RustDesk may open a visible desktop app and keep the --install-service call alive.
# Start it with a timeout so ORBS setup can continue without the customer using Task Manager.
try {
  $svcProc = Start-Process -FilePath $RustDeskExe -ArgumentList '--install-service' -PassThru -WindowStyle Hidden
  if (-not $svcProc.WaitForExit(25)) {
    Write-Host 'RustDesk service command stayed open; ORBS setup will continue.' -ForegroundColor Yellow
    try { $svcProc.Kill() } catch {}
  }
} catch {
  Write-Host 'RustDesk service command returned an error or was already installed; ORBS setup will continue.' -ForegroundColor Yellow
}
Start-Sleep -Seconds 3
# Close any visible RustDesk windows that the installer/service command left open.
Get-Process -Name 'rustdesk' -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2
try { Start-Service -Name 'RustDesk' -ErrorAction SilentlyContinue } catch {}
Start-Sleep -Seconds 3

Write-Step 'Writing ORBS relay settings directly to RustDesk config files'
Stop-RustDeskThings

$userConfig = Join-Path $env:APPDATA 'RustDesk\config\RustDesk2.toml'
$serviceConfig = 'C:\Windows\ServiceProfiles\LocalService\AppData\Roaming\RustDesk\config\RustDesk2.toml'
Write-OrbsToml -Path $userConfig -ServiceStyle:$false
Write-OrbsToml -Path $serviceConfig -ServiceStyle:$true

# Also run RustDesk's own config import command after direct file write.
& $RustDeskExe --config $OrbsConfigString | Out-Null 2>&1
Start-Sleep -Seconds 2

Write-Step 'Starting RustDesk service with ORBS settings'
try { Start-Service -Name 'RustDesk' -ErrorAction SilentlyContinue } catch {}
Start-Sleep -Seconds 5

Write-Step 'Setting RustDesk permanent password'
& $RustDeskExe --password $OrbsPassword | Out-Null 2>&1
Start-Sleep -Seconds 3

Write-Step 'Reading RustDesk ID'
$id = ''
try { $id = (& $RustDeskExe --get-id 2>$null | Select-Object -First 1).Trim() } catch {}
if (-not $id) { $id = 'Could not read ID automatically. Open RustDesk and read ID to Don.' }

$report = @"
ORBS RustDesk Full Support Setup Complete

Work Order: $OrbsWorkOrderId
Computer: $env:COMPUTERNAME
Windows User: $env:USERNAME
RustDesk ID: $id
ID Server: $OrbsIdServer
Relay Server: $OrbsRelayServer
Password: ORBS support password was set by ORBS setup.

Give this ID to Don if he does not already have it.
Don Reed / ORBS Computers: $OrbsPhone

ORBS config backup:
$ConfigBackupFile

Direct config files written:
$userConfig
$serviceConfig
"@
Set-Content -LiteralPath $ReportFile -Value $report -Encoding UTF8 -Force

Write-Step 'Sending ORBS RustDesk install notification to Don'
try {
  $payload = @{
    install_key = $OrbsNotifyKey
    work_order_id = $OrbsWorkOrderId
    work_order = $OrbsWorkOrderId
    source = 'ORBS RustDesk Windows Installer'
    status = 'complete'
    computer = $env:COMPUTERNAME
    windows_user = $env:USERNAME
    rustdesk_id = $id
    id_server = $OrbsIdServer
    relay_server = $OrbsRelayServer
    local_time = (Get-Date).ToString('s')
  } | ConvertTo-Json -Depth 4

  Invoke-RestMethod -Uri $OrbsNotifyUrl -Method Post -ContentType 'application/json' -Body $payload -TimeoutSec 15 | Out-Null
  Write-Host 'ORBS notification was sent to Don.' -ForegroundColor Green
} catch {
  Write-Host 'ORBS notification could not be sent, but setup is still complete.' -ForegroundColor Yellow
  Add-Content -LiteralPath $LogFile -Value "[$(Get-Date -Format s)] Pushover notify failed: $($_.Exception.Message)" -ErrorAction SilentlyContinue
}

Write-Host ''
Write-Host 'ORBS RustDesk Full Support Setup Complete' -ForegroundColor Green
if ($OrbsWorkOrderId) { Write-Host "Work Order: $OrbsWorkOrderId" -ForegroundColor Green }
Write-Host "Computer: $env:COMPUTERNAME" -ForegroundColor Green
Write-Host "Windows User: $env:USERNAME" -ForegroundColor Green
Write-Host "RustDesk ID: $id" -ForegroundColor Green
Write-Host "ID Server: $OrbsIdServer" -ForegroundColor Green
Write-Host "Relay Server: $OrbsRelayServer" -ForegroundColor Green
Write-Host ''
Write-Host "The RustDesk ID was saved to the Desktop as ORBS RustDesk ID.txt." -ForegroundColor Green
Write-Host 'ORBS setup is complete. You may close this blue setup window with the X.' -ForegroundColor Yellow
Start-Sleep -Seconds 3
exit 0
