🎬 Intro: Autopilot Your Vibes with PowerShell
Let’s be real. Restarting OBS and pressing stream every few hours is ✨a vibe killer✨. Whether you’re running a lo-fi chill zone, a silent productivity stream, or a 24/7 AI art showcase, doing it all manually is… very last season. 😤
Enter: my PowerShell-powered automation squad that’ll stop crashes, relaunch OBS, switch up scenes, and start streaming on its own. Yup — no hands, just vibes. 🌈🧠
In this post, I’ll walk you through a set of easy-to-customize PowerShell scripts that give your OBS setup a serious glow-up.
🧠 Code Files (With Copy Buttons)
There are four main files. Each one has a job, like your own little dev dream team. Copy-paste each one below into a file with the matching name.
1. restart_and_start_stream.ps1
This is your main launcher script. It checks if OBS is already running, closes it gracefully, clears crash logs, reopens it, and then uses a hotkey simulation to start the stream. Perfect for recovery after crashes or auto reboots.
# restart_and_start_stream.ps1
# Auto-elevate, kill OBS if needed, clean crash files, launch OBS, send hotkey
# === Config ===
$OBSPath = ""
$OBSWindowTitle = ""
$HotkeyCombination = '^%+S'
$OBSLaunchDelay = 5
$StopDelaySeconds = 3
$LogFile = ""
Function Log {
param([string]$message)
$timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
$logEntry = "$timestamp | $message"
Add-Content -Path $LogFile -Value $logEntry
Write-Output $logEntry
}
# === Restart OBS ===
Get-Process obs64 -ErrorAction SilentlyContinue | ForEach-Object {
$_.CloseMainWindow()
$_.WaitForExit(5000)
}
Remove-Item "$env:APPDATA\\obs-studio\\crashes\\*" -Force -Recurse -ErrorAction SilentlyContinue
if (-not (Get-Process obs64 -ErrorAction SilentlyContinue)) {
Start-Process -FilePath $OBSPath
Start-Sleep -Seconds $OBSLaunchDelay
}
# === Simulate Hotkey via VBScript ===
$vbscript = @"
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.AppActivate "$OBSWindowTitle"
WScript.Sleep 1000
WshShell.SendKeys "$HotkeyCombination"
"@
$vbpath = "$env:TEMP\\start_obs_hotkey.vbs"
$vbscript | Out-File -FilePath $vbpath -Encoding ASCII
Start-Process "wscript.exe" -ArgumentList "`"$vbpath`""
2. restart_stream.ps1
This script is a smarter version that uses OBS WebSocket API. It sends actual JSON requests to stop your current stream, relaunch OBS, select a random scene (if you want), and kick off the livestream with all settings in place.
# restart_stream.ps1
Import-Module "\\obs_control.psm1"
. "\\config.ps1"
Function Log {
param([string]$message)
$timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
Add-Content -Path $LogFile -Value "$timestamp | $message"
Write-Output "$timestamp | $message"
}
# Stop stream via WebSocket
$response = Invoke-OBSWebSocketRequest -Uri $OBSWebSocketHost -RequestType "StopStream"
# Gracefully close OBS
Get-Process obs64 -ErrorAction SilentlyContinue | ForEach-Object {
$_.CloseMainWindow()
$_.WaitForExit(5000)
}
# Relaunch OBS
if (-not (Get-Process obs64 -ErrorAction SilentlyContinue)) {
Start-Process -FilePath $OBSPath
Start-Sleep -Seconds $OBSLaunchDelay
}
# Pick scene
$selectedScene = if ($RandomizeScene) { Get-Random -InputObject $Scenes } else { $Scenes[0] }
Invoke-OBSWebSocketRequest -Uri $OBSWebSocketHost -RequestType "SetCurrentProgramScene" -RequestData @{sceneName=$selectedScene}
# Set profile and scene collection
Invoke-OBSWebSocketRequest -Uri $OBSWebSocketHost -RequestType "SetCurrentProfile" -RequestData @{profileName=$ProfileName}
Invoke-OBSWebSocketRequest -Uri $OBSWebSocketHost -RequestType "SetCurrentSceneCollection" -RequestData @{sceneCollectionName=$SceneCollection}
# Stream config
Invoke-OBSWebSocketRequest -Uri $OBSWebSocketHost -RequestType "SetStreamServiceSettings" -RequestData @{
streamServiceType = "rtmp_custom"
streamServiceSettings = @{
server = $YouTubePrimary
key = $StreamKey
}
}
# Start stream
Invoke-OBSWebSocketRequest -Uri $OBSWebSocketHost -RequestType "StartStream"
3. config.ps1
This is your customizable config file. You put all your editable settings here — paths, WebSocket host, stream key, profile names, scenes, and delays.
# config.ps1
$OBSPath = ""
$OBSWebSocketHost = "ws://localhost:4455"
$StreamKey = ""
$YouTubePrimary = "rtmp://yourstream.rtmp.server"
$Scenes = @("Scene1", "Scene2")
$RandomizeScene = $true
$ProfileName = "YouTube"
$SceneCollection = "Default"
$OBSLaunchDelay = 5
$StopDelaySeconds = 3
$LogFile = ""
$OBSWindowTitle = "OBS 31.0.3"
4. obs_control.psm1
This PowerShell module sends WebSocket commands to OBS. Think of it as your “talk to OBS” translator — it handles sending/receiving JSON requests.
# obs_control.psm1
Function Invoke-OBSWebSocketRequest {
param(
[string]$Uri,
[string]$RequestType,
[hashtable]$RequestData = @{}
)
$Payload = @{
op = 6
d = @{
requestType = $RequestType
requestId = [guid]::NewGuid().ToString()
requestData = $RequestData
}
} | ConvertTo-Json -Depth 10
try {
$WS = [System.Net.WebSockets.ClientWebSocket]::new()
$WS.ConnectAsync($Uri, [Threading.CancellationToken]::None).Wait()
$Bytes = [System.Text.Encoding]::UTF8.GetBytes($Payload)
$WS.SendAsync([System.ArraySegment[byte]]::new($Bytes), [System.Net.WebSockets.WebSocketMessageType]::Text, $true, [Threading.CancellationToken]::None).Wait()
$RecvBuffer = New-Object byte[] 8192
$Result = $WS.ReceiveAsync([System.ArraySegment[byte]]::new($RecvBuffer), [Threading.CancellationToken]::None).Result
$Response = [System.Text.Encoding]::UTF8.GetString($RecvBuffer, 0, $Result.Count)
$WS.Dispose()
return $Response | ConvertFrom-Json
} catch {
Write-Error "WebSocket Error: $_"
}
}
Export-ModuleMember -Function Invoke-OBSWebSocketRequest
🪄 Recap & Real-World Vibes
Once you’ve dropped these four files into place and customized your config, your OBS stream becomes self-aware. It’ll restart, clean up, randomize scenes, and vibe on command. 🚀
Want to run it every morning? Hook restart_and_start_stream.ps1
into Task Scheduler. Crash recovery? Run restart_stream.ps1
on failure. It’s flexible, aesthetic, and 100% hands-free.
Have questions or want to flex your version? Drop a comment, smash that share button, and show off your automated stream setup to the squad.