9.5 KiB
name, description
| name | description |
|---|---|
| screenconnect | Manage ACG ConnectWise ScreenConnect via the RESTful API Manager extension: sessions, parameterized self-tagging installers, backstage commands, custom properties; writes gated --confirm. Triggers: screenconnect, connectwise control, sc session, screenconnect installer. |
ScreenConnect (ConnectWise Control) Skill
Standalone CLI for the ACG ScreenConnect cloud instance
(https://computerguru.screenconnect.com) via the RESTful API Manager
extension. Read-only by default; writes gated behind --confirm.
Running the CLI
SC="bash $CLAUDETOOLS_ROOT/.claude/scripts/py.sh C:/claudetools/.claude/skills/screenconnect/scripts/sc.py"
$SC status # auth check + fleet counts
$SC sessions # WHOLE Access fleet (all agents)
$SC sessions --company "X" # one client's machines (CP1)
$SC sessions --like DELL # partial-name match
$SC sessions --name "<hostname>" # exact Name match
$SC sessions --filter "SessionType = 'Access'" # raw session-filter expression
$SC sessions --limit 25 # cap printed rows (--json is always full)
$SC session <sessionID> # full session detail
$SC build-installer --platform msi --name HOST --company "X" --site "Y" --tag "Z"
$SC send-command --session <id> --command "..." --confirm
$SC set-properties --session <id> --props-json '["Company","Site","Tag"]' --confirm
$SC raw --method GetSessionsByFilter --body '{"sessionFilter":"SessionType = '"'"'Access'"'"'"}'
Transport auto-selects httpx, else stdlib urllib (no hard dependency).
Credentials & auth (VERIFIED)
API secret is NEVER hardcoded - loaded from the SOPS vault
msp-tools/screenconnect.sops.yaml field credentials.api_secret (or the
SCREENCONNECT_API_SECRET env override). Auth is two headers:
CTRLAuthHeader: <raw api_secret> (NO "Basic" prefix - Basic auth 401s)
Origin: https://computerguru.screenconnect.com
Endpoints: POST <base>/App_Extensions/2d558935-686a-4bd0-9991-07539f5fe749/Service.ashx/<Method>.
Reads take a JSON object; the write methods take a positional array.
Custom properties on this instance: CP1=Company, CP2=Site, CP3=Tag (up to CP8).
The deploy workflow (RMM push -> self-tag -> control)
This is the headline use case - set a device for SC and have it land correctly:
build-installerwith the device's Company/Site/Tag (+ name) -> a parameterized access-installer URL (?e=Access&y=Guest&t=<name>&c=<Company>&c=<Site>&c=<Tag>). The cloud serves a pre-keyed installer; thec=params self-tag the agent.- Push that installer via
/rmm(download +msiexec /i ... /qnas SYSTEM). - The SC agent connects -> a session named
<name>appears with CP1/CP2/CP3 set. sessions --name <name>-> get the sessionID -> control it (send-command, etc.).
VERIFIED end-to-end on RMM-TEST-MACHINE 2026-06-22 (installed, self-tagged Company/Site/Tag, ran a command, re-tagged via set-properties).
Deploying the GuruRMM agent via SC (verified 2026-07-08)
Different from the SC-installer push above: to enroll a box that is in SC but NOT in GuruRMM,
send-command the server's own site-preconfigured one-liner. The site code is baked into the
downloaded signed binary (GRMM_CFG trailer) so it self-enrolls straight into that site — no
Staging, no reassign:
# site_code from GET /api/sites/<id>/install-info (e.g. Main = INNER-BRIDGE-8354)
CMD='powershell -NoProfile -ExecutionPolicy Bypass -Command "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; iex (irm '\''https://rmm.azcomputerguru.com/install/<SITE_CODE>/windows'\'')"'
$SC send-command --session <sessionID> --command "$CMD" --confirm
The install script auto-relaunches into native 64-bit PowerShell (handles SC's 32-bit command runner via Sysnative). Verified: DESKTOP-NFU17AJ enrolled into IMC → Main this way 2026-07-08.
send-commandreturns{}— SC gives no command output via the API (documented below). It is queued, not confirmed. Verify by enrollment, not by the send response: pollrmm-search.sh -c <client>for the new agent (pipe--jsonwith2>/dev/null— the[OK] Authenticatedbanner is on stderr;2>&1 | jqbreaks jq).- Offline targets: the one-liner is a single self-contained command, so it queues in the session's one event slot and runs on reconnect. It will NOT run until the box is online.
- Gotcha: the install script calls
Get-CimInstance Win32_Processor; a box with corrupt WMI dies there (bit CP-QB). A box that black-holes outbound TLS installs but never connects (bit IMC-PRINTSERVER) — SC still works because its relay is not TLS. - CP values are under
.CustomProperties.CustomPropertyN/.CustomPropertyValues[]on the raw session object (CP1=Company, CP2=Site, ...).--company "X"matches CP1 exactly, so pass the full tagged value (IMC's CP1 isIMC - Instrumental Music Center, notInstrumental Music Center) or enumerate with--like/ a rawCustomProperty1 = '...'filter first. SC truncates session Name to 15 chars —IMC-M-EDSERVICE(SC) isIMC-M-EdServices1(RMM).
Method surface (probed live 2026-06-22)
Available (CLI-exposed):
- Full-fleet listing:
GetSessionsByFilter{"sessionFilter":"<expr>"}(probed live 2026-07-06) - THE enumeration path.SessionType = 'Access'returns every unattended agent (958 on this instance);SessionType = 'Support'the on-demand sessions (24). Filter language: single-quoted literals,=/LIKE(with*wildcards),AND/OR. Per-clientCustomProperty1 = 'Safesite'; partial nameName LIKE '*DELL*'. The CLIsessionscommand wraps this (default = whole fleet). - Reads:
GetSessionsByName(EXACT Name match; "" -> only blank-name sessions, NOT the fleet - use the filter for listing),GetSessionDetailsBySessionID,GetSessionBySessionID. - Writes (gated):
SendCommandToSession[sessionID, command],SendMessageToSession[sessionID, message],UpdateSessionCustomProperties[sessionID, [cp1,cp2,cp3,...]],CreateSession(array; not the primary path - the installer creates access sessions).
Absent aliases (not needed):
GetSessions/GetAllSessions/GetSessionGroups-> "web method does not exist". No extension update required:GetSessionsByFiltercovers full-fleet inventory. (Earlier notes flagged this as a gap pending Mike; it is resolved.)
Safety gating
send-command, send-message, set-properties refuse to run without --confirm
(print what they WOULD do, exit 3). raw also refuses state-changing method names
(sendcommand/updatesession/create/delete/end/transfer/install/...) without
--confirm. NEVER run send-command against a production client session casually -
it executes on the guest. Test against a known test machine.
Error logging
On a GENUINE functional error (auth failure, unexpected API response, transport
failure) the CLI logs it to errorlog.md via log-skill-error.sh before
surfacing it. It does NOT log expected/handled conditions - a missing extension
method ("web method does not exist"), a rate-limit (429), the raw probe path, or
selftest runs (SC_SUPPRESS_ERRORLOG=1) are skipped (see _should_log_error).
Why this skill exists: the GuruRMM addon integration (the end goal)
This skill is the verified connector prototype for a GuruRMM addon, not a one-off CLI. The end goal is to surface ScreenConnect as a first-class, per-partner entry on the GuruRMM Integrations Center / App Center ("addons page"), so a partner can wire in their OWN paid ScreenConnect instance and the RMM drives it.
Positioning - ScreenConnect is the bring-your-own alternative to GuruConnect.
GuruRMM's native remote-access product is GuruConnect (consumed via its
integration contract - see guru-rmm/docs/GURU_CONNECT_INTEGRATION.md). A partner
who is already paying for ScreenConnect and does NOT want GuruConnect enables
the ScreenConnect addon instead and uses their existing licensed instance for
remote access. Same RMM surface (the "remote control" device action, embedded/
launched session), different provider behind it - selectable per partner on the
addons page. It is an alternative remote-access backend, not an addition GuruConnect
depends on.
What this skill proves / ports into the server: the parameterized access
installer build (build-installer -> a pre-keyed URL whose repeated c= params
self-tag the device into the right Company/Site/Tag with no SC-console step), the
silent RMM push, and post-install control (send-command, send-message,
set-properties to keep SC custom properties in sync as the RMM record changes).
sc_client.build_installer_url + the control methods are what move server-side.
Where the plan is mapped (all GuruRMM-side, needs Mike's go - status Raw):
docs/specs/SPEC-024-screenconnect-auto-deploy.md- the auto-deploy mechanics (per-partner instance config,c0..c7slot mapping, scope toggles, dispatch).docs/RMM_THOUGHTS.mdFeature 7 - parameterized deploy + control from the RMM.docs/RMM_THOUGHTS.mdRefinement 7a (Mike) - ScreenConnect as a per-partner App Center entry; generalizes to a "Remote Access" category (SC/TeamViewer/AnyDesk).docs/FEATURE_ROADMAP.mdIntegrations Center - the unified addons UI surface.
Advance via RMM_THOUGHTS -> /shape-spec. Do NOT build until Mike gives the go.
Reference
Verified method/param spec, auth, installer params, and the session-filter language:
references/api-reference.md.