Update pve RustDesk GA sync scripts

This commit is contained in:
alexveley
2026-06-24 02:12:21 -04:00
parent f47915dadf
commit f0987e855a
+31 -66
View File
@@ -1,6 +1,5 @@
#!/bin/bash #!/bin/bash
# Poll RustDesk IDs via QEMU guest agent; update Proxmox VM notes + registry.json. # Reads RustDesk peer ID via GA exec (rustdesk --get-id). Modern RustDesk stores enc_id in TOML, not plain id.
# Canonical Blair fleet sync — no per-VM scheduled tasks or share reports required.
# Install: /usr/local/sbin/blair-sync-rustdesk-via-ga.sh Cron: every 2 minutes. # Install: /usr/local/sbin/blair-sync-rustdesk-via-ga.sh Cron: every 2 minutes.
# Usage: blair-sync-rustdesk-via-ga.sh [--dry-run] BLAIR_VERBOSE=1 for detail. # Usage: blair-sync-rustdesk-via-ga.sh [--dry-run] BLAIR_VERBOSE=1 for detail.
set -euo pipefail set -euo pipefail
@@ -30,50 +29,9 @@ DRY_RUN = os.environ.get('BLAIR_DRY_RUN', '') in ('1', 'true', 'yes')
VERBOSE = os.environ.get('BLAIR_VERBOSE', '') in ('1', 'true', 'yes') VERBOSE = os.environ.get('BLAIR_VERBOSE', '') in ('1', 'true', 'yes')
VMIDS_ENV = os.environ.get('BLAIR_VMIDS', '').strip() VMIDS_ENV = os.environ.get('BLAIR_VMIDS', '').strip()
# RustDesk2.toml (LocalService) is the source of truth on Windows seats. # RustDesk >=1.2 stores enc_id in TOML, not plain id. Primary: rustdesk.exe --get-id via GA exec.
GUEST_READ_PATHS = [ RUSTDESK_EXE = r'C:\Program Files\RustDesk\rustdesk.exe'
r'C:\Windows\ServiceProfiles\LocalService\AppData\Roaming\RustDesk\config\RustDesk2.toml', GUEST_REPORT = r'C:\ProgramData\Blair\rustdesk-report.json'
r'C:\Windows\ServiceProfiles\LocalService\AppData\Roaming\RustDesk\config\RustDesk.toml',
r'C:\Windows\System32\config\systemprofile\AppData\Roaming\RustDesk\config\RustDesk2.toml',
r'C:\ProgramData\RustDesk\config\RustDesk2.toml',
r'C:\ProgramData\Blair\rustdesk-report.json',
]
PS_READ_ID = r'''
$ProgressPreference = 'SilentlyContinue'
$ErrorActionPreference = 'SilentlyContinue'
$paths = @(
'C:\Windows\ServiceProfiles\LocalService\AppData\Roaming\RustDesk\config\RustDesk2.toml',
'C:\Windows\ServiceProfiles\LocalService\AppData\Roaming\RustDesk\config\RustDesk.toml',
'C:\Windows\System32\config\systemprofile\AppData\Roaming\RustDesk\config\RustDesk2.toml',
'C:\ProgramData\RustDesk\config\RustDesk2.toml',
'C:\ProgramData\Blair\rustdesk-report.json'
)
foreach ($p in $paths) {
if (-not (Test-Path -LiteralPath $p)) { continue }
$t = Get-Content -Raw -LiteralPath $p
if ($p -like '*.json') {
try {
$j = $t | ConvertFrom-Json
if ($j.rustdesk_id -match '^\d{6,12}$') { Write-Output $j.rustdesk_id; exit 0 }
} catch {}
}
if ($t -match '(?m)^\s*id\s*=\s*[''"]?(\d{6,12})') { Write-Output $Matches[1]; exit 0 }
}
foreach ($rp in @(
'HKLM:\SOFTWARE\RustDesk\Host',
'HKLM:\SOFTWARE\RustDesk',
'HKLM:\SOFTWARE\WOW6432Node\RustDesk\Host',
'HKLM:\SOFTWARE\WOW6432Node\RustDesk'
)) {
if (-not (Test-Path $rp)) { continue }
foreach ($n in @('id', 'Id', 'rustdesk_id', 'peer_id')) {
$v = (Get-ItemProperty -Path $rp -Name $n -ErrorAction SilentlyContinue).$n
if ($v -match '^\d{6,12}$') { Write-Output $v; exit 0 }
}
}
exit 1
'''
def log(msg: str, *, force: bool = False) -> None: def log(msg: str, *, force: bool = False) -> None:
@@ -263,30 +221,37 @@ def guest_file_read(vmid: int, guest_path: str) -> tuple[str | None, str | None]
return None, f'file-read failed for {guest_path}' return None, f'file-read failed for {guest_path}'
def read_rustdesk_id(vmid: int) -> tuple[str | None, str | None]: def read_rustdesk_id_cli(vmid: int) -> tuple[str | None, str | None]:
for path in GUEST_READ_PATHS:
try:
text, err = guest_file_read(vmid, path)
if not text:
log(f'VM {vmid}: file-read miss {path}: {err}')
continue
rid = parse_id_from_content(text, path)
if rid:
log(f'VM {vmid}: ID {rid} from {path}')
return rid, None
log(f'VM {vmid}: no id in {path}')
except Exception as exc: # noqa: BLE001
log(f'VM {vmid}: {path}: {exc}')
enc = base64.b64encode(PS_READ_ID.strip().encode('utf-16-le')).decode('ascii')
rid, err = guest_exec_text( rid, err = guest_exec_text(
vmid, vmid,
['powershell.exe', '-NoProfile', '-NonInteractive', '-EncodedCommand', enc], ['cmd.exe', '/c', f'"{RUSTDESK_EXE}" --get-id'],
timeout=120, timeout=45,
) )
if rid: if rid and re.fullmatch(r'\d{6,12}', rid):
log(f'VM {vmid}: ID {rid} from guest exec')
return rid, None return rid, None
return None, err or 'rustdesk --get-id returned no id'
def read_rustdesk_id_report(vmid: int) -> tuple[str | None, str | None]:
text, err = guest_file_read(vmid, GUEST_REPORT)
if not text:
return None, err
rid = parse_id_from_content(text, GUEST_REPORT)
return (rid, None) if rid else (None, 'no rustdesk_id in report json')
def read_rustdesk_id(vmid: int) -> tuple[str | None, str | None]:
rid, err = read_rustdesk_id_cli(vmid)
if rid:
log(f'VM {vmid}: ID {rid} from rustdesk --get-id')
return rid, None
log(f'VM {vmid}: cli miss: {err}')
rid, err = read_rustdesk_id_report(vmid)
if rid:
log(f'VM {vmid}: ID {rid} from {GUEST_REPORT}')
return rid, None
return None, err or 'no RustDesk ID found' return None, err or 'no RustDesk ID found'