Bitfocus Companion for OBSBOT Cameras & Rodecaster Video Switcher CIS - Video Podcast Studio (Park413R) — Re-Deployment Guide (Windows 11)

Bitfocus Companion, VICREO Listener for OBSBOT Cameras & Rodecaster Video Switcher CIS - Video Podcast Studio (Park413R) — Re-Deployment Guide (Windows 11)

Use this after an OS wipe or PC replacement to restore a the Video Podcasting Studio PC that auto-launches Companion, VICREO and controls three OBSBOT Tail 2 cameras over a dedicated 192.168.2.0/24 subnet via a secondary USB-to-Ethernet adapter.

 


What this sets up

  • Companion v4.1.x auto-starts for all users.

  • VICREO Listener runs from a shared path and starts minimized for every user (inherits “Start Minimized”).

  • Companion config (your record/stop toggle) is restored for all existing users + Default profile.

  • ASIX USB NIC is set to 192.168.2.50/24 (no gateway) so your .2 devices stay reachable.

  • Companion → VICREO uses 127.0.0.1:10001 and works for admin + non-admin.


Prereqs (once per machine)

  • Install Companion Desktop (Win64) normally.

  • Place VICREO-Listener.exe at: C:\Tools\vicreo_listener\VICREO-Listener.exe

  • Export your working Companion config to: C:\Tools\record_toggle_vicreo_localhost.companionconfig

  • On one profile, right-click VICREO tray → Click to Start Minimized → close VICREO (this writes the setting).

  • Confirm that file exists:
    C:\Users\<your-admin>\AppData\Roaming\VICREO-Listener\config.json (contains the minimized setting).


One-shot Redeploy Script (run elevated PowerShell)

Update the three paths at the top only if different.

# ===== EDIT IF NEEDED =====
$CompanionExe = "C:\Program Files\Companion\Companion.exe"
$GoldenConfig = "C:\Tools\record_toggle_vicreo_localhost.companionconfig"
$VicreoShared = "C:\Tools\vicreo_listener\VICREO-Listener.exe"
$AdminVicreoCfgFolder = "C:\Users\it-coffm1pc\AppData\Roaming\VICREO-Listener"  # has config.json with Start Minimized
$UsbNicFallbackAlias = "Ethernet 2"
$VicreoPort = 10001
# ==========================

# Helpers
function Copy-Mirror($src,$dst){ New-Item -ItemType Directory -Force -Path $dst | Out-Null; robocopy $src $dst /MIR /R:1 /W:1 /NFL /NDL | Out-Null }

Write-Host "=== Kiosk Redeploy ===" -ForegroundColor Cyan

# 0) Sanity
if (!(Test-Path $CompanionExe)) { throw "Companion not found: $CompanionExe" }
if (!(Test-Path $GoldenConfig)) { throw "Companion config not found: $GoldenConfig" }
if (!(Test-Path $VicreoShared)) { throw "VICREO not found: $VicreoShared" }
if (!(Test-Path $AdminVicreoCfgFolder)) { throw "Admin VICREO config not found: $AdminVicreoCfgFolder" }

# 1) Network (.2 NIC)
$UsbNic = Get-NetAdapter | ? { $_.InterfaceDescription -like "*ASIX*USB*Gigabit*" } | Sort-Object Status -Descending | Select -First 1
$UsbNicAlias = if ($UsbNic) { $UsbNic.Name } else { $UsbNicFallbackAlias }
Write-Host "[1/6] Configure ASIX '$UsbNicAlias' to 192.168.2.50/24 (no gateway)..." -ForegroundColor Cyan
try{
  Get-NetIPAddress -InterfaceAlias $UsbNicAlias -AddressFamily IPv4 -ErrorAction SilentlyContinue |
    ? { $_.IPAddress -ne '127.0.0.1' } | Remove-NetIPAddress -Confirm:$false -ErrorAction SilentlyContinue
  Set-NetIPInterface -InterfaceAlias $UsbNicAlias -Dhcp Disabled -ErrorAction SilentlyContinue
  New-NetIPAddress -InterfaceAlias $UsbNicAlias -IPAddress 192.168.2.50 -PrefixLength 24 -ErrorAction Stop
  Set-DnsClientServerAddress -InterfaceAlias $UsbNicAlias -ResetServerAddresses -ErrorAction SilentlyContinue
  (Get-NetConnectionProfile -InterfaceAlias $UsbNicAlias) | Set-NetConnectionProfile -NetworkCategory Private
  Set-NetIPInterface -InterfaceAlias $UsbNicAlias -InterfaceMetric 50 -ErrorAction SilentlyContinue
} catch { Write-Host "  NIC warning: $($_.Exception.Message)" -ForegroundColor Yellow }

# 2) Companion autostart + firewall
Write-Host "[2/6] Companion autostart & firewall..." -ForegroundColor Cyan
Get-Process Companion -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
New-Item "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" -Force | Out-Null
Remove-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "Companion" -ErrorAction SilentlyContinue
Set-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "Bitfocus Companion" -Value ("`"$CompanionExe`"")
if (-not (Get-NetFirewallRule -DisplayName "Companion Inbound" -ErrorAction SilentlyContinue)) {
  New-NetFirewallRule -DisplayName "Companion Inbound" -Program $CompanionExe -Direction Inbound -Action Allow -Profile Domain,Private | Out-Null
}

# 3) VICREO: propagate Start Minimized to Default + all users
Write-Host "[3/6] Propagate VICREO 'Start Minimized'..." -ForegroundColor Cyan
$DefaultVicreo = "C:\Users\Default\AppData\Roaming\VICREO-Listener"
Copy-Mirror $AdminVicreoCfgFolder $DefaultVicreo
$exclude = 'Public','Default','Default User','All Users','WDAGUtilityAccount'
Get-ChildItem C:\Users -Directory | ? { $exclude -notcontains $_.Name } | % {
  $dest = "C:\Users\$($_.Name)\AppData\Roaming\VICREO-Listener"
  Copy-Mirror $AdminVicreoCfgFolder $dest
}

# 4) All Users Startup: call hidden/minimized launcher
Write-Host "[4/6] All Users Startup for VICREO (hidden)..." -ForegroundColor Cyan
$SharedDir = Split-Path $VicreoShared
$PsHider = Join-Path $SharedDir "Start_VICREO_Hidden.ps1"
$CmdHider= Join-Path $SharedDir "Start_VICREO_Hidden.cmd"
Set-Content -Path $PsHider -Encoding UTF8 -Value @"
Get-Process -Name "VICREO-Listener" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
$proc = Start-Process -FilePath '$VicreoShared' -WindowStyle Minimized -PassThru
Start-Sleep -Milliseconds 400
Add-Type @"
using System;
using System.Runtime.InteropServices;
public static class Win {
  public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
  [DllImport("user32.dll")] public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
  [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
  [DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr hWnd);
  [DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
}
"@
\$SW_HIDE = 0
\$targetPid = [uint32]\$proc.Id
for (\$i=0; \$i -lt 60; \$i++) {
  try { \$null = Get-Process -Id \$proc.Id -ErrorAction Stop } catch { break }
  \$script:hiddenAny = \$false
  \$cb = [Win+EnumWindowsProc]{
    param([IntPtr] \$hWnd, [IntPtr] \$lParam)
    if (-not [Win]::IsWindowVisible(\$hWnd)) { return \$true }
    [uint32]\$ownerPid = 0
    [void][Win]::GetWindowThreadProcessId(\$hWnd, [ref]\$ownerPid)
    if (\$ownerPid -eq \$targetPid) {
      [void][Win]::ShowWindowAsync(\$hWnd, \$SW_HIDE)
      \$script:hiddenAny = \$true
    }
    return \$true
  }
  [void][Win]::EnumWindows(\$cb, [IntPtr]::Zero)
  if (\$hiddenAny) { break }
  Start-Sleep -Milliseconds 200
}
"@
Set-Content -Path $CmdHider -Encoding ASCII -Value @"
@echo off
powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "$PsHider"
exit /b 0
"@
$StartupAll = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"
New-Item -ItemType Directory -Force -Path $StartupAll | Out-Null
# Shortcut to run minimized
$lnk = Join-Path $StartupAll "VICREO Listener (Hidden).lnk"
$wsh = New-Object -ComObject WScript.Shell
$s = $wsh.CreateShortcut($lnk)
$s.TargetPath = "C:\Windows\System32\cmd.exe"
$s.Arguments  = "/c `"$CmdHider`""
$s.WorkingDirectory = $SharedDir
$s.WindowStyle = 7
$s.IconLocation = "$VicreoShared,0"
$s.Save()

# 5) Restore Companion config to all existing users + Default
Write-Host "[5/6] Restore Companion config to users + Default..." -ForegroundColor Cyan
Get-Process Companion -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
# Existing users
Get-ChildItem C:\Users -Directory | ? { $exclude -notcontains $_.Name } | % {
  $data = "C:\Users\$($_.Name)\AppData\Roaming\companion\v4.1"
  New-Item -ItemType Directory -Force -Path $data | Out-Null
  Start-Process -FilePath $CompanionExe -ArgumentList @("--data `"$data`"", "--restore `"$GoldenConfig`"") -Wait -WindowStyle Hidden
}
# Default profile
$defData = "C:\Users\Default\AppData\Roaming\companion\v4.1"
New-Item -ItemType Directory -Force -Path $defData | Out-Null
Start-Process -FilePath $CompanionExe -ArgumentList @("--data `"$defData`"", "--restore `"$GoldenConfig`"") -Wait -WindowStyle Hidden

# 6) Kick Companion; quick checks
Write-Host "[6/6] Launch Companion & checks..." -ForegroundColor Cyan
Start-Process -FilePath $CompanionExe -WindowStyle Minimized
$probe = Test-NetConnection 127.0.0.1 -Port $VicreoPort
Write-Host ("VICREO 127.0.0.1:{0} listening now/soon: {1}" -f $VicreoPort, ($probe.TcpTestSucceeded -as [string])) -ForegroundColor Green

Write-Host "`nDone. Sign out/in with a non-admin to verify:" -ForegroundColor Cyan
Write-Host " - VICREO starts minimized/hidden (tray only)" -ForegroundColor Green
Write-Host " - Companion shows VICREO green" -ForegroundColor Green
Write-Host " - Record/Stop works globally (F8/F10) with Panopto in background" -ForegroundColor Green


After running — Validation Checklist

  1. Non-admin login:

    • VICREO starts minimized/hidden (no big window).

    • Companion → Connections → VICREO shows green.

    • Your button steps still target VICREO → Single Key F8/F10.

  2. Panopto in background: F8 = record, F10 = stop.

  3. New user test: Create a fresh local/domain user → on first login, VICREO is minimized and Companion loads your layout.


Notes / Gotchas

  • If a user ever shows a VICREO window, it’s usually because they have a custom Startup entry pointing to the EXE directly. Remove it so the All Users shortcut + PS hider is the only launcher.

  • If you ever update VICREO settings (port/secret), re-copy the Roaming\VICREO-Listener folder from your “golden” profile to everyone (and to C:\Users\Default\…).

  • Keep your Companion config export up to date (C:\Tools\record_toggle_vicreo_localhost.companionconfig) and rerun the script after changes.