Skip to the content.

Collector Readiness Check

Before adding a new collector to an auto-balance group, verify it can reach all devices in that group. Once the collector joins, LM starts assigning devices to it automatically — devices it can’t reach will generate monitoring errors.

The standard workflow:

  1. Build the new collector and leave it outside any group.
  2. Discover devices and protocols using tools/elm-collector-readiness.sh.
  3. Generate the test script (stdout redirect or clipboard).
  4. Test reachability from the new collector in LM Collector Debug.
  5. Fix any failures before moving the collector into the group.

See also:

Step 1 — Find the auto-balance group

Run with no arguments to list auto-balance groups:

tools/elm-collector-readiness.sh
Auto-balance groups:

id    name                      collectors  threshold
----  ------------------------  ----------  ---------
42    My Region Collectors      3           500
87    APAC Collectors           2           500

Note the ID of the group you are adding the new collector to.

Step 2 — Discover devices and generate the test script

The script always renders the Groovy test script to stdout. Redirect it to a file or pipe to clipboard.

By group ID — write to file:

tools/elm-collector-readiness.sh --id 42 > /tmp/check.groovy

By group name — write to file:

tools/elm-collector-readiness.sh --name "My Region Collectors" > /tmp/check.groovy

Copy directly to clipboard (macOS):

tools/elm-collector-readiness.sh --id 42 | pbcopy

With a non-default elm profile:

tools/elm-collector-readiness.sh --id 42 --profile prod > /tmp/check.groovy

--profile defaults to config (the same default as elm — reads config.ini).

Status messages go to stderr so they don’t pollute the redirected output:

Group:       My Region Collectors (id=42)
Collectors:  3
AutoBalance: true

Fetching devices in group 42...
Devices found: 47

Protocol legend: wmi=135, ssh=22, http=80, https=443 -- these are bare TCP
connect checks, NOT credential/protocol verification. A pass only means the
port accepted a connection, not that the named protocol/service works.

Device                           IP/Hostname             Protocols
-------------------------------- ----------------------  ---------
server01                         10.0.1.10               ping, snmp, ssh
windows-box                      10.0.1.20               ping, wmi
api-device                       10.0.1.30               ping, http, https

Protocol detection uses autoProperties set by LM Active Discovery on each device. The IP/hostname used is the name field — the address LM uses to reach the device, not displayName. wmi/ssh/http/https are bare TCP connect checks — no protocol handshake, no credentials — named after the protocol that usually lives on that port, but a pass only confirms the port is open, not that the protocol/service actually works (the script prints a legend saying so, every run). ping and snmp are real protocol tests (ICMP, and an actual SNMP GetRequest).

autoProperty Value Test added Port
auto.snmp.operational true SNMP probe (UDP 161) 161
auto.network.listening_tcp_ports contains 22 ssh (TCP connect only) 22
auto.network.listening_tcp_ports contains 80 http (TCP connect only) 80
auto.network.listening_tcp_ports contains 135, or auto.wmi.operational 135, or true wmi (TCP connect only — RPC endpoint mapper, necessary for WMI, not sufficient) 135
auto.network.listening_tcp_ports contains 443 https (TCP connect only) 443
(always) Ping (ICMP)

If a device has no Active Discovery data yet (no auto.network.listening_tcp_ports), only ping is tested. Run Active Discovery on the group in LM before using this tool for best results.

Step 3 — Run the test from the new collector

  1. Open the LM portal and navigate to the new collector’s device.
  2. Go to Collector Debug → Script tab.
  3. Paste the rendered Groovy (from file or clipboard) and run it.

Example output:

47 devices (pre-filled by elm)
Protocol legend: wmi=135, ssh=22, http=80, https=443 -- these are bare TCP connect
checks, NOT credential/protocol verification. A pass only means the port accepted
a connection, not that the named protocol/service works.

Device                           IP/Hostname          ping      snmp      ssh       wmi
-------------------------------- -------------------- --------- --------- --------- ---------
server01                         10.0.1.10            PASS      PASS      PASS      -
windows-box                      10.0.1.20            PASS      -         -         PASS
api-device                       10.0.1.30            PASS      -         -         -
unreachable-host                 10.0.2.99            FAIL      -         FAIL      -

FAILURES — investigate before adding this collector to the group:
  - unreachable-host  ping
  - unreachable-host  ssh

Automated run across all collectors (PowerShell)

tools/lm-collector-reachability-run-all.ps1 does Steps 2-4 in a single pass for every active collector in the group at once, then saves each collector’s result as <hostname>.csv so you can diff them to find reachability gaps between collectors.

It is self-contained PowerShell — it uses only the Logic.Monitor module (no elm, bash, jq, or jinja2). Establish a session first (Connect-LMAccount, or your own connection wrapper), then:

# List auto-balance groups
./tools/lm-collector-reachability-run-all.ps1

# Run against a group by id or name
./tools/lm-collector-reachability-run-all.ps1 -id 42
./tools/lm-collector-reachability-run-all.ps1 -group "My Region Collectors" -OutputDir ./results

It discovers group members via preferredCollectorGroupId, builds the same protocol matrix from autoProperties, generates the Groovy inline, submits it to each active collector via Collector Debug, waits, and writes one CSV per collector.

When two or more collectors return, the script then prints a built-in cross-collector comparison — for every device and protocol it gathers each collector’s result and lists only the rows where collectors disagree (e.g. one pass, another FAIL):

-- Comparison: reachability gaps between collectors --

  api-device  [id=10293]
      http       collectorA=pass  collectorB=FAIL

3 device(s) differ between collectors; 26 agree.

This scales to any collector count — the odd collector out of eight is visible on the per-protocol line, not just an A-vs-B comparison. The raw per-collector CSVs are still written to the output directory if you want to eyeball them. For a full textual diff of the two-collector case the script also prints a ready-to-run difft command (difft is pairwise only, so it is suggested only when exactly two collectors returned):

difft results/collectorA.csv results/collectorB.csv

Devices that are themselves collector hosts (identified by a collector’s collectorDeviceId) are skipped — a collector is monitored from itself, so cross-testing it from another collector is meaningless. If such hosts are found in an auto-balance group the script warns: collector hosts should be pinned to their own collector, not auto-balanced.

Vetting a new collector before adding it (-Candidate)

This is the pre-add check the whole workflow exists for: you built a new collector and want to know whether it will reach everything a group monitors before you move it in. Pass it with -Candidate (collector id or hostname). The group still defines the device list; the candidate — which is not in the group — gets that same list submitted to it alongside the group’s own collectors:

# Will newedge02 reach everything group 191 monitors?
./tools/lm-collector-reachability-run-all.ps1 -id 191 -Candidate newedge02

After the general comparison, the script prints a per-candidate verdict that lists only the device+protocol combinations the candidate fails to reach but an in-group collector does — the real gaps the candidate would introduce. Devices the whole group already can’t reach are not counted against the candidate.

== Candidate verdict: newedge02 ==
  2 gap(s) - the candidate would NOT reach these, but a group collector does:
    https      windows-box  [id=10220]  candidate=FAIL, group reaches it
    wmi        api-device   [id=10293]  candidate=FAIL, group reaches it
  Fix routing/firewall for these before moving the candidate into the group.

If there are no gaps it prints “Reaches everything the group’s collectors reach. Ready to add to the group.” You can pass -Candidate more than once (or a comma-separated list) to vet several collectors in one run.

Checking whether devices can move to a different group (-SourceCollector)

-Candidate above answers “would a new collector reach everything a group already monitors?” tools/lm-collector-move-readiness-run-all.ps1 answers the mirror-image question: “the devices sitting on these specific collectors right now — could the group I’m about to move them into actually reach them?” Use it when retiring a collector, consolidating collectors into a group, or relocating devices between sites, and you want to know before the move whether every device would still be reachable.

Device discovery is by preferredCollectorId against the named source collector(s) — not by group membership, so the source collectors don’t need to belong to any group at all (they can be standalone, or the very collector being retired):

# Would every device currently on legacy01/legacy02 be reachable from the active
# collectors in "Consolidated Collectors"?
./tools/lm-collector-move-readiness-run-all.ps1 -source legacy01,legacy02 -group "Consolidated Collectors"

# by id
./tools/lm-collector-move-readiness-run-all.ps1 -source 191,192 -id 42

The device summary table gets an extra Source column showing which source collector each device currently sits on. The Groovy reachability test itself, the per-collector CSVs, and the cross-collector comparison (are the target group’s own collectors consistent with each other?) all work exactly as in the group-vs-group case above.

After that, a move verdict classifies every device:

== Move verdict: 47 device(s) from 2 source collector(s) -> Consolidated Collectors (id=42) ==

READY:   44 device(s) - every target collector reaches them; safe to move.

BLOCKED: 1 device(s) - NO target collector reaches at least one expected protocol:
  - unreachable-host  [id=10299]  (from legacy01)
      ping  collectorA=FAIL  collectorB=FAIL

PARTIAL: 2 device(s) - SOME target collectors reach them, some don't.
         Risky if the target group is auto-balance: the device could land on a collector that fails it.
  - windows-box  [id=10220]  (from legacy02)
      wmi   collectorA=pass  collectorB=FAIL

BLOCKED means no collector in the target group can reach the device on an expected protocol — fix routing/firewall before moving it. PARTIAL only matters if the target group is auto-balance: LM could place the device on either collector, so a protocol that only some of them reach is a real risk even though a path exists. READY devices are safe to move as-is.

Interpreting results

Result Meaning
PASS Connection succeeded
FAIL Connection refused or timed out — routing or firewall issue
TIMEOUT SNMP only: no UDP response within timeout
- Protocol not expected for this device; skipped

SNMP TIMEOUT

TIMEOUT on SNMP does not necessarily mean the device is unreachable. The probe is a hardcoded SNMPv2c GetRequest with community public — it cannot succeed against anything that isn’t SNMPv2c with that exact community, for two distinct reasons that both present as the identical TIMEOUT:

If ping passes but snmp shows TIMEOUT, check the device’s snmp.community property in LM (v2c) or whether it’s configured for SNMPv3 at all, and verify the collector can reach UDP 161 from the network level. To check a specific device properly, use the collector debug console’s !snmpdiagnose command — it runs a real SNMP get/walk with the actual configured version/community/v3 credentials and gives a specific diagnosis (e.g. “Unknown security name — check snmp.security host property”) instead of a blind TIMEOUT. See collector-debug-notes.md.

WMI (tcp-135)

TCP 135 is the WMI/DCOM endpoint mapper. A passing wmi check means the Windows RPC endpoint is reachable from the new collector, which is the necessary precondition for WMI collection. It is a bare TCP connect test, not a WMI credential check — despite the name, a pass does not mean WMI itself would actually work (see collector-debug-notes.md for !wmi, a real credentialed WMI test — with caveats about when it can and can’t be used for this kind of pre-move check).

meta

Update the ToC on this page by running the following:

gh-md-toc --insert --no-backup --hide-footer --skip-header examples/collector-readiness.md