Hook Scripts
Hook scripts are NXSL scripts stored in the Script Library with names prefixed by Hook::. The NetXMS server calls them automatically at specific points during its operation. They allow you to customize server behavior without modifying the core product.
Hook scripts are pre-created in the Script Library during server initialization. To customize a hook, edit the corresponding script in Configuration → Script Library. An empty hook script is ignored by the server.
Polling Hooks
These hooks execute during their respective polling cycles (most of them at the end of the poll). They receive the polled object as $object; $node is additionally set when the polled object is a node, $isCluster is always set (true when the object is a cluster), and $map is additionally set when the object is a network map. Status and configuration polls also run for clusters, sensors, and other pollable objects — in those cases $node is not defined. Access points and wireless domains run only Hook::ConfigurationPoll, not Hook::StatusPoll. These hooks are useful for custom post-poll processing, logging, or side effects.
Use PollerTrace() to send diagnostic messages to the polling trace output.
Hook::StatusPoll
Executes at the end of each status poll cycle.
| Item | Details |
|---|---|
Fires |
After status poll completes for a pollable object (Node, Cluster, Sensor, etc.). Does not fire for access points and wireless domains — those run only |
Object context |
The polled object ( |
Return value |
Not used |
// Log status changes to persistent storage
if ($node.status != ReadPersistentStorage("lastStatus:" .. $node.name))
{
WritePersistentStorage("lastStatus:" .. $node.name, $node.status);
PollerTrace("Status changed to " .. $node.status);
}
Hook::ConfigurationPoll
Executes during each configuration poll, after capability and interface discovery but before automatic template and container binding. For access points the hook runs at the start of the poll.
| Item | Details |
|---|---|
Fires |
During configuration poll for Node, AccessPoint, WirelessDomain, Cluster, Sensor, cloud domain, or traffic observer objects — after capability and interface discovery but before automatic template and container binding (for access points, at the start of the poll) |
Object context |
The polled object ( |
Return value |
Not used |
// Set custom attribute based on discovered platform
if ($node.platformName ~= "^linux")
$node.setCustomAttribute("os_family", "Linux");
Hook::InstancePoll
Executes at the end of each instance discovery poll cycle.
| Item | Details |
|---|---|
Fires |
After instance discovery poll completes for a data collection target. Runs only when the target is reachable — the poll is aborted (and the hook skipped) when the target is unreachable |
Object context |
The polled object ( |
Return value |
Not used |
Hook::TopologyPoll
Executes at the end of each topology poll cycle.
| Item | Details |
|---|---|
Fires |
After topology poll completes for a Node |
Object context |
The polled Node ( |
Return value |
Not used |
Hook::DiscoveryPoll
Executes at the end of each discovery poll cycle.
| Item | Details |
|---|---|
Fires |
After network discovery poll completes for a Node |
Object context |
The polled Node ( |
Return value |
Not used |
Hook::DiscoveryFilter
Evaluates whether a discovered node should be created, after the host has been contacted and its capabilities determined. This hook runs in Stage 2 of the discovery flow (see Network Discovery) — after reachability checks, capability probing, and protocol filtering.
Unlike Hook::AcceptNewNode which only has IP/MAC information, this hook receives a DiscoveredNode object with full details about the discovered device.
| Item | Details |
|---|---|
Fires |
During network discovery Stage 2, after capabilities are gathered |
Object context |
None |
Script arguments |
|
Additional variables |
|
Return value |
|
Default |
|
The DiscoveredNode object provides the following attributes:
| Attribute | Description |
|---|---|
|
IP address as string |
|
IP address as InetAddress object |
|
Network mask (prefix length) |
|
Subnet address as string |
|
Zone UIN |
|
Zone object (or |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Agent version string (empty if no agent) |
|
Platform name as reported by agent (empty if no agent) |
|
SNMP sysObjectID as string |
|
SNMP version (0=v1, 1=v2c, 3=v3) |
|
DNS name resolved from IP address (or |
|
Array of |
Each DiscoveredInterface object has:
| Attribute | Description |
|---|---|
|
Interface name |
|
Interface alias |
|
Interface description |
|
Interface SNMP index |
|
Interface type |
|
MAC address as string |
|
Array of InetAddress objects |
|
Interface speed |
|
Interface MTU |
|
|
|
Physical location identifiers |
// Accept only SNMP devices that are routers or bridges
if ($node.isSNMP && ($node.isRouter || $node.isBridge))
return true;
return false;
Object Lifecycle Hooks
These hooks fire when objects are created, modified, or deleted.
Hook::AcceptNewNode
Evaluates whether a newly discovered IP address should become a Node object. This is one of the most commonly used hooks for controlling automatic network discovery.
| Item | Details |
|---|---|
Fires |
During network discovery, before creating a new Node from a discovered address |
Object context |
None (no |
Predefined variables |
|
Return value |
Only an explicit |
Default |
|
// Only accept nodes from specific subnets
if ($ipAddr ~= "^10\.1\." || $ipAddr ~= "^192\.168\.5\.")
return true;
return false;
Hook::PostObjectCreate
Executes immediately after a new object is created and inserted into the server’s in-memory object index. The database write happens later, asynchronously.
| Item | Details |
|---|---|
Fires |
After a new object of any type is created (manually or automatically) |
Object context |
The newly created object ( |
Return value |
Not used |
// Send notification when new node is created
if (classof($object) == "Node")
SendNotification("SMTP-Text", "[email protected]", "New node created", "New node created: " .. $object.name);
The first argument of SendNotification() must name an existing notification channel (SMTP-Text exists on default installations); notifications sent to unknown channel names are silently dropped.
Hook::ObjectDelete
Executes when an object is about to be deleted, before the deletion occurs.
| Item | Details |
|---|---|
Fires |
Before an object of any type is deleted |
Object context |
The object being deleted ( |
Return value |
Not used |
// Log object deletion
trace(1, "Object deleted: " .. $object.name .. " (ID: " .. $object.id .. ")");
Hook::CreateInterface
Evaluates whether an automatically discovered interface should be created as an object. Only called for interfaces discovered during polling, not for manually created interfaces.
| Item | Details |
|---|---|
Fires |
During configuration poll, when a new interface is discovered on a Node |
Object context |
The parent Node ( |
Script arguments |
|
Return value |
|
Default |
|
// Skip virtual and loopback interfaces
if ($1.name ~= "^(lo|veth|docker|br-|virbr)")
return false;
return true;
Hook::UpdateInterface
Executes when an existing interface is updated during configuration polling (properties changed, port location updated, etc.).
| Item | Details |
|---|---|
Fires |
During configuration poll, when an existing interface’s properties change |
Object context |
The parent Node ( |
Predefined variables |
|
Script arguments |
|
Return value |
Not used |
Hook::CreateSubnet
Evaluates whether an automatically discovered subnet should be created as an object.
| Item | Details |
|---|---|
Fires |
During configuration poll, when a new subnet is derived from node interface addresses |
Object context |
The parent Node ( |
Script arguments |
|
Return value |
|
Default |
|
// Do not create /32 or /128 subnets
if ($1.ipAddress.mask == 32 || $1.ipAddress.mask == 128)
return false;
return true;
Event and Alarm Hooks
Hook::EventProcessor
Executes for every event before it enters Event Processing Policy (EPP) rule evaluation. Can be used to modify events, add tags, or perform pre-processing logic.
| Item | Details |
|---|---|
Fires |
After event creation and correlation, before EPP rules process the event |
Object context |
The event source object ( |
Predefined variables |
|
Return value |
Not used |
// Add a tag to all events from a specific zone
if ($node != null && $node.zoneUIN == 5)
$event.addTag("remote-site");
Hook::AlarmStateChange
Executes when an existing alarm changes state (updated, acknowledged, resolved, or terminated). It does not fire on alarm creation. Runs asynchronously in a background thread.
| Item | Details |
|---|---|
Fires |
When an existing alarm transitions between states (not on alarm creation) |
Object context |
None (runs asynchronously without object context) |
Predefined variables |
|
Return value |
Not used |
// Log alarm state changes to persistent storage
WritePersistentStorage(
"alarm_log:" .. $alarm.id,
$alarm.state .. ":" .. GetCurrentTime()
);
Tunnel Hooks
Hook::OpenBoundTunnel
Executes when an agent tunnel is established and the agent is bound to a known Node.
| Item | Details |
|---|---|
Fires |
When a bound agent tunnel connects |
Object context |
The Node the tunnel is bound to ( |
Predefined variables |
|
Return value |
Not used |
Hook::OpenUnboundTunnel
Executes when an agent tunnel is established but the agent is not bound to any Node.
| Item | Details |
|---|---|
Fires |
When an unbound agent tunnel connects |
Object context |
None (no |
Predefined variables |
|
Return value |
Not used |
// Log unbound tunnel connections for review
trace(1, "Unbound tunnel from " .. $tunnel.systemName ..
" (" .. $tunnel.address .. ")");
Authentication and User Hooks
Hook::Login
Evaluates whether a user login attempt should be allowed. Runs after standard authentication succeeds but before the session is fully established.
| Item | Details |
|---|---|
Fires |
After successful authentication, before session creation |
Object context |
None (no |
Predefined variables |
|
Return value |
|
// Block login outside business hours (8:00-18:00)
t = DateTime(time());
if (t.hour < 8 || t.hour >= 18)
{
if ($user.name != "admin")
return false;
}
return true;
Hook::LDAPSynchronization
Evaluates each LDAP object during user/group synchronization. Can filter which LDAP users and groups are synchronized into NetXMS.
| Item | Details |
|---|---|
Fires |
For each LDAP user or group found during LDAP synchronization |
Object context |
None (no |
Predefined variables |
|
Return value |
|
// Only sync users whose login name starts with "it_"
if ($ldapObject.isUser)
{
if (not ($ldapObject.loginName ~= "^it_"))
return false;
}
return true;
Configuration Backup Hook
Hook::RegisterForConfigurationBackup
Determines whether a node should be registered for device configuration backup via the external backup API. Evaluated during configuration polls.
| Item | Details |
|---|---|
Fires |
During configuration poll, when evaluating node for backup registration |
Object context |
The polled Node ( |
Return value |
|
Default |
|
// Register only SNMP routers for configuration backup
return $node.isSNMP && $node.isRouter;
Common Patterns
Using PollerTrace in Poll Hooks
Poll hooks can send diagnostic messages to the poller trace output visible in the management console:
// In Hook::ConfigurationPoll
PollerTrace("Custom hook: checking compliance...");
if ($node.customAttributes["compliance_status"] == null)
{
$node.setCustomAttribute("compliance_status", "unchecked");
PollerTrace("Custom hook: set initial compliance status");
}
See PollerTrace() for details.
Error Handling
If a hook script that returns a boolean encounters a runtime error:
-
For filter hooks (
CreateInterface,CreateSubnet,AcceptNewNode,DiscoveryFilter,RegisterForConfigurationBackup): the object creation is blocked (treated as rejection) -
For
Hook::LoginandHook::LDAPSynchronization: only an explicitfalsereturn blocks the operation — a runtime error (like anullreturn) does not block -
For informational hooks (
StatusPoll,ConfigurationPoll, etc.): the error is logged and the poll continues normally
See Also
-
Script Execution Contexts — all contexts where NXSL scripts run
-
Script Security — trusted node validation
-
PollerTrace() — sending messages to poller trace output