Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <#!
- .SYNOPSIS
- Connects to a Linux computer in RustDesk and reconnects after its graphical-login handoff.
- .DESCRIPTION
- RustDesk may initially connect to a LightDM (or similar) login screen. When the
- user signs in, the remote RustDesk server can be replaced by the per-user server.
- Its built-in retry can occur before that replacement server is ready.
- This wrapper opens the normal RustDesk connection, watches the remote machine's
- loginctl sessions over key-based SSH, and issues one fresh RustDesk connection
- after the requested user becomes active on the specified graphical seat.
- .NOTES
- Requires Windows PowerShell 5.1 or later, RustDesk, OpenSSH's ssh.exe, and
- non-interactive/key-based SSH access to the remote machine.
- #>
- [CmdletBinding()]
- param(
- # RustDesk ID, relay address, or direct address such as 192.168.1.25:21118.
- [Parameter(Mandatory = $true)]
- [ValidateNotNullOrEmpty()]
- [string]$RustDeskTarget,
- # An SSH host alias, hostname, or user@hostname accepted by ssh.exe.
- [Parameter(Mandatory = $true)]
- [ValidateNotNullOrEmpty()]
- [string]$SshTarget,
- # Defaults to the current Windows username, normalised for typical Linux use.
- [ValidateNotNullOrEmpty()]
- [string]$SessionUser = $(if ($env:USERNAME) { $env:USERNAME.ToLowerInvariant() } else { '' }),
- [ValidateNotNullOrEmpty()]
- [string]$Seat = 'seat0',
- [ValidateScript({ Test-Path -LiteralPath $_ -PathType Leaf })]
- [string]$RustDeskPath = (Join-Path $env:ProgramFiles 'RustDesk\RustDesk.exe'),
- [ValidateRange(30, 900)]
- [int]$LoginWatchWindowSeconds = 300,
- [ValidateRange(1, 30)]
- [int]$PollIntervalSeconds = 3,
- [ValidateRange(1, 60)]
- [int]$SessionStartupGraceSeconds = 7,
- # Optional plain-text diagnostic log path. It contains timestamps only.
- [string]$LogPath
- )
- $sshCommand = Get-Command ssh.exe -ErrorAction Stop
- $seatPattern = '^\s*\S+\s+\d+\s+' + [regex]::Escape($SessionUser) + '\s+' + [regex]::Escape($Seat) + '\s'
- function Write-ConnectionLog {
- param([Parameter(Mandatory = $true)][string]$Message)
- if (-not $LogPath) {
- return
- }
- try {
- Add-Content -LiteralPath $LogPath -Value ('{0:yyyy-MM-dd HH:mm:ss} {1}' -f (Get-Date), $Message)
- }
- catch {
- # Logging is diagnostic only and must not prevent a remote connection.
- }
- }
- function Test-RemoteDesktopSession {
- # SSH-created sessions have no seat. A graphical Linux desktop session is
- # explicitly associated with a seat, normally seat0.
- $sessions = & $sshCommand.Source -o BatchMode=yes -o ConnectTimeout=3 -o LogLevel=ERROR $SshTarget 'loginctl list-sessions --no-legend' 2>$null
- $matchingSessions = @($sessions | Where-Object { $_ -match $seatPattern })
- return ($LASTEXITCODE -eq 0 -and $matchingSessions.Count -gt 0)
- }
- function Start-RustDeskConnection {
- Start-Process -FilePath $RustDeskPath -ArgumentList "--connect $RustDeskTarget"
- }
- $wasOnDesktop = Test-RemoteDesktopSession
- $deadline = [DateTime]::UtcNow.AddSeconds($LoginWatchWindowSeconds)
- $reconnectIssued = $false
- Write-ConnectionLog "Opened initial connection to $RustDeskTarget; waiting for $SessionUser on $Seat."
- Start-RustDeskConnection
- # A connection made while the desktop is already signed in does not cross the
- # display-manager-to-user-session boundary. The initial RustDesk connection is
- # already the right one, so exit instead of keeping a watcher alive.
- if ($wasOnDesktop) {
- Write-ConnectionLog "$SessionUser was already active on $Seat; no post-login reconnection is needed."
- return
- }
- while ([DateTime]::UtcNow -lt $deadline) {
- $isOnDesktop = Test-RemoteDesktopSession
- if (-not $wasOnDesktop -and $isOnDesktop) {
- Write-ConnectionLog "Detected $SessionUser on $Seat; waiting $SessionStartupGraceSeconds seconds for the user-session RustDesk server."
- Start-Sleep -Seconds $SessionStartupGraceSeconds
- Start-RustDeskConnection
- Write-ConnectionLog 'Issued post-login RustDesk reconnection.'
- $reconnectIssued = $true
- break
- }
- $wasOnDesktop = $isOnDesktop
- Start-Sleep -Seconds $PollIntervalSeconds
- }
- if (-not $reconnectIssued) {
- Write-ConnectionLog 'Stopped watching without detecting a new graphical-session login.'
- }
Add Comment
Please, Sign In to add comment