From 117a80023e01ec9fb137122f7226994534cb0363 Mon Sep 17 00:00:00 2001 From: christian Date: Thu, 8 Oct 2026 11:16:41 -0400 Subject: [PATCH] Add one-time remote access setup for the Macs and Windows PCs. mac-authorize.sh is a one-liner for Apple Remote Desktop's Send UNIX Command: it authorizes NA Ingest's status-panel key for the logged-in user and prints the account name. windows-setup.ps1 turns on Windows' OpenSSH server, authorizes the same key, creates desktop start tasks for OBS, Arena, rtpMIDI and the Bible app, and enables Wake-on-LAN where the adapter allows it. Co-Authored-By: Claude Opus 5.5 --- remote-access/mac-authorize.sh | 5 ++ remote-access/windows-setup.ps1 | 85 +++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 remote-access/mac-authorize.sh create mode 100644 remote-access/windows-setup.ps1 diff --git a/remote-access/mac-authorize.sh b/remote-access/mac-authorize.sh new file mode 100644 index 0000000..aac570c --- /dev/null +++ b/remote-access/mac-authorize.sh @@ -0,0 +1,5 @@ +# Paste this into Apple Remote Desktop: select the Macs -> Manage -> Send UNIX Command, +# "Run command as: current user", then Send. It lets NA Ingest's status panel log in +# with its key (no password), and prints this Mac's account name for the config. +# Safe to run more than once. +H=$(dscl . -read "/Users/$(whoami)" NFSHomeDirectory | awk '{print $2}'); mkdir -p "$H/.ssh" && chmod 700 "$H/.ssh" && touch "$H/.ssh/authorized_keys" && chmod 600 "$H/.ssh/authorized_keys" && (grep -q 'status-panel@NA-Ingest' "$H/.ssh/authorized_keys" || echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHM2BPUpVpbMxKumLayVSutUsFWUXEfJ/4vxIJ0thbgY status-panel@NA-Ingest' >> "$H/.ssh/authorized_keys") && echo "OK user=$(whoami) mac=$(scutil --get ComputerName) ssh-group=$(dseditgroup -o checkmember -m "$(whoami)" com.apple.access_ssh 2>/dev/null | cut -d' ' -f1 || echo none)" diff --git a/remote-access/windows-setup.ps1 b/remote-access/windows-setup.ps1 new file mode 100644 index 0000000..7addead --- /dev/null +++ b/remote-access/windows-setup.ps1 @@ -0,0 +1,85 @@ +# Status panel remote access for NA Ingest - run ONCE on each Windows PC +# (OBS PC, Lighting PC, Bible TV PC), logged in as the normal user. +# +# 1. Start menu -> type PowerShell -> right-click -> Run as administrator +# 2. Paste this whole file and press Enter +# 3. Send the "RESULT" block it prints back to Claude +# +# It turns on Windows' built-in SSH server, lets NA Ingest log in with its key +# (no password), and creates "start" tasks for the apps it finds (OBS, Resolume +# Arena, rtpMIDI, the Bible app). The tasks start the app on this desktop, which +# a plain SSH command cannot do on Windows. Safe to run more than once. + +$ErrorActionPreference = 'Stop' +$Key = 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHM2BPUpVpbMxKumLayVSutUsFWUXEfJ/4vxIJ0thbgY status-panel@NA-Ingest' +$notes = @() + +# 1. OpenSSH Server, started now and at every boot, allowed through the firewall +$cap = Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Server*' | Select-Object -First 1 +if ($cap.State -ne 'Installed') { Add-WindowsCapability -Online -Name $cap.Name | Out-Null } +Set-Service -Name sshd -StartupType Automatic +Start-Service sshd +if (-not (Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -ErrorAction SilentlyContinue)) { + New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True ` + -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 | Out-Null +} +Enable-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' + +# 2. NA Ingest's key. Administrators read C:\ProgramData\ssh\administrators_authorized_keys, +# everyone else their own .ssh\authorized_keys - write both. +$adminKeys = Join-Path $env:ProgramData 'ssh\administrators_authorized_keys' +if (-not (Test-Path $adminKeys) -or -not (Select-String -Path $adminKeys -SimpleMatch 'status-panel@NA-Ingest' -Quiet)) { + Add-Content -Path $adminKeys -Value $Key -Encoding ascii +} +icacls $adminKeys /inheritance:r /grant '*S-1-5-32-544:F' /grant '*S-1-5-18:F' | Out-Null +$userSsh = Join-Path $env:USERPROFILE '.ssh' +New-Item -ItemType Directory -Force -Path $userSsh | Out-Null +$userKeys = Join-Path $userSsh 'authorized_keys' +if (-not (Test-Path $userKeys) -or -not (Select-String -Path $userKeys -SimpleMatch 'status-panel@NA-Ingest' -Quiet)) { + Add-Content -Path $userKeys -Value $Key -Encoding ascii +} + +# 3. Start tasks for the apps found on this PC (they run on this user's desktop) +function Find-First($candidates) { + foreach ($c in $candidates) { if ($c -and (Test-Path $c)) { return (Resolve-Path $c).Path } } + return $null +} +$roots = @($env:ProgramFiles, ${env:ProgramFiles(x86)}, (Join-Path $env:LOCALAPPDATA 'Programs')) | Where-Object { $_ } +$bible = Get-ChildItem -Path $roots -Filter '*.exe' -Recurse -Depth 3 -ErrorAction SilentlyContinue | + Where-Object { $_.FullName -match 'bible' -and $_.Name -notmatch 'uninst|update|crash|helper' } | + Select-Object -First 1 -ExpandProperty FullName +$apps = @( + @{ Name = 'OBS'; Exe = (Find-First @("$env:ProgramFiles\obs-studio\bin\64bit\obs64.exe")); Args = '--disable-shutdown-check' }, + @{ Name = 'Arena'; Exe = (Find-First (Get-ChildItem "$env:ProgramFiles\Resolume Arena*\Arena.exe" -ErrorAction SilentlyContinue | ForEach-Object FullName)); Args = '' }, + @{ Name = 'rtpMIDI'; Exe = (Find-First @("${env:ProgramFiles(x86)}\Tobias Erichsen\rtpMIDI\rtpMIDI.exe", "$env:ProgramFiles\Tobias Erichsen\rtpMIDI\rtpMIDI.exe")); Args = '' }, + @{ Name = 'BibleApp'; Exe = $bible; Args = '' } +) +$principal = New-ScheduledTaskPrincipal -UserId "$env:USERDOMAIN\$env:USERNAME" -LogonType Interactive -RunLevel Limited +$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries ` + -ExecutionTimeLimit ([TimeSpan]::Zero) -MultipleInstances IgnoreNew +$tasks = @() +foreach ($app in $apps) { + if (-not $app.Exe) { continue } + $actionArgs = @{ Execute = $app.Exe; WorkingDirectory = (Split-Path $app.Exe) } + if ($app.Args) { $actionArgs.Argument = $app.Args } + $action = New-ScheduledTaskAction @actionArgs + Register-ScheduledTask -TaskPath '\StatusPanel\' -TaskName ('Start ' + $app.Name) -Action $action ` + -Principal $principal -Settings $settings -Force | Out-Null + $tasks += ('{0} = {1}' -f $app.Name, $app.Exe) +} + +# 4. Wake-on-LAN: let the wired adapter wake the PC (the BIOS setting must be on too) +$nics = Get-NetAdapter -Physical -ErrorAction SilentlyContinue | Where-Object Status -eq 'Up' +foreach ($nic in $nics) { + try { Set-NetAdapterPowerManagement -Name $nic.Name -WakeOnMagicPacket Enabled -ErrorAction Stop } + catch { $notes += "Wake-on-LAN not settable on $($nic.Name)" } +} + +Write-Host '' +Write-Host '===== RESULT (send this to Claude) =====' +Write-Host ('pc=' + $env:COMPUTERNAME + ' user=' + $env:USERNAME + ' domain=' + $env:USERDOMAIN) +Write-Host ('sshd=' + (Get-Service sshd).Status) +foreach ($nic in $nics) { Write-Host ('nic=' + $nic.Name + ' mac=' + $nic.MacAddress + ' ip=' + ((Get-NetIPAddress -InterfaceIndex $nic.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue).IPAddress -join ',')) } +if ($tasks) { $tasks | ForEach-Object { Write-Host ('task: ' + $_) } } else { Write-Host 'task: none (no known apps found)' } +$notes | ForEach-Object { Write-Host ('note: ' + $_) } +Write-Host '========================================'