-
Notifications
You must be signed in to change notification settings - Fork 0
Command Center
Batch, scheduled PowerShell/cmd command execution across many workstations at once - this is not the same as the Console feature described on the Client-Server Communication page. Console is immediate, single-machine, server-initiated push over port 8080; Command Center is scheduled, client-initiated pull, over the same port 443 API-Token channel used for heartbeat/event reporting.
| Table | Role |
|---|---|
commands |
One row per created command: script text (command), earliest run time (run_after_at), Emergency Stop flag (blocked), creator (user_id) |
command_workstations |
Pivot table: one row per (command × assigned workstation) pair, result field (NULL until a result comes back) |
CommandsController::saveCommand() - requires the write-batch-command permission. Validates: a script is selected, ≥1 workstation is assigned, the date/time is in the future. Once at least one result has come back for a command (CommandWorkstations::whereNotNull("result")->count() > 0), the command can no longer be edited.
sequenceDiagram
participant C as BigLanService client
participant S as BigLan server
Note over C: On startup, then every 30 minutes
C->>S: action: getWaitingCommandsCounter (wsid)
S-->>C: number of pending commands
C->>S: action: getCommand (wsid)
Note over S: getCommand() immediately marks the row<br/>"[Retrieved]" so it isn't handed out twice
S-->>C: command_workstations_id + script text
Note over C: Script runs locally
C->>S: action: saveCommandResult (id, result)
Note over S: the "[Retrieved]" placeholder is<br/>overwritten with the real result
-
getWaitingCommandsCounter()- countscommand_workstationsrows whereresultis stillNULL, joined tocommandswhereblocked = 0andrun_after_at <= now -
getCommand()- returns the oldest eligible pending command (ORDER BY run_after_at ASC) and immediately sets itsresultto"[Retrieved]"- this prevents the same command from being handed to the same client twice on overlapping polls -
saveCommandResult()- the client calls this to send back the actual output, overwriting the placeholder
CommandsController::emergencyStop() sets commands.blocked = 1. From that point on, no new getWaitingCommandsCounter()/getCommand() call will hand out this command - but it does not recall it from a workstation that already retrieved it and is mid-execution.
If a client retrieves a command but never reports back a result (crash, network loss, etc.), the result field stays at "[Retrieved]" forever - there is no timeout or automatic re-issuing. This shows up as a permanently "stuck" entry in the Command Center list.