Removed the DEM file system dependency
This commit is contained in:
68
README.md
68
README.md
@@ -4,23 +4,22 @@ IT support tool that runs OBS Studio's replay buffer silently on VDI sessions, g
|
||||
|
||||
## How It Works
|
||||
|
||||
1. DEM assigns this to targeted users at logon via App Volumes (OBS) + file transfer + logon task
|
||||
2. OBS launches hidden with the replay buffer running — users never see the OBS interface
|
||||
3. A system tray icon appears — right-click → **Save Replay**
|
||||
4. The clip saves to `\\server\ITCaptures\<username>\YYYY-MM-DD_HH-MM-SS.mkv`
|
||||
1. DEM runs `Start-OBSReplayBuffer.ps1` as a logon task
|
||||
2. The script validates all required project files are accessible, then deploys OBS config files to `%APPDATA%\obs-studio\` automatically
|
||||
3. OBS launches hidden with the replay buffer running — users never see the OBS interface
|
||||
4. A system tray icon appears — right-click → **Save Replay**
|
||||
5. The clip saves to `\\server\ITCaptures\<username>\YYYY-MM-DD_HH-MM-SS.mkv`
|
||||
|
||||
## Architecture
|
||||
|
||||
| Component | Role |
|
||||
|---|---|
|
||||
| **App Volumes AppStack** | Delivers OBS Studio to targeted VDI sessions |
|
||||
| **DEM File Transfer** | Drops OBS config files into `%APPDATA%\obs-studio\` at logon |
|
||||
| **DEM Logon Task** | Runs `Start-OBSReplayBuffer.ps1` at logon |
|
||||
| **DEM Logon Task** | Runs `Start-OBSReplayBuffer.ps1` at logon — only DEM task required |
|
||||
| **`config.psd1`** | Central config — UNC path, buffer duration, OBS executable path |
|
||||
| **`Start-OBSReplayBuffer.ps1`** | Creates user capture folder, writes OBS profile, launches OBS + tray icon |
|
||||
| **`Start-OBSReplayBuffer.ps1`** | Validates project files, deploys OBS config, creates user capture folder, writes OBS profile, launches OBS + tray icon |
|
||||
| **`Show-ReplayTray.ps1`** | WinForms system tray icon — right-click menu with Save Replay / Exit |
|
||||
| **`Invoke-ReplaySave.ps1`** | Sends `SaveReplayBuffer` to OBS via WebSocket v5 (built into OBS 28+) |
|
||||
| **`obs-config/`** | OBS profile, scene collection, and WebSocket config delivered by DEM |
|
||||
| **`obs-config/`** | OBS config files — deployed to `%APPDATA%\obs-studio\` at logon by the script |
|
||||
|
||||
## Repository Structure
|
||||
|
||||
@@ -33,9 +32,6 @@ obs-replay-buffer/
|
||||
│ └── Invoke-ReplaySave.ps1
|
||||
└── obs-config/
|
||||
├── global.ini
|
||||
├── profiles/
|
||||
│ └── ITMonitor/
|
||||
│ └── basic.ini
|
||||
├── scenes/
|
||||
│ └── ITMonitor.json
|
||||
└── plugin_config/
|
||||
@@ -45,12 +41,13 @@ obs-replay-buffer/
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **OBS Studio 28+** packaged as an App Volumes AppStack (WebSocket v5 is built in — no plugin needed)
|
||||
- **VMware App Volumes** to deliver OBS to targeted users
|
||||
- **VMware DEM** to deliver config files and run the logon task
|
||||
- **OBS Studio 28+** — delivered via App Volumes AppStack **or** installed directly on the machine (WebSocket v5 is built in — no plugin needed)
|
||||
- **VMware DEM** to run the logon task
|
||||
- A **UNC share** writable by VDI users for clip storage
|
||||
- A **network share** to host this repo's files, accessible from all VDI machines
|
||||
|
||||
> **App Volumes is optional.** If OBS Studio is installed directly on the machine (e.g. via SCCM, Intune, or manual install), App Volumes is not required. Set `OBSExecutable` in `config.psd1` to the correct path and the script will work as-is.
|
||||
|
||||
## Configuration
|
||||
|
||||
Edit `config.psd1` before deploying:
|
||||
@@ -60,7 +57,7 @@ Edit `config.psd1` before deploying:
|
||||
| `UNCPath` | Base UNC path for clip storage — username subfolder created automatically | `\\server\ITCaptures` |
|
||||
| `BufferSeconds` | Replay buffer duration in seconds | `120` |
|
||||
| `WebSocketPort` | OBS WebSocket port — must match `obs-config/plugin_config/obs-websocket/config.json` | `4455` |
|
||||
| `OBSExecutable` | Full path to `obs64.exe` on the VDI machine | `C:\Program Files\obs-studio\bin\64bit\obs64.exe` |
|
||||
| `OBSExecutable` | Full path to `obs64.exe` on the target machine | `C:\Program Files\obs-studio\bin\64bit\obs64.exe` |
|
||||
| `ProfileName` | OBS profile name — must match the folder under `obs-config/profiles/` | `ITMonitor` |
|
||||
| `SceneCollection` | OBS scene collection name — must match the filename under `obs-config/scenes/` | `ITMonitor` |
|
||||
|
||||
@@ -68,49 +65,40 @@ Edit `config.psd1` before deploying:
|
||||
|
||||
### Step 1 — Host the repo on a network share
|
||||
|
||||
Place this repo (or a copy of it) on a share accessible from all VDI machines, e.g.:
|
||||
Place this repo (or a copy of it) on a share accessible from all target machines, e.g.:
|
||||
|
||||
```
|
||||
\\stcu-fs01\IT-Tools\OBS-Record\
|
||||
```
|
||||
|
||||
### Step 2 — DEM: File Transfer tasks
|
||||
### Step 2 — DEM: Logon task
|
||||
|
||||
Create these file transfer tasks in DEM, scoped to the target user group. All run at logon.
|
||||
|
||||
| Source (on network share) | Destination (on VDI session) |
|
||||
|---|---|
|
||||
| `obs-config\profiles\ITMonitor\` | `%APPDATA%\obs-studio\basic\profiles\ITMonitor\` |
|
||||
| `obs-config\scenes\ITMonitor.json` | `%APPDATA%\obs-studio\basic\scenes\ITMonitor.json` |
|
||||
| `obs-config\plugin_config\obs-websocket\config.json` | `%APPDATA%\obs-studio\plugin_config\obs-websocket\config.json` |
|
||||
| `obs-config\global.ini` | `%APPDATA%\obs-studio\global.ini` |
|
||||
|
||||
> **Note:** `basic.ini` is intentionally not delivered by DEM — it is written dynamically at logon by `Start-OBSReplayBuffer.ps1` so that the correct UNC path (including username) and primary monitor resolution are baked in per session.
|
||||
|
||||
### Step 3 — DEM: Logon task
|
||||
|
||||
Create one logon task in DEM (scoped to the same target group). Set it to **not wait for completion**.
|
||||
Create one logon task in DEM (scoped to the target user group). Set it to **not wait for completion**.
|
||||
|
||||
```
|
||||
powershell.exe -ExecutionPolicy Bypass -NonInteractive -WindowStyle Hidden -File "\\stcu-fs01\IT-Tools\OBS-Record\scripts\Start-OBSReplayBuffer.ps1"
|
||||
```
|
||||
|
||||
This script handles launching both OBS and the tray icon — no second task needed.
|
||||
This is the only DEM task needed. The script handles all config file deployment, folder creation, and launching both OBS and the tray icon. It will exit cleanly (code 1) if any required project file is inaccessible, or exit 0 if OBS is already running.
|
||||
|
||||
### Step 4 — Assign App Volumes AppStack
|
||||
> **No DEM file transfer tasks are needed.** The script deploys `global.ini` and the WebSocket config from the repo to `%APPDATA%\obs-studio\` at each logon. `basic.ini` is written dynamically so the correct UNC path and primary monitor resolution are baked in per session.
|
||||
|
||||
Assign the OBS AppStack to the same user group in App Volumes. The logon task will exit cleanly if OBS is not present or already running.
|
||||
### Step 3 — OBS Studio (App Volumes or native install)
|
||||
|
||||
**Option A — App Volumes:** Assign the OBS AppStack to the same user group.
|
||||
|
||||
**Option B — Native install:** Ensure OBS Studio 28+ is installed at the path set in `OBSExecutable` in `config.psd1`. No other configuration is needed.
|
||||
|
||||
## User Experience
|
||||
|
||||
- A shield icon appears in the system tray at logon — no other UI is visible
|
||||
- Right-click the icon → **Save Replay** to save the last `BufferSeconds` of screen activity
|
||||
- A balloon notification confirms success or failure
|
||||
- A Windows toast notification confirms success or failure (falls back to a message box if toast is unavailable)
|
||||
- Clips appear at `\\server\ITCaptures\<username>\` named by timestamp
|
||||
|
||||
## Changing the Buffer Duration
|
||||
|
||||
Update `BufferSeconds` in `config.psd1`. The value is written into the OBS profile at each logon, so no repackaging of the App Volumes AppStack is needed.
|
||||
Update `BufferSeconds` in `config.psd1`. The value is written into the OBS profile at each logon, so no repackaging or redeployment is needed.
|
||||
|
||||
## Notes
|
||||
|
||||
@@ -118,12 +106,10 @@ Update `BufferSeconds` in `config.psd1`. The value is written into the OBS profi
|
||||
|
||||
The `obs-config/scenes/ITMonitor.json` file was generated to target monitor index `0` (primary display). If it does not capture correctly on first use:
|
||||
|
||||
1. Launch OBS normally on a test machine with the AppStack assigned
|
||||
1. Launch OBS normally on a test machine
|
||||
2. Manually configure a Display Capture source pointed at the primary monitor
|
||||
3. Save, then copy `%APPDATA%\obs-studio\basic\scenes\ITMonitor.json` back into this repo
|
||||
|
||||
The `basic.ini` and WebSocket config are reliable and should not need adjustment.
|
||||
|
||||
### OBS Tray Icon vs. IT Tray Icon
|
||||
|
||||
OBS itself also places a tray icon when minimized to tray. Users will see two icons — the OBS icon and the IT Screen Recorder shield icon. The OBS icon can be right-clicked to quit OBS, which would break the replay buffer. If this is a concern, a future enhancement could hide the OBS tray icon via a startup flag or OBS config setting.
|
||||
OBS places its own tray icon when minimized. Users will see two icons — the OBS icon and the IT Screen Recorder shield icon. The OBS icon can be right-clicked to quit OBS, which would break the replay buffer. If this is a concern, a future enhancement could suppress the OBS tray icon via an OBS config setting.
|
||||
|
||||
@@ -12,6 +12,22 @@
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
|
||||
function Show-Notification {
|
||||
param([string]$Title, [string]$Body)
|
||||
try {
|
||||
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
|
||||
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
|
||||
$xml = [Windows.Data.Xml.Dom.XmlDocument]::new()
|
||||
$escaped = [System.Security.SecurityElement]::Escape($Body)
|
||||
$xml.LoadXml("<toast><visual><binding template='ToastGeneric'><text>$Title</text><text>$escaped</text></binding></visual></toast>")
|
||||
$toast = [Windows.UI.Notifications.ToastNotification]::new($xml)
|
||||
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('IT Screen Recorder').Show($toast)
|
||||
}
|
||||
catch {
|
||||
[System.Windows.Forms.MessageBox]::Show($Body, $Title, [System.Windows.Forms.MessageBoxButtons]::OK) | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
$saveScript = Join-Path $PSScriptRoot 'Invoke-ReplaySave.ps1'
|
||||
|
||||
# --- Tray icon ---
|
||||
@@ -33,10 +49,10 @@ $saveItem.Add_Click({
|
||||
$result = & powershell.exe -ExecutionPolicy Bypass -NonInteractive -File $saveScript
|
||||
|
||||
if ($result -eq $true) {
|
||||
$tray.ShowBalloonTip(4000, 'IT Screen Recorder', 'Replay saved.', [System.Windows.Forms.ToolTipIcon]::Info)
|
||||
Show-Notification -Title 'IT Screen Recorder' -Body 'Replay saved.'
|
||||
}
|
||||
else {
|
||||
$tray.ShowBalloonTip(4000, 'IT Screen Recorder', 'Could not save replay. Please contact the helpdesk.', [System.Windows.Forms.ToolTipIcon]::Error)
|
||||
Show-Notification -Title 'IT Screen Recorder' -Body 'Could not save replay. Please contact the helpdesk.'
|
||||
}
|
||||
|
||||
$saveItem.Text = 'Save Replay'
|
||||
|
||||
@@ -15,6 +15,19 @@ $ErrorActionPreference = 'Stop'
|
||||
$configPath = Join-Path $PSScriptRoot '..\config.psd1'
|
||||
$config = Import-PowerShellDataFile -Path $configPath
|
||||
|
||||
# --- Verify required project files are accessible ---
|
||||
$requiredPaths = @(
|
||||
(Join-Path $PSScriptRoot '..\obs-config\global.ini')
|
||||
(Join-Path $PSScriptRoot '..\obs-config\plugin_config\obs-websocket\config.json')
|
||||
(Join-Path $PSScriptRoot 'Show-ReplayTray.ps1')
|
||||
$config.OBSExecutable
|
||||
)
|
||||
foreach ($path in $requiredPaths) {
|
||||
if (-not (Test-Path -Path $path)) {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# --- Skip if OBS is already running (handles reconnect scenarios) ---
|
||||
if (Get-Process -Name 'obs64' -ErrorAction SilentlyContinue) {
|
||||
exit 0
|
||||
@@ -32,6 +45,16 @@ $screen = [System.Windows.Forms.Screen]::PrimaryScreen
|
||||
$width = $screen.Bounds.Width
|
||||
$height = $screen.Bounds.Height
|
||||
|
||||
# --- Deploy global OBS config and WebSocket plugin config ---
|
||||
$obsConfigRoot = "$env:APPDATA\obs-studio"
|
||||
$sourceConfig = Join-Path $PSScriptRoot '..\obs-config'
|
||||
|
||||
Copy-Item -Path "$sourceConfig\global.ini" -Destination "$obsConfigRoot\global.ini" -Force
|
||||
|
||||
$wsConfigDir = "$obsConfigRoot\plugin_config\obs-websocket"
|
||||
New-Item -ItemType Directory -Path $wsConfigDir -Force | Out-Null
|
||||
Copy-Item -Path "$sourceConfig\plugin_config\obs-websocket\config.json" -Destination "$wsConfigDir\config.json" -Force
|
||||
|
||||
# --- Write OBS profile (basic.ini) ---
|
||||
$profileDir = "$env:APPDATA\obs-studio\basic\profiles\$($config.ProfileName)"
|
||||
New-Item -ItemType Directory -Path $profileDir -Force | Out-Null
|
||||
@@ -70,8 +93,10 @@ $obsArgs = @(
|
||||
'--minimize-to-tray'
|
||||
'--startreplaybuffer'
|
||||
'--disable-updater'
|
||||
"--profile `"$($config.ProfileName)`""
|
||||
"--collection `"$($config.SceneCollection)`""
|
||||
'--profile'
|
||||
$config.ProfileName
|
||||
'--collection'
|
||||
$config.SceneCollection
|
||||
)
|
||||
|
||||
Start-Process -FilePath $config.OBSExecutable -ArgumentList $obsArgs -WindowStyle Hidden
|
||||
|
||||
Reference in New Issue
Block a user