Body
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
-
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.
-
Panopto in background: F8 = record, F10 = stop.
-
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.