Find answers to your NQE questions and share NQEs you've developed.
Recently active
In support of ongoing federal cybersecurity and supply-chain risk management initiatives, Forward Networks has developed a streamlined detection workflow for identifying devices manufactured by Huawei, ZTE, TP-Link or any other network device of concern that are within an enterprise or government environment.This proactive measure aligns with Cybersecurity and Infrastructure Security Agency (CISA) guidance and the Federal Zero Trust Architecture (ZTA) implementation goals outlined in OMB Memorandum M-22-09. This capability helps agencies rapidly locate unapproved or unmanaged devices—enhancing visibility, compliance, and operational integrity across complex network infrastructures. What’s Going OnBecause consumer network devices (routers, access points, and embedded network interface components) are widely deployed in home and small-office settings, they may appear in larger networks without full discovery or oversight. These “commercial off-the-shelf” (COTS) components can bypass stan
The default number of results returned for an NQE query executed from the API is 1000 (returned as a list assigned to the key “items”)You can increase the limit to 10,000 items. For retrieving results of more than 10,000 items, you will need to use the limit and offset parameters as part of your script, and concatenate the results of multiple API calls within the script.Below is a simple script in Python that concatenates successive chunks of 10,000 items into a single output:import requestsdef nqe_query_with_offset(): my_result = [] limit= 10000 offset = 0 network_id = "101" url = "https://fwd.app/api/nqe?networkId=" + network_id total_extracted = False while total_extracted == False: payload ={"queryId": "FQ_ac651cb2901b067fe7dbfb511613ab44776d8029", "queryOptions": { "limit": limit, "offset": offset}} print(payload) headers = { 'Content-Type': 'application/json', 'Authorization': 'Basic #KEY#'} response = requests.request("POST", url,
The Framework Regional Variations Determining a Device’s Region Changing Variables Based on Region Knowing the Collection State Anatomy of a test Imports Pattern Matching Function Exceptions Report Putting Tests Together Making NQE Verifications Creating Scorecards Summary Ok, so you make all your configs using Ansible or Netbox Config Templates and are feeling good that you’ve got a consistent configuration everywhere - nice! Having a solid templating system to produce standardized configs is a great first step. But once the devices have been made live on the network, how can we run in-life tests to make sure their configurations have not drifted away from the ‘golden’ one they started out with? Two general approaches might be used for this: Regenerate configs periodically and compare them with the live config. Write specific tests for parts of the configuration (security hardening measures for example) and leave the remainder unchecked. Option 1 is a fairly simple approach
You may often want to find all pattern matches within the device configuration and filter the results based on a regular expression.The following NQE query uses a regex filter as part of a two step process in the getMatch(device) function.First, we find peer-group names in a Cisco BGP configuration and stores each match in a string called groupName by matching on the pattern defined at the top of the query.Second, we iterate through each each pattern match and filter the groupName based on the regex `^PUBLIC.*(?:-4|-X)$`The regex matches a string that starts with the word “PUBLIC” and end with either “-4” or “-X”.The main foreach loop at the bottom of the query applies the function getMatch to output a list of devices along with all the matching peer group names pattern = ```router bgp {number} neighbor {groupName: string} peer-group```;getMatch(device) =foreach match in blockMatches(device.files.config, pattern)let validRegex = re`^PUBLIC.*(?:-4|-X)$`let groupName = match.data.groupNa
You can use the NQE group function to collapse rows that have multiple matching columns.In the following example, we make a list of all devices in the network (and store in a list called data), and group all the devices in data together that have matching values for Vendor, Model, OS, and OS Version. The matching values are grouped by attributes.Note that list stored in data just has device names. We don’t actually list all the device names within the select statement. The device is the identifier for each unique element that is hidden when you use the group function. We access the list of devices in each group (within the list data) with a foreach loop in order to count the unique items and provide a total in the last column./** * @intent List devices grouped by matching Vendor, Model, OS, and Version and the total number of devices in each group. * @description List devices grouped by matching Vendor, Model, OS, and Version and the total number of devices in each group. */foreach dev
This NQE extracts the config for each ACL, accounting for all syntaxes used in Cisco devices. The order is determined by the line number, which is used to compare the line of the deny statement with the last line of the ACL config and returns the failures by device and ACL name.standard(config) = foreach match in patternMatches(config, `access-list {aclName:string} {!"remark"}`) group match.line as config by match.data.aclName as name select { name, config };nested(config) = foreach match in patternMatches(config, `ip access-list {string} {name:string}`) let config = (foreach line in match.line.children where !hasMatch(line.text, re`.*remark.*`) select line) select { name: match.data.name, config };foreach device in network.devicesforeach acl in standard(device.files.config) + nested(device.files.config)let maxLine = max(foreach line in acl.config select line.lineNumber)foreach line in acl.configwhere hasMatch(line.text, re`.*deny\s*ip any any.*`) &&
Hello: Hopefully this isnt a repeat as i couldn’t find the answer on here so I wanted to post it. im trying to match against “tags” within the application, and everything I am tying, regarding the ‘where matches” command is used, isnt working. This is in the regular inventory so i have the statement “foreach device in network.devices” list as well above where i think the match line should go. I can it list the tags, just not match/filter on tags.
In this video, I demonstrate how Forward Enterprise replaces Infoblox NetMRI, which has now reached its Last Order Date (April 30, 2025) and will go end of support in April 2027. Many teams are looking for a solution that not only replaces NetMRI but also takes them far beyond its limitations — and that’s exactly what Forward provides. Here are a few highlights from the video:A true network digital twin: Forward mathematically models your entire environment — devices, topology, and paths — so you can validate intent, detect drift, and troubleshoot with precision. Continuous validation & automation: Changes can be verified before they’re deployed, and misconfigurations are flagged automatically. Multi-vendor and hybrid cloud support: Visibility and assurance across your whole network, whether it’s on-prem, cloud, or hybrid. Certified Infoblox IntegrationWe have a validated integration with Infoblox NIOS DDI. This is especially powerful for NetMRI users because:Network data (su
Avoiding device management being exposed on interfaces to the internet is something that we all want to avoid, but if such an exposure was to occur wouldn’t you want to know?This query inspects all interfaces and specifically checks whether http, https, fgfm (FortiManager), snmp, and SSH are enabled via the set allowaccess command. To run this check you’ll need to configure a custom command.Custom Command Required.show system interfacesThe Query:/** * @intent Do not present fgfm, SSH, HTTPS on the internet ports * @description Check all interfaces that face the internet to ensure * "SSH","HTTPS" and "fgfm" are not present. Example Interface: edit "mgmt1" set vdom "root" set ip 169.254.255.2 255.255.255.255 set allowaccess ping https ssh snmp set status down set type physical set dedicated-to management set role lan set snmp-index 1 next */ifacePattern = ```config system interface edit {ifaceName:string} set ip
This is to discuss a common practice with the use of the interface Description field.It is really common to look at CDP or LLDP and find the neighbor device name, then put that remote device name into the interface Description of the interface that connects these two devices together. It is also common to add the remote device interface as well./** * @intent Verify if the interface description includes the device name of the linked device * @description Use the Link element of the data model to determine the device name and interface * of a networking device that is connected to this interface. * Verify that the remote device name and remote interface an included in the interface Description. */export getL3Interfaces(device: Device) = foreach iface in device.interfaces where length(iface.links) > 0 foreach ifaceIpInfo in getSvis(iface) + getSubIfaces(iface) select { name: ifaceIpInfo.name, adminStatus: ifaceIpInfo.adminStatus, operStatus: ifaceIpInfo.operStatus, ipv
Chinese state-sponsored threat actors are targeting network infrastructure worldwide, leveraging compromised routers and edge devices to establish long-term persistence and exfiltrate sensitive data. A recent joint cybersecurity advisory from NSA, CISA, FBI, and international partners highlights the scale of this threat and provides detailed mitigation guidance.At Forward Networks, we’ve created a purpose-built NQE query to help customers quickly identify two of the most common risks associated with this campaign:Known exploited vulnerabilities used by the threat actors to gain initial access Permissive ACLs that may allow traffic to flow to attacker-controlled IP addresses Why this threat mattersThe campaign—tracked in industry reporting under names such as Salt Typhoon and RedMike—isn’t limited to a single vendor or region. Attackers embed themselves in network devices, sometimes at ISPs or providers, then use those footholds to:Steal authentication information by redirecting TACA
OverviewWorking with IP addresses in NQE opens up all kinds of possibilities, but it’s not always clear what tools are available out of the box. I’ve worked with several customers who wanted to do everything from filtering IPv6 neighbors to calculating subnet utilization across thousands of devices—and the good news is, NQE makes a lot of this simpler than you might expect.In this post, I’m sharing five of my favorite IP address-related techniques that you might not know about, along with tips for using them in your own queries. 1. Use toNumber() to Compare IP AddressesWhen you want to compare IP addresses (e.g., sort them, find the lowest one, etc.), you can use toNumber() to convert each address into a numeric value.Note that this can only be applied to an IPv4 address.toNumber(10.1.2.3) // Converts to an integer based on its position in the full IPv4 rangeThis is useful for identifying router IDs or evaluating address ranges, especially when you don’t know in advance how the addres
In dynamic network environments, engineers often make quick changes directly to a device’s running configuration to resolve issues or apply updates. But if those changes aren’t saved to the startup configuration, they’ll be lost on the next device restart—potentially causing outages or security gaps.This oversight can lead to:Devices booting with outdated configurations Outages and service disruptions Security vulnerabilities if critical policy changes aren’t retained Manually verifying that all running configs are saved can be time-consuming and error-prone, especially in large environments. Forward Networks’ Network Query Engine (NQE) simplifies this process by automatically comparing the running and startup configurations across devices in your network.PrerequisitesAccess to Forward Enterprise with NQE enabled Cisco devices modeled in Forward Networks Network Admin role to create custom commands Add the following Custom Commands (requires Network Admin Role) show startup-
Forward NQE includes several under-the-hood optimizations that can improve query performance. This post focuses on the _lookup optimization, which can reduce execution time when filtering on a single key field using an exact equality comparison. Leveraging _lookup is considered a best practice whenever possible.In a recent query I wrote joining device CVE information with the EPSS database in a network containing 10,000 devices, re-writing the NQE to take advantage of _lookup reduced the execution time by over 50%. While this kind of optimization isn’t as dramatic as parallelization—where a multi-minute query might drop to seconds—it can still offer a significant and worthwhile improvement, particularly in queries with repeated key-based lookups over large lists. What _lookup DoesNormally, when you write a loop in NQE that scans a list for a match, the query engine will iterate over every item in that list and check the condition. This can be slow if the list or number of devices in th
When an NQE runs in parallel, it executes the same logic across all devices in the snapshot inventory simultaneously, rather than one device at a time in sequence. In practice, this can be the difference between a query that risks hitting the 20-minute timeout and one that completes in a fraction of the time. When Parallelization HappensA query will run in parallel if:It starts with an iteration over network.devices It does not access network.devices in any other way (only one iteration) It does not access network.endpoints It does not use the group … by qualifierHow to CheckFrom the NQE IDE:Windows: Alt + left-click Execute Mac: Option + left-click ExecuteIn the debug panel, look for:parallel_foreach device in network.devicesIf you only see foreach device in network.devices, it’s not parallelized.Example 1 — Pass the Device Object, Not Its Name Broken (serial)Passing device.name into a function and then re-looking up the device causes a second iteration over network.devices.getDeviceV
I am looking for for BGP protocol which will show below details: device nameNeighborAddressoutbound Interface descriptionpeerDeviceName peerVrfpeer outbound Interface descriptionsessionState: neighbor.sessionStatepeerType (Internal/External) The one I created, but its not loading:import "@fwd/L3/Interface Utilities"; //getL3Interfaces(device: Device)getPeerInfo(neighbor, sourceRouterId) = max(foreach device in network.devices where device.name == neighbor.peerDeviceName let l3IfaceList = getL3Interfaces(device) foreach networkInstance in device.networkInstances foreach protocol in networkInstance.protocols where isPresent(protocol.bgp) let bgp = protocol.bgp foreach neighbor in bgp.neighbors where neighbor.peerRouterId == sourceRouterId let outIface = max(foreach l3Iface in l3IfaceList foreach address in l3Iface.ipv4.addresses where neighbor.neighborAddress in ipS
The following NQE query lists all the IP addresses that are part of a NAT rule on any device in the network./** * @intent List all NAT entries * @description List all NAT entries, including post NAT IPs */foreach device in network.devicesforeach natEntry in device.natEntrieslet headerMatches = natEntry.headerMatcheslet ipv4SrcSubnets = natEntry.headerMatches.ipv4Srclet ipv4DstSubnets = natEntry.headerMatches.ipv4Dstlet ipv4NatSrcSubnets = (foreach rewrite in natEntry.rewrites select rewrite.ipv4Src)let ipv4NatDstSubnets = (foreach rewrite in natEntry.rewrites select rewrite.ipv4Dst)where isPresent(max(ipv4NatSrcSubnets)) || isPresent(max(ipv4NatDstSubnets))select { deviceName: device.name, "NAT type": natEntry.natType, "Source IP": ipv4SrcSubnets, "Destination IP": ipv4DstSubnets, "Source port start": (foreach tpSr in headerMatches.tpSrc select tpSr.start), "Source port end": (foreach tpSr in headerMatches.tpSrc
I see the filter function and count function shows as unknown functions in NQE query. Please help with appropriate functions for these two. I need to count the total number of interfaces in a devices and interfaces operational status DOWN in state.
I am running a custom command(show interface status) against all Cisco Nexus routers which will show the interface hardware SFP type.How do I get this SFP info through NQE? I am not getting the SPF printed, tried multiple was. Can anyone help me on this. foreach cliCommandResponse in endpoint.cliCommandResponsescliCommandResponse.command == "show interface status"select {endpointName: endpoint.name,command: cliCommandResponse.command,response: cliCommandResponse.response}
For many organizations, the challenge of gaining full visibility into all devices connected to their network goes beyond traditional routers, switches, and firewalls. Non-network devices—such as power controllers, printers, terminal servers and security cameras—are often left out of inventory reports, even though they can pose operational and security risks if unmanaged.This became a critical need for one of our large financial services customers. They required a way to inventory every device on their network, including thousands of non-network endpoints still accessible via SNMP. Their goal? Replace an existing NetBrain solution and consolidate into Forward Networks as their single source of truth.The result is the Endpoints feature—engineered to discover and report on any device Forward can authenticate to via CLI, SNMP, or API. This guide walks you through setting up SNMP Endpoints using real-world configurations and examples. With this workflow, you can generate a comprehensive in
I created this guide to help explain the group by statement in Network Query Engine (NQE), using a real example where I needed to extract CDP neighbor information from Cisco devices. If you're trying to clean up duplicate entries or shift your query’s focus from devices to neighbors, this walkthrough should make group by much more approachable. How I think about group byI think about group by as a way to shift the focus of data from one primary association to another. For me, the key is figuring out what information is unique per device and what stays consistent across devices or throughout the network. Using group by, I can take repeated entries (like neighbors showing up on multiple devices) and consolidate them so each shared element appears once, with its associated device-specific details grouped alongside it.One crucial nuance I’ve learned: after the group by statement, only the variables I explicitly include in the grouping are accessible. So I always make sure to gather everyt
On September 30, 2025, Microsoft will retire the default outbound access method for Azure VMs. This means any new deployments without an explicitly configured egress path (like a NAT gateway or public IP) will no longer have outbound Internet access by default. Why does this matter? Default outbound access is:Implicit and brittle — IPs are assigned by Microsoft and can change without notice Insecure — Opens potential paths to the internet that may go unnoticed Deprecated — Will soon be unavailable for new resources Microsoft recommends using explicit outbound connectivity, such as:Subnets associated with a NAT Gateway VMs in the backend pool of a standard Load Balancer with outbound rules VMs with explicitly assigned public IPs Read Microsoft’s official guidance How to Audit Your Azure Subnets for Missing NAT Gateways With Forward Networks, you can identify Azure subnets that have Internet-bound routes but no associated NAT Gateway — a risky configuration in today’s Zero Trust wor
I am trying to locate all of my fiber 100Mbps interfaces because they are being phased out by various vendors and not supported on newer equipment.The data model has an interface speed value (ethernet.speedMbps) but not seeing a medial type - I can see both inside the interface details however the speed/media is naturally in strings without spaces so challenging to pull out. I was looking to see if both speed and media types were in the data model for a simple NQE vs having to parse out the interface details. Also the interface speed value (ethernet.speedMbps) but it appears that if bandwidth is statically configured, that value is used - on Cisco devices bandwidth can be set to value for protocol calculation but is not necessarily matching the actual interface speed.
Is it possible to write a Forward NQE query that will produce a list of firewall rules that have not been used in the last 90 / 180 / 365 days (based on hit count)? It would be helpful to have firewall name, the rule ID numbers, and last used date/time if possible.
After some digging and working with other FN personnel, it appears that the above mentioned NQE is missing all 17.12, and all 03. IOS versions in the data model for the OS Support NQE report. This was determined first by modifying an NQE to run a check against the OS Support and return violations for those IOS that are no longer supported, which would come back as failed. Good IOS would report as pass. However, the above mentioned IOSs all returned a value of “Indeterminate”. Which then made us look at the OS Support NQE itself and the devices associated with the above/below IOS versions are not listed on the report, but they are in the regular inventory. Known Affected IOS (from our known devices):03.01.0103.07.04E03.11.03a03.11.0503.11.0817.12.0317.12.0417.12.04a17.12.04b
Already have an account? Login
No account yet? Create an account
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.