Reach systems on a private network by running a PowerShell action on a device inside that network

Query a system that only exists on a customer's private network, such as a line-of-business application, a NAS, a door-access controller or an on-premises server, by running a PowerShell workflow action on a device inside that network. For MSPs and IT teams supporting sites with on-premises systems.

Runs in On the device (PowerShell, as SYSTEM)
Uses API key credential for the internal system (optional)
Suggested approval No approval needed for engineers (policy rule: Specific groups → No approval needed), because it only reads. No Anyone rule
Category Devices

Test it with SuperIT before you rely on it

This is an example, not a ready-made action, and it hasn't been tested end to end. The internal address https://lob.corp.local/api/status and the response fields are placeholders for your own system's. Before you use it, work through it with SuperIT: ask SuperIT to review the script against your environment and requirements, and adjust it together. Then run it on a test device, as in Test it. Device actions can't use Test, so every run is real.

Why use an action instead of asking SuperIT

SuperIT can't reach systems inside a customer's network. In a chat, web requests from a device (Invoke-WebRequest and Invoke-RestMethod) are blocked by a locked command policy, chat commands get no stored credentials, and the cloud sandbox blocks private addresses. A device action running on a server inside the network can call the internal API with an encrypted credential, and SuperIT can then use the answer in chat.

To check something on the device itself, such as a service, a disk or an event log, just ask SuperIT in chat.

Why a device, not the sandbox

The cloud sandbox reaches the public internet only. Private address ranges, such as 10.x, 172.16–31.x and 192.168.x, are blocked (see Network), so a sandbox action can't see anything behind a customer's firewall. A device action runs on a Windows device through the SuperIT RMM agent instead, so it can reach whatever that device can reach. Pick a device that is always on and on the right network, usually a server.

When to use it

  • "Is the practice management server responding at the Leeds office?"
  • "How many licences are in use on our line-of-business app?"
  • "Check the NAS at the main office for failed disks."

What the action does

  1. Runs on the chosen Windows device as SYSTEM, with no user signed in.
  2. Stops before calling anything if expected_hostname isn't this device's computer name.
  3. Refuses any address that isn't https://, and doesn't follow redirects, so the API key is only sent to the address you set.
  4. Calls the internal system's HTTP API with an optional API key from the linked credential. Linked credentials reach device actions as environment variables, as they do in the sandbox.
  5. Prints the system's version, health and licence use, and returns them as a result.

What it doesn't do:

  • It doesn't run on macOS or Linux. Device actions need Windows and PowerShell.
  • It doesn't run in a user's session, so it can't see mapped drives or the signed-in user's files.
  • It can't use Python or Playwright. On a device, only PowerShell runs.
  • It doesn't open firewall ports or change the system it queries.
  • It doesn't turn off certificate checks or fall back to http://.

Before you begin

  • A Windows device with the SuperIT RMM agent on the same network as the system, online when the action runs.
  • Credentials for the internal system, if it needs them. Under Workflows → Credentials, select New, name it LOB App and choose the matching Auth scheme, for example Other (custom header) with header X-Api-Key. The script reads it as CREDENTIAL_LOB_APP_X_API_KEY. See Credentials. Systems that accept Windows authentication see the device's computer account, because the action runs as SYSTEM.
  • An authorization policy. A device action runs with full rights on that device, so always link a policy rather than leaving it at None. For a read-only query: Requester Specific groups superit:engineers, Approver No approval needed. See Approvals.
  • A default device. Ask SuperIT to make the server the action's default device. The linked credential reaches whichever device runs the action, and that device's DNS decides where lob.corp.local points. Without a default device, a run with no device chosen goes to your team's designated device. expected_hostname stops the script there before it calls the API, but the key has still been sent to that device.
  • The Admin role, and SuperIT. Whether an action runs in the sandbox or on a device is part of the action, and the action editor doesn't let you change it. Ask SuperIT to create the action as a device action, or to change an existing action to one. The action's Overview then shows Device. See Set an action to run on a device.

Build it with SuperIT

Create an action called "Check LOB app status".
Purpose: query our line-of-business app's internal API at https://lob.corp.local/api/status and report version, health and licences in use.
This action must always run on a device (a server on the customer network), not in the cloud sandbox.
Runtime: PowerShell (Windows PowerShell 5.1 on the device, runs as SYSTEM).
Input: expected_hostname (string, required). Stop before calling anything unless it matches $env:COMPUTERNAME.
Credential: "LOB App" (custom header X-Api-Key).
Read-only. https only; never skip certificate checks; don't follow redirects.
Authorization policy: superit:engineers group, no approval.

SuperIT confirms the target, drafts the script for Windows PowerShell 5.1, validates it and creates the action as a draft. You review the script and publish it under Workflows → Actions.

Or build it yourself

You can write the script in the action editor, but ask SuperIT (or an admin using the API) to set the action to run on a device. Add this input:

Name Type Required Example
expected_hostname string Yes SRV-APP01
# Goal: from this device, read the LOB app's internal status API and report version, health and licence use. Read-only.
# Windows PowerShell 5.1 on the device. No top-level param() block: SuperIT wraps this script in try { }.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$statusUri = "https://lob.corp.local/api/status"   # internal address, reachable from this device
$apiKey = $env:CREDENTIAL_LOB_APP_X_API_KEY

function Invoke-LobStatusCheck {
    param([string]$Uri, $ExpectedHostname)

    Assert-TargetDevice -ExpectedHostname $ExpectedHostname
    Assert-HttpsUri -Uri $Uri
    $status = Get-LobStatus -Uri $Uri
    Write-LobStatusReport -Uri $Uri -Status $status
    # $script: so SuperIT can still read $result after this function returns.
    $script:result = @{
        checked_from = $env:COMPUTERNAME; version = $status.version; health = $status.health
        licences_in_use = $status.licencesInUse; licences_total = $status.licencesTotal
    }
}

function Assert-TargetDevice {
    param($ExpectedHostname)
    $expected = ("$ExpectedHostname".Trim() -split '\.')[0]
    if (-not $expected) { throw "expected_hostname is required: enter this device's computer name." }
    if ($expected -ne $env:COMPUTERNAME) { throw "This run reached '$env:COMPUTERNAME', not '$expected'. Nothing was called." }
}

function Assert-HttpsUri {
    param([string]$Uri)
    # Over http the API key would cross the network in clear text.
    if (([uri]$Uri).Scheme -ne 'https') { throw "Only https:// addresses are allowed, not '$Uri'." }
}

function Get-LobStatus {
    param([string]$Uri)
    $headers = @{}
    if ($apiKey) { $headers["X-Api-Key"] = $apiKey }
    try {
        # No redirects: Windows PowerShell 5.1 resends X-Api-Key to the new address, which could be another host or http.
        return Invoke-RestMethod -Uri $Uri -Headers $headers -TimeoutSec 20 -MaximumRedirection 0
    } catch {
        $reason = $_.Exception.Message
        Write-ReachabilityHint -Uri $Uri
        throw "Failed to read LOB app status from '$Uri' on ${env:COMPUTERNAME}: $reason"
    }
}

function Write-ReachabilityHint {
    param([string]$Uri)
    $target = [uri]$Uri
    $reach = Test-NetConnection -ComputerName $target.Host -Port $target.Port -WarningAction SilentlyContinue
    Write-Output "TCP $($target.Port) to $($target.Host) reachable from ${env:COMPUTERNAME}: $($reach.TcpTestSucceeded)"
}

function Write-LobStatusReport {
    param([string]$Uri, $Status)
    Write-Output "=== LOB APP STATUS ==="
    Write-Output "Host         : $(([uri]$Uri).Host)"
    Write-Output "Checked from : $env:COMPUTERNAME"
    Write-Output "Version      : $($Status.version)"
    Write-Output "Health       : $($Status.health)"
    Write-Output "Licences     : $($Status.licencesInUse) of $($Status.licencesTotal) in use"
}

Invoke-LobStatusCheck -Uri $statusUri -ExpectedHostname $ctx.inputs.expected_hostname

Things that differ on a device:

  • The device runs Windows PowerShell 5.1, not PowerShell 7. Avoid PowerShell 7-only syntax, and set TLS 1.2 as above.
  • Windows PowerShell 5.1 has no -SkipCertificateCheck, and you shouldn't work around it. If the internal system uses a private certificate, trust your internal certificate authority on the device rather than turning checks off or using http://.
  • Don't put a param() block at the top of the script, because SuperIT wraps the whole script in try { }. Parameters inside functions are fine.
  • Assign $script:result inside a function, as above. SuperIT reads $result after your script ends, and a plain $result = inside a function never reaches it.
  • Keep the run short. Device actions time out after 5 minutes by default; the editor allows up to 60. See Timeouts.

Test it

The Test button doesn't work for device actions. Check the script safely instead:

  1. Paste the script into Windows PowerShell on the device as an administrator and confirm it works. Running it as SYSTEM can still behave differently, for example with Windows authentication.
  2. Publish the action.
  3. Run it once on the device: open the action, select Run, enter the device's computer name in expected_hostname, pick the same device under Run target, and select Run action. This is a real, billed run. The help text reads "Runs elevated as SYSTEM on the device via the mesh."
  4. Check Stdout and the Target device in the run details.
  5. Run it with a different name in expected_hostname and confirm it fails with "Nothing was called".

Use it

  • In chat: select the server in the chat, then ask "Check the LOB app status". SuperIT asks whether to run on the device, fills in expected_hostname, runs the action there and summarises the result.
  • On a schedule: ask SuperIT "Run Check LOB app status on SRV-APP01 every day, with expected_hostname SRV-APP01". Device schedules name a specific Windows device. Schedules are created in chat only and repeat every N days. A scheduled run's output stays in run history, so to be told about a problem, add the webhook call from Post a message to a Teams or Slack channel to the script.
  • Managed teams: use Publish to teams if several customers run the same application. Each copy runs on that team's own devices with that team's own credential, which its admin fills in.

Variations

  • Active Directory: run on a domain controller and use Get-ADUser to report lockout status, password expiry or group membership for a user. To unlock the account as well, see Unlock an on-premises Active Directory account.
  • Database check: run Invoke-Sqlcmd or sqlcmd on the SQL server to report database sizes or the last backup time.
  • Printers and scanners: query a printer's web interface or SNMP from a server at the same site for toner levels and error states.