FortiManager
FortiManager supports network operations use cases for centralized management, best practices compliance, and workflow automation to provide better protection against breaches.
farhanahmed
Staff
Staff
Article Id 399199
Description This article describes how to fetch MAC address of all managed FortiSwitches and their physical ports using FortiManager TCL script and JSON API with Postman.
Scope FortiManager, FortiGate, FortiSwitch.
Solution
  1. Using TCL Script: Follow the first two steps from the article below on how to enable and run TCL scripts in FortiManager: Technical Tip: How to use TCL script...existing route

 

Go to Device Manager -> Scripts, select type TCL Script, and select 'Create new'.

 

Create the following TCL script:

 

proc get_switch_mac_addrs {vdom_name} {
#
# Step 1: Check VDOM status
#
set status [exec "get system status\n" "# " 15]
set vdom_enabled false
if {![regexp {Virtual domain configuration: disable} $status]} {
set vdom_enabled true
}
#
# Step 2: Enter VDOM if enabled
#
if {$vdom_enabled} {
puts "VDOMs are enabled. Entering VDOM: $vdom_name"
exec "end\n" "# " 5
exec "config vdom\nedit $vdom_name\n" "# " 5
exec "config global\n" "# " 5
} else {
puts "VDOMs are disabled. Continuing in default context."
}
#
# Step 3: Get list of managed switches
#
set output [exec "get switch-controller managed-switch\n" "# " 10]
if {$output eq ""} {
puts "No managed switches found."
return
}
#
# Step 4: Get MAC cache output (only once)
#
set mac_cache [exec "diagnose switch-controller mac-cache show\n" "# " 10]
#
# Step 5: Loop through each switch
#
set current_switch ""
foreach line [split $output "\n"] {
if {[regexp {switch-id:\s+(\S+)} $line -> switch_id]} {
puts "\n==========================="
puts " Switch: $switch_id"
puts "==========================="
#
# Find FortiSwitch MAC from mac-cache
#
set current_switch ""
set switch_mac_found 0
foreach cache_line [split $mac_cache "\n"] {
if {[regexp {^managed-switch:\s+(\S+)} $cache_line -> cache_switch]} {
set current_switch $cache_switch
} elseif {[regexp {^4094\s+0\s+([0-9a-fA-F:]+)} $cache_line -> mac]} {
if {$current_switch eq $switch_id} {
puts " FortiSwitch MAC : $mac"
set switch_mac_found 1
}
}
}
if {!$switch_mac_found} {
puts " FortiSwitch MAC : <not found>"
}
#
# Step 6: Get per-port MAC configs
#
set config_output [exec "show switch-controller managed-switch $switch_id\n" "# " 10]
set current_port ""
set port_has_mac 0
foreach cline [split $config_output "\n"] {
if {[regexp {\s+edit\s+"([^"]+)"} $cline -> port]} {
set current_port $port
set port_has_mac 0
} elseif {[regexp {\s+set\s+mac-addr\s+([0-9a-fA-F:]+)} $cline -> port_mac]} {
puts [format " %-7s: %s" $current_port $port_mac]
set port_has_mac 1
} elseif {[regexp {\s+next} $cline]} {
if {$port_has_mac == 0 && $current_port ne ""} {
puts [format " %-7s: <no mac>" $current_port]
}
set current_port ""
}
}
}
}
#
# Step 7: Exit VDOM
#
if {$vdom_enabled} {
exec "end\n" "# " 5
}
}
#
# Call the function with VDOM name — replace "root" if needed
#
get_switch_mac_addrs "root"

 

Note:

  • Using mac-cache (diagnose switch-controller mac-cache show), the scripts get the MAC address of connected FortiSwitches and then the MAC addresses of all physical ports of the FortiSwitch.
  • The script takes into consideration whether VDOMs are enabled on the FortiGate. The default is set to 'root' (set in the last line of the script).
  • The script can run on multiple FortiGates.

 

Sample output:

 

fsw.png

 


 

 

  1. Using JSON API with Postman: The API query below fetches the details of FortiSwitches connected to FortiGate using FortiManager.

 

{
   "method": "get",
   "params": [
      {

         "url": "/pm/config/device/{{DEVICE_NAME}}/vdom/{{VDOM}}/switch-controller/managed-switch"
      }
   ],
   "id": "1",
   "verbose": 1,
   "session": "{{session}}"
}

 

The response output of the query can be extensive depending on the number of switches connected.

 

In Postman, Script ('Post-run' or in older versions 'Tests') allows the use of JavaScript to show only specific output, in this case mac-addr of switch ports:

 

fsw_api.png

 


Sample script to show output as seen in the image above:

 

let data = pm.response.json();

let html = `

    <style>

        body { font-family: Arial, sans-serif; font-size: 13px; }

        table { width: 100%; border-collapse: collapse; margin-bottom: 20px; }

        th, td { padding: 6px; border: 1px solid #ddd; text-align: left; }

        th { background-color: #f2f2f2; }

        h3 { background-color: #e8e8e8; padding: 8px; border-left: 4px solid #007bff; }

    </style>

`;

(data.result[0].data || []).forEach(switchObj => {

    let sn = switchObj.sn || "Unknown";

    html += `<h3>FortiSwitch Serial: ${sn}</h3>`;

    html += `

        <table>

            <thead>

                <tr>

                    <th>Port Name</th>

                    <th>MAC Address</th>

                    <th>Link Status</th>

                </tr>

            </thead>

            <tbody>

    `;

    (switchObj.ports || []).forEach(port => {

        html += `

            <tr>

                <td>${port["port-name"] || "-"}</td>

                <td>${port["mac-addr"] || "-"}</td>

                <td>${port["link-status"] || "-"}</td>

            </tr>

        `;

    });

    html += `</tbody></table>`;

});

pm.visualizer.set(html);

 

Related documents:

Tcl scripts.

Postman Scripts.

Technical Tip: How to troubleshoot TCL Scripts failed in FortiManager.

Technical Tip: How to fetch FortiAP and FortiSwitch Serials using TCL Script in FortiManager.