Appearance
Self-service scripts
Self-service scripts let an end user run a small, curated set of pre-approved scripts on their own machine — via the OpsMerge Tray app that lives in their menu bar / notification area — without the operator needing to do anything live.
Use cases:
- "Clear the print queue" — a tech-friendly user can self-serve a stuck printer queue.
- "Restart Teams" — instead of opening a ticket, the user runs the fix themselves.
- "Submit a diagnostic bundle" — collects logs and uploads, attached to the next ticket they open.
- "Request elevated access to install software" — the user can request; an operator approves; the script runs as SYSTEM.
This is a safety-rails feature: end users can only run scripts an operator has explicitly published as self-service, and only on their own machine.
How it works (high level)
- You publish a script to the self-service catalogue, scoped to a client/site/role.
- The Tray app on the endpoint shows the user the available self-service scripts (filtered to what they're allowed to run).
- The user clicks one. They may be asked to confirm intent and provide parameters.
- The script runs as
LOCAL SYSTEM(Windows) or root (Linux/macOS) — not as the user. So it can do privileged work. - Approval gating (optional): if the script is approval-gated, the user submits a request; an operator approves; the run then proceeds.
- The result appears in the Tray app and in the user's recent-actions history.
The Tray app talks to the OpsMerge agent on the same endpoint over a local IPC channel — so even though the user clicks a button, the actual execution path goes through the same audited script-execution surface as if you'd run it from the OpsMerge UI.
Publishing a script as self-service
Settings → RMM → Scripts → script → Self-service tab → Enable.
You set:
- Friendly label — what the user sees in the Tray app (defaults to script name).
- User-facing description — one or two sentences. Make this readable to a non-technical user.
- Icon — optional emoji or icon, helps recognition in the Tray app.
- Approval required — does this script need operator approval before each run?
- Allowed audiences — which contacts can see/run it (by client, by site, by tag, or by named contacts).
- Visible parameters — which of the script's parameters does the user fill in?
The same script can be both available to operators in the normal Scripts library and exposed to self-service. There's no separate codebase.
Approval workflow
If approval is required:
- User clicks the script in Tray app.
- User fills in parameters and submits a request.
- The request appears in an operator inbox in OpsMerge (Settings → Self-service → Pending approvals).
- An operator approves or rejects.
- If approved, the script executes on the endpoint immediately.
- If rejected, the user sees the rejection with the operator's reason.
We strongly recommend approval gating for anything that:
- Modifies system state in non-trivial ways (install software, modify configs, restart services).
- Could be expensive or hard to reverse.
- Touches anything privileged enough that an attacker getting the user's credentials could cause damage.
Things that are safe to leave un-approval-gated:
- Diagnostic-only scripts (collect-and-show, no state change).
- Clear-cache-style scripts where the worst case is "user has to log back in".
- Restart-a-specific-app scripts.
Audiences
You can scope a self-service script to any combination of:
- All users at a client.
- Users at a specific site within a client.
- Users with a specific tag (e.g.
it-savvyfor the user who clearly knows what they're doing). - A named list of contacts.
If a user doesn't match any audience for a given script, they don't see it.
Don't give the same scripts to everyone
The temptation is to enable everything for everyone. Resist. The whole point of self-service is curation — three or four genuinely-useful scripts that work for that user are more valuable than twenty they don't understand.
What the user sees
In the Tray app:
- A list of available scripts (filtered by audience).
- For each script: label, description, icon.
- A history of their own recent runs (last 30 days), including operator approvals.
- A "Request elevated access" button if any approval-gated scripts are available to them.
They don't see:
- Scripts they're not in the audience for.
- The script's actual code or implementation.
- Anything about other endpoints (only their own machine).
- Anything about other users.
Operator side: monitoring usage
Settings → Self-service → Usage.
You see:
- How many self-service runs across your fleet, per day/week/month.
- Which scripts are most-used.
- Approval queue depth and time-to-approve metrics.
If a particular script is being heavily used, that's usually a sign you should automate it via policy rather than relying on user-initiated runs. The whole point of an MSP is to take work off the user's plate.
Security considerations
- Self-service scripts run as
LOCAL SYSTEM/root. The user clicking the button doesn't get root — the script does. So a user can't escalate via self-service to access things they shouldn't. - The approval workflow exists specifically to gate scripts that, even running as SYSTEM, you don't want a non-operator triggering.
- Every self-service run is logged the same as an operator-initiated run — same audit detail, same retention.
- A user with the Tray app installed but who's no longer at the client (you removed them) loses access immediately.
Common patterns
"Standard helpdesk-tier-1 deflection"
Three scripts, all without approval:
- Restart printer queue — clears stuck print jobs.
- Reset Teams — kills Teams.exe, clears its cache, restarts.
- Submit diagnostics — bundles event logs + recent ticket history, uploads to OpsMerge, attaches to the user's next ticket.
Result: 30% fewer "my printer is broken" tickets.
"Approval-gated software install"
One script with approval:
- Install allowed software — parameter is the software name from an allow-list ("Slack", "Zoom", "Chrome"). User requests, operator approves, script runs
winget installorbrew installaccordingly.
Result: users get software they need without needing the IT team to schedule a session.
"VIP-only diagnostic"
One script visible only to vip:true contacts:
- Run advanced diagnostic — for VIPs, who get more thorough auto-collected diagnostics so the operator has more context when they open the ticket.
Common issues
User says "I don't see any scripts in Tray". They're not in any script's audience, the Tray app isn't running, or the agent is offline. Check those in order.
Approval inbox is empty despite the user submitting a request. The user's request was rejected by the policy filter before reaching the inbox (e.g. they're not in the script's audience). They see a "this is not available to you" message rather than the request being submitted.
Script always fails when run via self-service but works when I run it via the operator UI. Self-service runs in a tighter sandbox — no interactive desktop, stricter timeout (60 seconds by default). Adjust the script or the per-script timeout.
Tray app crashes / doesn't appear. Tray is a Tauri-based app on Windows/macOS. Reinstall via the agent: Run script → "Reinstall Tray app" (a system template script).
Next
- Scripts & automation — the underlying engine
- Policies — controlling which clients have self-service enabled at all