Add TacticalRMM and RustDesk deployment scripts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
# author: https://github.com/bradhawkins85
|
||||
# modified: added RustDesk (ScoutIT-RemoteSupport) silent install with service verification and ID output
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
|
||||
$innosetup = 'tacticalagent-v2.10.0-windows-amd64.exe'
|
||||
$api = '"https://apirmm.scoutitsystems.com"'
|
||||
$clientid = '1'
|
||||
$siteid = '1'
|
||||
$agenttype = '"workstation"'
|
||||
$power = 0
|
||||
$rdp = 0
|
||||
$ping = 0
|
||||
$auth = '"f77cac29dc421abacbfc1882c2700b655f7a4bcf6500aaec040208dc2a5bdbff"'
|
||||
$downloadlink = 'https://agents.tacticalrmm.com/api/v2/agents/?version=2.10.0&arch=amd64&token=f3c1cbee-7d48-4f2a-8f0a-7cc33bb42802&plat=windows&api=apirmm.scoutitsystems.com'
|
||||
$apilink = $downloadlink.split('/')
|
||||
|
||||
# ── RustDesk / ScoutIT Remote Support config ──────────────────────────────────
|
||||
$rustdeskMsi = 'estudio-scoutit-remotesupport.msi'
|
||||
$rustdeskDl = 'https://files.scoutitsystems.com/public/api/raw?hash=VOG5D5aP2ih-2KAaDT0h4Q'
|
||||
$rustdeskInstallDir = 'C:\Program Files\ScoutIT-RemoteSupport'
|
||||
$rustdeskService = 'ScoutIT-RemoteSupport'
|
||||
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
# ── Helper: Install RustDesk ──────────────────────────────────────────────────
|
||||
function Install-RustDesk {
|
||||
$msiPath = "$env:TMP\$rustdeskMsi"
|
||||
|
||||
# Download
|
||||
Write-Host "Downloading ScoutIT Remote Support client..."
|
||||
Try {
|
||||
Invoke-WebRequest -Uri $rustdeskDl -OutFile $msiPath
|
||||
}
|
||||
Catch {
|
||||
Write-Warning "RustDesk download failed: $($_.Exception.Message)"
|
||||
return
|
||||
}
|
||||
|
||||
# Silent MSI install
|
||||
Write-Host "Installing ScoutIT Remote Support client silently..."
|
||||
Try {
|
||||
Start-Process -FilePath "msiexec.exe" `
|
||||
-ArgumentList "/i `"$msiPath`" /qn /norestart CREATEDESKTOPSHORTCUTS=`"N`" INSTALLPRINTER=`"N`"" `
|
||||
-Wait
|
||||
Start-Sleep -Seconds 10
|
||||
}
|
||||
Catch {
|
||||
Write-Warning "RustDesk MSI install failed: $($_.Exception.Message)"
|
||||
return
|
||||
}
|
||||
Finally {
|
||||
if (Test-Path $msiPath) { Remove-Item -Path $msiPath -Force }
|
||||
}
|
||||
|
||||
# Locate the installed exe
|
||||
$rustdeskExe = "$rustdeskInstallDir\$($rustdeskMsi -replace '\.msi$', '.exe')"
|
||||
if (-not (Test-Path $rustdeskExe)) {
|
||||
Write-Host "Searching for RustDesk exe in Program Files..."
|
||||
$found = Get-ChildItem 'C:\Program Files' -Recurse -Filter '*.exe' -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Name -match 'rustdesk|scoutit|remotesupport' } |
|
||||
Select-Object -First 1
|
||||
if ($found) {
|
||||
$rustdeskExe = $found.FullName
|
||||
Write-Host "Found exe at: $rustdeskExe"
|
||||
} else {
|
||||
Write-Warning "Could not locate RustDesk exe. Skipping service and ID steps."
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
$exeDir = Split-Path $rustdeskExe
|
||||
|
||||
# Install service if not present
|
||||
$svc = Get-Service -Name $rustdeskService -ErrorAction SilentlyContinue
|
||||
if ($null -eq $svc) {
|
||||
Write-Host "Registering ScoutIT Remote Support service..."
|
||||
Start-Process -FilePath $rustdeskExe -ArgumentList '--install-service' -Wait
|
||||
Start-Sleep -Seconds 20
|
||||
$svc = Get-Service -Name $rustdeskService -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# Ensure service is running
|
||||
if ($null -ne $svc) {
|
||||
$attempts = 0
|
||||
while ($svc.Status -ne 'Running' -and $attempts -lt 5) {
|
||||
Write-Host "Starting ScoutIT Remote Support service (attempt $($attempts + 1))..."
|
||||
Start-Service -Name $rustdeskService -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 5
|
||||
$svc.Refresh()
|
||||
$attempts++
|
||||
}
|
||||
if ($svc.Status -eq 'Running') {
|
||||
Write-Host "ScoutIT Remote Support service is running."
|
||||
} else {
|
||||
Write-Warning "ScoutIT Remote Support service did not reach Running state."
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Service '$rustdeskService' not found after install."
|
||||
}
|
||||
|
||||
# Get and output the RustDesk ID (visible in RMM job logs)
|
||||
Push-Location $exeDir
|
||||
$rustdeskId = & $rustdeskExe --get-id 2>&1
|
||||
Pop-Location
|
||||
|
||||
Write-Output "................................................."
|
||||
Write-Output "ScoutIT Remote Support ID: $rustdeskId"
|
||||
Write-Output "................................................."
|
||||
}
|
||||
|
||||
# ── Tactical RMM ─────────────────────────────────────────────────────────────
|
||||
$serviceName = 'tacticalrmm'
|
||||
If (Get-Service $serviceName -ErrorAction SilentlyContinue) {
|
||||
Write-Host "Tactical RMM Is Already Installed"
|
||||
} Else {
|
||||
$OutPath = $env:TMP
|
||||
$output = $innosetup
|
||||
$installArgs = @('-m install --api ', "$api", '--client-id', $clientid, '--site-id', $siteid, '--agent-type', "$agenttype", '--auth', "$auth")
|
||||
if ($power) { $installArgs += "--power" }
|
||||
if ($rdp) { $installArgs += "--rdp" }
|
||||
if ($ping) { $installArgs += "--ping" }
|
||||
|
||||
Try {
|
||||
$DefenderStatus = Get-MpComputerStatus | Select-Object AntivirusEnabled
|
||||
if ($DefenderStatus -match "True") {
|
||||
Add-MpPreference -ExclusionPath 'C:\Program Files\TacticalAgent\*'
|
||||
Add-MpPreference -ExclusionPath 'C:\Program Files\Mesh Agent\*'
|
||||
Add-MpPreference -ExclusionPath 'C:\ProgramData\TacticalRMM\*'
|
||||
}
|
||||
}
|
||||
Catch { # pass
|
||||
}
|
||||
|
||||
$X = 0
|
||||
do {
|
||||
Write-Output "Waiting for network"
|
||||
Start-Sleep -s 5
|
||||
$X += 1
|
||||
} until (($connectresult = Test-NetConnection $apilink[2] -Port 443 | Where-Object { $_.TcpTestSucceeded }) -or $X -eq 3)
|
||||
|
||||
if ($connectresult.TcpTestSucceeded -eq $true) {
|
||||
Try {
|
||||
Invoke-WebRequest -Uri $downloadlink -OutFile "$OutPath\$output"
|
||||
Start-Process -FilePath "$OutPath\$output" -ArgumentList '/VERYSILENT /SUPPRESSMSGBOXES' -Wait
|
||||
Write-Host "Extracting..."
|
||||
Start-Sleep -s 5
|
||||
Start-Process -FilePath "C:\Program Files\TacticalAgent\tacticalrmm.exe" -ArgumentList $installArgs -Wait
|
||||
|
||||
# ── Install RustDesk after Tactical RMM ──
|
||||
Install-RustDesk
|
||||
|
||||
exit 0
|
||||
}
|
||||
Catch {
|
||||
$ErrorMessage = $_.Exception.Message
|
||||
$FailedItem = $_.Exception.ItemName
|
||||
Write-Error -Message "$ErrorMessage $FailedItem"
|
||||
exit 1
|
||||
}
|
||||
Finally {
|
||||
if (Test-Path "$OutPath\$output") { Remove-Item -Path "$OutPath\$output" -Force }
|
||||
}
|
||||
} else {
|
||||
Write-Output "Unable to connect to server"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
# ScoutIT Remote Support (RustDesk) - Standalone Install Script
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
|
||||
# ── Config ────────────────────────────────────────────────────────────────────
|
||||
$rustdeskMsi = 'estudio-scoutit-remotesupport.msi'
|
||||
$rustdeskDl = 'https://files.scoutitsystems.com/public/api/raw?hash=VOG5D5aP2ih-2KAaDT0h4Q'
|
||||
$rustdeskInstallDir = 'C:\Program Files\ScoutIT-RemoteSupport'
|
||||
$rustdeskService = 'ScoutIT-RemoteSupport'
|
||||
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
# ── Check if already installed ────────────────────────────────────────────────
|
||||
$svcCheck = Get-Service -Name $rustdeskService -ErrorAction SilentlyContinue
|
||||
if ($null -ne $svcCheck) {
|
||||
Write-Host "ScoutIT Remote Support is already installed. Exiting."
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ── Download ──────────────────────────────────────────────────────────────────
|
||||
$msiPath = "$env:TMP\$rustdeskMsi"
|
||||
Write-Host "Downloading ScoutIT Remote Support client..."
|
||||
Try {
|
||||
Invoke-WebRequest -Uri $rustdeskDl -OutFile $msiPath
|
||||
}
|
||||
Catch {
|
||||
Write-Error "Download failed: $($_.Exception.Message)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ── Silent MSI install ────────────────────────────────────────────────────────
|
||||
Write-Host "Installing ScoutIT Remote Support client silently..."
|
||||
Try {
|
||||
Start-Process -FilePath "msiexec.exe" `
|
||||
-ArgumentList "/i `"$msiPath`" /qn /norestart CREATEDESKTOPSHORTCUTS=`"N`" INSTALLPRINTER=`"N`"" `
|
||||
-Wait
|
||||
Start-Sleep -Seconds 10
|
||||
}
|
||||
Catch {
|
||||
Write-Error "MSI install failed: $($_.Exception.Message)"
|
||||
exit 1
|
||||
}
|
||||
Finally {
|
||||
if (Test-Path $msiPath) { Remove-Item -Path $msiPath -Force }
|
||||
}
|
||||
|
||||
# ── Locate the installed exe ──────────────────────────────────────────────────
|
||||
$rustdeskExe = "$rustdeskInstallDir\$($rustdeskMsi -replace '\.msi$', '.exe')"
|
||||
if (-not (Test-Path $rustdeskExe)) {
|
||||
Write-Host "Searching for RustDesk exe in Program Files..."
|
||||
$found = Get-ChildItem 'C:\Program Files' -Recurse -Filter '*.exe' -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Name -match 'rustdesk|scoutit|remotesupport' } |
|
||||
Select-Object -First 1
|
||||
if ($found) {
|
||||
$rustdeskExe = $found.FullName
|
||||
Write-Host "Found exe at: $rustdeskExe"
|
||||
} else {
|
||||
Write-Error "Could not locate RustDesk exe after install."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
$exeDir = Split-Path $rustdeskExe
|
||||
|
||||
# ── Install service if not present ────────────────────────────────────────────
|
||||
$svc = Get-Service -Name $rustdeskService -ErrorAction SilentlyContinue
|
||||
if ($null -eq $svc) {
|
||||
Write-Host "Registering ScoutIT Remote Support service..."
|
||||
Start-Process -FilePath $rustdeskExe -ArgumentList '--install-service' -Wait
|
||||
Start-Sleep -Seconds 20
|
||||
$svc = Get-Service -Name $rustdeskService -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# ── Ensure service is running ─────────────────────────────────────────────────
|
||||
if ($null -ne $svc) {
|
||||
$attempts = 0
|
||||
while ($svc.Status -ne 'Running' -and $attempts -lt 5) {
|
||||
Write-Host "Starting ScoutIT Remote Support service (attempt $($attempts + 1))..."
|
||||
Start-Service -Name $rustdeskService -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 5
|
||||
$svc.Refresh()
|
||||
$attempts++
|
||||
}
|
||||
if ($svc.Status -eq 'Running') {
|
||||
Write-Host "ScoutIT Remote Support service is running."
|
||||
} else {
|
||||
Write-Warning "Service did not reach Running state after $attempts attempts."
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Service '$rustdeskService' not found after install."
|
||||
}
|
||||
|
||||
# ── Output RustDesk ID ────────────────────────────────────────────────────────
|
||||
Push-Location $exeDir
|
||||
$rustdeskId = & $rustdeskExe --get-id 2>&1
|
||||
Pop-Location
|
||||
|
||||
Write-Output "................................................."
|
||||
Write-Output "ScoutIT Remote Support ID: $rustdeskId"
|
||||
Write-Output "................................................."
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,109 @@
|
||||
# ScoutIT Remote Support (RustDesk) - Uninstall Script
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
|
||||
# ── Config ────────────────────────────────────────────────────────────────────
|
||||
$rustdeskInstallDir = 'C:\Program Files\ScoutIT-RemoteSupport'
|
||||
$rustdeskService = 'ScoutIT-RemoteSupport'
|
||||
$rustdeskMsiName = 'estudio-scoutit-remotesupport' # used to find uninstall key in registry
|
||||
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
Write-Host "Starting ScoutIT Remote Support uninstall..."
|
||||
|
||||
# ── Stop and unregister the service ──────────────────────────────────────────
|
||||
$svc = Get-Service -Name $rustdeskService -ErrorAction SilentlyContinue
|
||||
if ($null -ne $svc) {
|
||||
Write-Host "Stopping ScoutIT Remote Support service..."
|
||||
Stop-Service -Name $rustdeskService -Force -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 3
|
||||
|
||||
# Attempt graceful service uninstall via exe first
|
||||
$rustdeskExe = Get-ChildItem $rustdeskInstallDir -Filter '*.exe' -ErrorAction SilentlyContinue |
|
||||
Select-Object -First 1
|
||||
if ($rustdeskExe) {
|
||||
Write-Host "Unregistering service via exe..."
|
||||
Start-Process -FilePath $rustdeskExe.FullName -ArgumentList '--uninstall-service' -Wait
|
||||
Start-Sleep -Seconds 5
|
||||
}
|
||||
} else {
|
||||
Write-Host "Service '$rustdeskService' not found - may already be removed."
|
||||
}
|
||||
|
||||
# ── MSI uninstall via registry ProductCode ───────────────────────────────────
|
||||
Write-Host "Looking for MSI uninstall entry in registry..."
|
||||
$uninstallKeys = @(
|
||||
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
|
||||
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
|
||||
)
|
||||
|
||||
$productCode = $null
|
||||
foreach ($key in $uninstallKeys) {
|
||||
$match = Get-ItemProperty $key -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.DisplayName -match 'scoutit|remotesupport|rustdesk' -or
|
||||
$_.Publisher -match 'scoutit|rustdesk' } |
|
||||
Select-Object -First 1
|
||||
if ($match) {
|
||||
$productCode = $match.PSChildName
|
||||
Write-Host "Found uninstall entry: $($match.DisplayName) [$productCode]"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if ($productCode) {
|
||||
Write-Host "Running MSI uninstall..."
|
||||
Start-Process -FilePath "msiexec.exe" `
|
||||
-ArgumentList "/x `"$productCode`" /qn /norestart" `
|
||||
-Wait
|
||||
Start-Sleep -Seconds 10
|
||||
Write-Host "MSI uninstall complete."
|
||||
} else {
|
||||
Write-Warning "No MSI uninstall entry found in registry. Falling back to manual removal."
|
||||
}
|
||||
|
||||
# ── Kill any remaining processes ─────────────────────────────────────────────
|
||||
Write-Host "Killing any remaining RustDesk processes..."
|
||||
Get-Process | Where-Object { $_.Path -match 'ScoutIT-RemoteSupport|rustdesk|scoutit' } |
|
||||
Stop-Process -Force -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 2
|
||||
|
||||
# ── Remove install directory ──────────────────────────────────────────────────
|
||||
if (Test-Path $rustdeskInstallDir) {
|
||||
Write-Host "Removing install directory: $rustdeskInstallDir"
|
||||
Remove-Item -Path $rustdeskInstallDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
if (Test-Path $rustdeskInstallDir) {
|
||||
Write-Warning "Directory still exists - may have locked files. You may need to reboot and re-run."
|
||||
} else {
|
||||
Write-Host "Install directory removed."
|
||||
}
|
||||
} else {
|
||||
Write-Host "Install directory not found - already removed."
|
||||
}
|
||||
|
||||
# ── Remove leftover AppData / config ─────────────────────────────────────────
|
||||
$appDataPaths = @(
|
||||
"$env:APPDATA\ScoutIT-RemoteSupport",
|
||||
"$env:APPDATA\RustDesk",
|
||||
"$env:ProgramData\ScoutIT-RemoteSupport",
|
||||
"$env:ProgramData\RustDesk"
|
||||
)
|
||||
foreach ($path in $appDataPaths) {
|
||||
if (Test-Path $path) {
|
||||
Write-Host "Removing: $path"
|
||||
Remove-Item -Path $path -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
# ── Confirm ───────────────────────────────────────────────────────────────────
|
||||
$svcFinal = Get-Service -Name $rustdeskService -ErrorAction SilentlyContinue
|
||||
$dirFinal = Test-Path $rustdeskInstallDir
|
||||
|
||||
Write-Output "................................................."
|
||||
if ($null -eq $svcFinal -and -not $dirFinal) {
|
||||
Write-Output "ScoutIT Remote Support successfully uninstalled."
|
||||
} else {
|
||||
if ($null -ne $svcFinal) { Write-Warning "Service '$rustdeskService' still present." }
|
||||
if ($dirFinal) { Write-Warning "Install directory still present - reboot may be required." }
|
||||
}
|
||||
Write-Output "................................................."
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user