Schlagwort-Archive: inventory

Commandline Tool for exporting Cisco hardware inventory via SNMP

This tool exports every hardware asset from an Cisco device with a serial number. You can export the list as table or CSV.

Download: https://gist.github.com/lanbugs/4dbed5e0e8a7d5b6d29c4ea9b9e93bb2

>python cisco_inventory.py -h
usage: cisco_inventory.py [-h] -H HOST -v SNMP_VERSION [-C SNMP_COMMUNITY]
                          [-u SNMP_USER] [-A SNMP_AUTH] [-a SNMP_AUTH_METHOD]
                          [-X SNMP_PRIVACY] [-x SNMP_PRIVACY_METHOD]
                          [-L SNMP_SECURITY] [--csv]

Cisco inventory grabber Version 0.1 Written by Maximilian Thoma 2018

optional arguments:
  -h, --help            show this help message and exit
  -H HOST               WLC IP address
  -v SNMP_VERSION       SNMP version, valid are 2 or 3
  -C SNMP_COMMUNITY     SNMP Community (only v2)
  -u SNMP_USER          SNMP user (v3)
  -A SNMP_AUTH          SNMP auth password (v3)
  -a SNMP_AUTH_METHOD   SNMP auth method, valid are MD5 or SHA (v3)
  -X SNMP_PRIVACY       SNMP privacy password (v3)
  -x SNMP_PRIVACY_METHOD
                        SNMP privacy method, valid are AES or DES (v3)
  -L SNMP_SECURITY      SNMP security level, valid are no_auth_or_privacy,
                        auth_without_privacy or auth_with_privacy (v3)
  --csv                 Result should be CSV

Demo;

>python cisco_inventory.py -H 10.10.10.33 -v 3 -u snmpuser -A snmpauth -a MD5 -X snmpencr -x DES -L auth_with_privacy
| Description                                            | Class       | Name                                   | HWRev   | FWRev       | SWRev      | Serial           | Manufactor          | Model          | FRU?   |
|--------------------------------------------------------+-------------+----------------------------------------+---------+-------------+------------+------------------+---------------------+----------------+--------|
| 1000BaseSX                                             | -           | GigabitEthernet1/4/12                  | V01     |             |            | FNS11111111      | CISCO               | GLC-SX-MMD     | true   |
| 1000BaseSX                                             | -           | GigabitEthernet1/4/11                  | V01     |             |            | FNS11111111      | CISCO               | GLC-SX-MMD     | true   |
| 1000BaseSX                                             | -           | GigabitEthernet1/4/10                  | V01     |             |            | FNS11111111      | CISCO               | GLC-SX-MMD     | true   |
| 1000BaseSX                                             | -           | GigabitEthernet1/4/11                  | V01     |             |            | FNS11111111      | CISCO               | GLC-SX-MMD     | true   |
| 1000BaseSX                                             | -           | GigabitEthernet1/3/8                   | V01     |             |            | FNS11111111      | CISCO               | GLC-SX-MMD     | true   |
| 1000BaseSX                                             | -           | GigabitEthernet1/3/9                   | V01     |             |            | FNS11111111      | CISCO               | GLC-SX-MMD     | true   |
| 1000BaseSX                                             | -           | GigabitEthernet1/3/6                   | V01     |             |            | FNS11111111      | CISCO               | GLC-SX-MMD     | true   |
| 1000BaseSX                                             | -           | GigabitEthernet1/3/7                   | V01     |             |            | FNS11111111      | CISCO               | GLC-SX-MMD     | true   |
| 1000BaseSX                                             | -           | GigabitEthernet2/3/10                  | V01     |             |            | FNS11111111      | CISCO               | GLC-SX-MMD     | true   |
| 1000BaseX (SFP) with 12 SFP Ports Jumbo Frame Support  | module      | Switch1 Linecard 4 (virtual slot 4)    | V02     |             |            | FNS11111111      | Cisco               | WS-X4612-SFP-E | true   |
| 1000BaseX (SFP) with 12 SFP Ports Jumbo Frame Support  | module      | Switch1 Linecard 3 (virtual slot 3)    | V02     |             |            | FNS11111111      | Cisco               | WS-X4612-SFP-E | true   |
| Cisco Systems, Inc. WS-C4506-E 6 slot switch           | chassis     | Switch1 System                         | V03     |             |            | FNS11111111      | Cisco               | WS-C4506-E     | false  |
| FanTray                                                | fan         | Switch2 FanTray 1                      | V04     |             |            | FNS11111111      | Cisco               | WS-X4596-E     | true   |
| Power Supply ( AC 1400W )                              | powerSupply | Switch2 Power Supply 1                 | V04     |             |            | FNS11111111      | Cisco Systems, Inc. | PWR-C45-1400AC | true   |
| Power Supply ( AC 1400W )                              | powerSupply | Switch2 Power Supply 2                 | V04     |             |            | FNS11111111      | Cisco Systems, Inc. | PWR-C45-1400AC | true   |
| SFP-10Gbase-SR                                         | -           | TenGigabitEthernet1/1/1                | V03     |             |            | FNS11111111      | CISCO-FINISAR       | SFP-10G-SR     | true   |
| SFP-10Gbase-SR                                         | -           | TenGigabitEthernet1/1/2                | V03     |             |            | FNS11111111      | CISCO-FINISAR       | SFP-10G-SR     | true   |
| Sup 7L-E 10GE (SFP+), 1000BaseX (SFP) with 4 SFP Ports | module      | Switch1 Supervisor 1 (virtual slot 1)  | V01     | 15.0(1r)SG3 | 03.06.03.E | FNS11111111      | Cisco               | WS-X45-SUP7L-E | true   |

 

Script:

#!/usr/bin/env python

# Need following pip packages
# - easysnmp
# - tabulate

# Checkout blog article to tool
# https://lanbugs.de/netzwerktechnik/hersteller/cisco/commandline-tool-for-exporting-cisco-hardware-inventory-via-snmp/


from easysnmp import Session
import argparse
from tabulate import tabulate
from operator import itemgetter
from pprint import pprint

def main():
    ####
    # ARGS
    ####
    description = """
    Cisco inventory grabber\nVersion 0.1\nWritten by Maximilian Thoma 2018
    """

    aparser = argparse.ArgumentParser(description=description)
    aparser.add_argument('-H', dest='host', help='WLC IP address', required=True)
    aparser.add_argument('-v', dest='snmp_version', help='SNMP version, valid are 2 or 3', required=True)
    aparser.add_argument('-C', dest='snmp_community', help='SNMP Community (only v2)')
    aparser.add_argument('-u', dest='snmp_user', help='SNMP user (v3)')
    aparser.add_argument('-A', dest='snmp_auth', help='SNMP auth password (v3)')
    aparser.add_argument('-a', dest='snmp_auth_method', help='SNMP auth method, valid are MD5 or SHA (v3)')
    aparser.add_argument('-X', dest='snmp_privacy', help='SNMP privacy password (v3)')
    aparser.add_argument('-x', dest='snmp_privacy_method', help='SNMP privacy method, valid are AES or DES (v3)')
    aparser.add_argument('-L', dest='snmp_security',
                         help='SNMP security level, valid are no_auth_or_privacy, auth_without_privacy or auth_with_privacy (v3)')
    aparser.add_argument('--csv', dest='csv', help='Result should be CSV', action='store_true')
    args = aparser.parse_args()

    ####
    # Setup SNMP connection
    ####

    if args.snmp_version == "2":
        try:
            snmp = Session(hostname=args.host, version=2, use_numeric=True)

        except Exception as e:
            print e

    if args.snmp_version == "3":
        try:
            snmp = Session(
                hostname=args.host,
                version=3,
                security_level=args.snmp_security,
                security_username=args.snmp_user,
                auth_protocol=args.snmp_auth_method,
                auth_password=args.snmp_auth,
                privacy_protocol=args.snmp_privacy_method,
                privacy_password=args.snmp_privacy,
                use_numeric=True
            )

        except Exception as e:
            print e

    ####
    # Init Data Buffer
    ####

    inventory = {}
    inv_print = []

    ####
    # SNMP Walk inventory
    ####

    port = {
    0: "-",
    1: "other",
    2: "unknown",
    3: "chassis",
    4: "backplane",
    5: "container",
    6: "powerSupply",
    7: "fan",
    8: "sensor",
    9: "module",
    10: "port",
    11: "stack",
    12: "cpu"
    
    }

    ## Get inventory
    result_ids = snmp.walk(".1.3.6.1.2.1.47.1.1.1.1")

    def stripper(string):
        if "NoneType" not in str(type(string)):
            return string.strip()
        else:
            return string


    for r in result_ids:
        
        if r.oid_index in inventory:
            element_id = r.oid.replace(".1.3.6.1.2.1.47.1.1.1.1.","")

            if element_id == "16": # fru
                fru = "true" if "1" in r.value else "false"
                inventory[r.oid_index][element_id] = fru

            elif element_id == "5": # class
                classx = port[int(r.value)] if len(r.value) is 1 else port[0]
                inventory[r.oid_index][element_id] = classx

            else: # everything else
                inventory[r.oid_index][element_id] = r.value
            
        else:
            element_id = r.oid.replace(".1.3.6.1.2.1.47.1.1.1.1.","")
            inventory[r.oid_index] = {}
            inventory[r.oid_index][element_id] = r.value
        
    
    
    for elements, values in inventory.iteritems():
        
        if len(values['11']) >= 1:        
            #print elements
            
            #2 entPhysicalDescr
            #3 entPhysicalVendorType
            #4 entPhysicalContainedIn
            #5 entPhysicalClass
            #6 entPhysicalParentRelPos
            #7 entPhysicalName
            #8 entPhysicalHardwareRev
            #9 entPhysicalFirmwareRev
            #10 entPhysicalSoftwareRev
            #11 entPhysicalSerialNum
            #12 entPhysicalMfgName
            #13 entPhysicalModelName
            #14 entPhysicalAlias
            #15 entPhysicalAssetID
            #16 entPhysicalIsFRU
            
            inv_print.append([stripper(values.get('2')),
                              stripper(values.get('5')),
                              stripper(values.get('7')),
                              stripper(values.get('8')),
                              stripper(values.get('9')),
                              stripper(values.get('10')),
                              stripper(values.get('11')),
                              stripper(values.get('12')),
                              stripper(values.get('13')),
                              stripper(values.get('16'))])



    ####
    # Sort table
    ####

    inv = sorted(inv_print, key=itemgetter(0))

    ####
    # Result
    ####

    if args.csv is True:

        print 'Description;Class;Name;HWRev;FWRev;SWRev;Serial;Manufactor;Model;FRU?'
        
        for line in inv:
            print ';'.join(str(l) for l in line)

    else:
        print tabulate(inv, headers=['Description', 'Class', 'Name', 'HWRev', 'FWRev', 'SWRev', 'Serial', 'Manufactor', 'Model', 'FRU?'], tablefmt="orgtbl")


if __name__ == "__main__":
    main()

 

Commandline Tool to export current registered users at APs from an Cisco Wireless LAN Controller (WLC)

This tool exports all current clients on all APs assigned to the WLC. You can export as CSV or as table.

Download: https://gist.github.com/lanbugs/6dc874ad0736424c5c7808f01ec78f96

$ python cisco_ap_clients_grabber.py -h
usage: cisco_ap_clients_grabber.py [-h] -H HOST -v SNMP_VERSION
                                   [-C SNMP_COMMUNITY] [-u SNMP_USER]
                                   [-A SNMP_AUTH] [-a SNMP_AUTH_METHOD]
                                   [-X SNMP_PRIVACY] [-x SNMP_PRIVACY_METHOD]
                                   [-L SNMP_SECURITY] [--csv]

Cisco AP clients grabber Version 0.1 Written by Maximilian Thoma 2017

optional arguments:
  -h, --help            show this help message and exit
  -H HOST               WLC IP address
  -v SNMP_VERSION       SNMP version, valid are 2 or 3
  -C SNMP_COMMUNITY     SNMP Community (only v2)
  -u SNMP_USER          SNMP user (v3)
  -A SNMP_AUTH          SNMP auth password (v3)
  -a SNMP_AUTH_METHOD   SNMP auth method, valid are MD5 or SHA (v3)
  -X SNMP_PRIVACY       SNMP privacy password (v3)
  -x SNMP_PRIVACY_METHOD
                        SNMP privacy method, valid are AES or DES (v3)
  -L SNMP_SECURITY      SNMP security level, valid are no_auth_or_privacy,
                        auth_without_privacy or auth_with_privacy (v3)
  --csv                 Result should be CSV

Demo:

>python cisco_ap_clients_grabber.py -H 1.1.1.1 -v 3 -u username -A authpass -a MD5 -X privpass -x DES -L auth_with_privacy
| IP            | MAC               | Name                               | SSID         | SSID MAC          |
|---------------+-------------------+------------------------------------+--------------+-------------------|
| 10.10.10.1    | C0:FF:EE:C0:FF:EE | host/client0001.m.local            | workstations | DE:AD:BE:EF:00:00 |
| 10.10.10.2    | C0:FF:EE:C0:FF:EE | host/client0002.m.local            | workstations | DE:AD:BE:EF:00:00 |
| 10.10.10.3    | C0:FF:EE:C0:FF:EE | host/client0003.m.local            | workstations | DE:AD:BE:EF:00:00 |
| 10.10.10.4    | C0:FF:EE:C0:FF:EE | host/client0004.m.local            | workstations | DE:AD:BE:EF:00:00 |
| 10.10.10.5    | C0:FF:EE:C0:FF:EE | host/client0005.m.local            | workstations | DE:AD:BE:EF:00:00 |
| 10.10.45.200  | C0:FF:EE:C0:FF:EE |                                    | guests       | DE:AD:BE:EF:00:00 |
| 10.10.45.201  | C0:FF:EE:C0:FF:EE |                                    | guests       | DE:AD:BE:EF:00:00 |
| 10.10.45.202  | C0:FF:EE:C0:FF:EE |                                    | guests       | DE:AD:BE:EF:00:00 |
| 10.10.45.203  | C0:FF:EE:C0:FF:EE |                                    | guests       | DE:AD:BE:EF:00:00 |
| 10.10.45.204  | C0:FF:EE:C0:FF:EE |                                    | guests       | DE:AD:BE:EF:00:00 |
| 10.10.45.205  | C0:FF:EE:C0:FF:EE |                                    | guests       | DE:AD:BE:EF:00:00 |
| 10.10.45.206  | C0:FF:EE:C0:FF:EE |                                    | guests       | DE:AD:BE:EF:00:00 |

Script:

#!/usr/bin/env python

# Need following pip packages
# - easysnmp
# - tabulate

# Checkout blog article to tool
# https://lanbugs.de/netzwerktechnik/commandline-tool-to-export-current-registered-users-at-aps-from-an-cisco-wireless-lan-controller-wlc/

from easysnmp import Session
import argparse
from tabulate import tabulate
from operator import itemgetter


def main():
    ####
    # ARGS
    ####
    description = """
    Cisco AP clients grabber\nVersion 0.1\nWritten by Maximilian Thoma 2018
    """

    aparser = argparse.ArgumentParser(description=description)
    aparser.add_argument('-H', dest='host', help='WLC IP address', required=True)
    aparser.add_argument('-v', dest='snmp_version', help='SNMP version, valid are 2 or 3', required=True)
    aparser.add_argument('-C', dest='snmp_community', help='SNMP Community (only v2)')
    aparser.add_argument('-u', dest='snmp_user', help='SNMP user (v3)')
    aparser.add_argument('-A', dest='snmp_auth', help='SNMP auth password (v3)')
    aparser.add_argument('-a', dest='snmp_auth_method', help='SNMP auth method, valid are MD5 or SHA (v3)')
    aparser.add_argument('-X', dest='snmp_privacy', help='SNMP privacy password (v3)')
    aparser.add_argument('-x', dest='snmp_privacy_method', help='SNMP privacy method, valid are AES or DES (v3)')
    aparser.add_argument('-L', dest='snmp_security',
                         help='SNMP security level, valid are no_auth_or_privacy, auth_without_privacy or auth_with_privacy (v3)')
    aparser.add_argument('--csv', dest='csv', help='Result should be CSV', action='store_true')
    args = aparser.parse_args()

    ####
    # Setup SNMP connection
    ####

    if args.snmp_version == "2":
        try:
            snmp = Session(hostname=args.host, version=2, use_numeric=True)

        except Exception as e:
            print e

    if args.snmp_version == "3":
        try:
            snmp = Session(
                hostname=args.host,
                version=3,
                security_level=args.snmp_security,
                security_username=args.snmp_user,
                auth_protocol=args.snmp_auth_method,
                auth_password=args.snmp_auth,
                privacy_protocol=args.snmp_privacy_method,
                privacy_password=args.snmp_privacy,
                use_numeric=True
            )

        except Exception as e:
            print e

    ####
    # Init Data Buffer
    ####

    inventory = []
    longids = []

    ####
    # SNMP Walk Clients inventory
    ####

    ## Get longids for clients
    result_longids = snmp.walk(".1.3.6.1.4.1.14179.2.1.4.1.1")

    for rl in result_longids:
        longids.append(rl.oid.replace(".1.3.6.1.4.1.14179.2.1.4.1.1.", "") + "." + rl.oid_index)

    ## Collect informations

    for id in longids:
        # Client MAC
        result_mac = snmp.get(".1.3.6.1.4.1.14179.2.1.4.1.1." + id)
        mac = ":".join(["%02s" % hex(ord(m))[2:] for m in result_mac.value]).replace(' ', '0').upper()

        # Client Name
        name = snmp.get(".1.3.6.1.4.1.14179.2.1.4.1.3." + id).value

        # Client IP
        ip = snmp.get(".1.3.6.1.4.1.14179.2.1.4.1.2." + id).value

        # SSID
        ssid = snmp.get(".1.3.6.1.4.1.14179.2.1.4.1.7." + id).value

        # SSID MAC
        result_ssid_mac = snmp.get(".1.3.6.1.4.1.14179.2.1.4.1.4." + id)
        ssid_mac = ":".join(["%02s" % hex(ord(m))[2:] for m in result_ssid_mac.value]).replace(' ', '0').upper()

        inventory.append([ip, mac, name, ssid, ssid_mac])

    ###
    # Sort table
    ####

    inv = sorted(inventory, key=itemgetter(0))

    ####
    # Result
    ####

    if args.csv is True:

        print 'IP;MAC;Name;SSID;SSID MAC'

        for ip, mac, name, ssid, ssid_mac in inv:
            print '%s;%s;%s;%s;%s' % (ip, mac, name, ssid, ssid_mac)

    else:
        print tabulate(inv, headers=["IP", "MAC", "Name", "SSID", "SSID MAC"], tablefmt="orgtbl")


if __name__ == "__main__":
    main()

 

 

CLI Tool – Export AP inventory from an Cisco Wireless LAN Controller (WLC)

This tool exports the complete AP inventory from an Cisco WLC. You can create an CSV export or an table.

Download: https://gist.github.com/lanbugs/e86042c0b2afaf7166637a9aa9711cb6

$ python cisco_wlc_ap_grabber.py -h
usage: cisco_wlc_ap_grabber.py [-h] -H HOST -v SNMP_VERSION
                               [-C SNMP_COMMUNITY] [-u SNMP_USER]
                               [-A SNMP_AUTH] [-a SNMP_AUTH_METHOD]
                               [-X SNMP_PRIVACY] [-x SNMP_PRIVACY_METHOD]
                               [-L SNMP_SECURITY] [--csv]

Cisco AP WLC inventory grabber Version 0.1 Written by Maximilian Thoma 2017

optional arguments:
  -h, --help            show this help message and exit
  -H HOST               WLC IP address
  -v SNMP_VERSION       SNMP version, valid are 2 or 3
  -C SNMP_COMMUNITY     SNMP Community (only v2)
  -u SNMP_USER          SNMP user (v3)
  -A SNMP_AUTH          SNMP auth password (v3)
  -a SNMP_AUTH_METHOD   SNMP auth method, valid are MD5 or SHA (v3)
  -X SNMP_PRIVACY       SNMP privacy password (v3)
  -x SNMP_PRIVACY_METHOD
                        SNMP privacy method, valid are AES or DES (v3)
  -L SNMP_SECURITY      SNMP security level, valid are no_auth_or_privacy,
                        auth_without_privacy or auth_with_privacy (v3)
  --csv                 Result should be CSV

Demo result:

>python cisco_wlc_ap_grabber.py -H 1.1.1.1 -v 3 -u username -A authpass -a MD5 -X privpass -x DES -L auth_with_privacy

| Name        | IP            | MAC               | Model             | Serialnumber   |
|-------------+---------------+-------------------+-------------------+----------------|
| dexxx-acp01 | 10.10.100.1   | 64:F6:9D:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp02 | 10.11.100.2   | 58:97:1E:C0:FF:EE | AIR-LAP1142N-E-K9 | FCZ11111111    |
| dexxx-acp03 | 10.11.100.3   | 34:DB:FD:C0:FF:EE | AIR-CAP1602I-E-K9 | FGL11111111    |
| dexxx-acp04 | 10.11.100.4   | 58:97:1E:C0:FF:EE | AIR-LAP1142N-E-K9 | FCZ11111111    |
| dexxx-acp05 | 10.11.100.5   | 64:F6:9D:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp06 | 10.11.100.6   | 40:F4:EC:C0:FF:EE | AIR-LAP1142N-E-K9 | FCZ11111111    |
| dexxx-acp07 | 10.11.100.7   | 0C:27:24:C0:FF:EE | AIR-CAP1602I-E-K9 | FGL11111111    |
| dexxx-acp08 | 10.11.100.8   | 00:78:88:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp09 | 10.11.100.9   | 40:F4:EC:C0:FF:EE | AIR-LAP1142N-E-K9 | FCZ11111111    |
| dexxx-acp10 | 10.11.100.10  | 44:AD:D9:C0:FF:EE | AIR-CAP1602I-E-K9 | FGL11111111    |
| dexxx-acp11 | 10.11.100.11  | 50:0F:80:C0:FF:EE | AIR-AP2802I-E-K9  | FDW11111111    |
| dexxx-acp12 | 10.11.100.12  | 74:A0:2F:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp13 | 10.11.100.13  | 0C:85:25:C0:FF:EE | AIR-LAP1142N-E-K9 | FCZ11111111    |
| dexxx-acp14 | 10.11.100.14  | 74:A0:2F:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp15 | 10.11.100.15  | 64:F6:9D:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp16 | 10.11.100.16  | C0:62:6B:C0:FF:EE | AIR-LAP1142N-E-K9 | FCZ11111111    |
| dexxx-acp17 | 10.11.100.17  | 0C:27:24:C0:FF:EE | AIR-CAP1602I-E-K9 | FGL11111111    |
| dexxx-acp18 | 10.11.100.18  | CC:16:7E:C0:FF:EE | AIR-CAP1702I-E-K9 | FCW11111111    |
| dexxx-acp19 | 10.11.100.19  | 64:F6:9D:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp20 | 10.11.100.20  | 64:F6:9D:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp21 | 10.11.100.21  | 64:F6:9D:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp22 | 10.11.100.22  | E4:AA:5D:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp23 | 10.11.100.23  | F4:CF:E2:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp24 | 10.11.100.24  | 00:FE:C8:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp25 | 10.11.100.25  | F4:CF:E2:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp26 | 10.11.100.26  | 00:FE:C8:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp27 | 10.11.100.27  | 64:F6:9D:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp28 | 10.11.100.28  | 64:F6:9D:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |
| dexxx-acp29 | 10.11.100.29  | 64:F6:9D:C0:FF:EE | AIR-CAP1702I-E-K9 | FCZ11111111    |

Script:

#!/usr/bin/env python

# Need following pip packages
# - easysnmp
# - tabulate

# Checkout blog article to tool
# https://lanbugs.de/netzwerktechnik/hersteller/cisco/cli-tool-export-ap-inventory-from-an-cisco-wireless-lan-controller-wlc/


from easysnmp import Session
import argparse
from tabulate import tabulate
from operator import itemgetter


def main():
    ####
    # ARGS
    ####
    description = """
    Cisco AP WLC inventory grabber\nVersion 0.1\nWritten by Maximilian Thoma 2017
    """

    aparser = argparse.ArgumentParser(description=description)
    aparser.add_argument('-H', dest='host', help='WLC IP address', required=True)
    aparser.add_argument('-v', dest='snmp_version', help='SNMP version, valid are 2 or 3', required=True)
    aparser.add_argument('-C', dest='snmp_community', help='SNMP Community (only v2)')
    aparser.add_argument('-u', dest='snmp_user', help='SNMP user (v3)')
    aparser.add_argument('-A', dest='snmp_auth', help='SNMP auth password (v3)')
    aparser.add_argument('-a', dest='snmp_auth_method', help='SNMP auth method, valid are MD5 or SHA (v3)')
    aparser.add_argument('-X', dest='snmp_privacy', help='SNMP privacy password (v3)')
    aparser.add_argument('-x', dest='snmp_privacy_method', help='SNMP privacy method, valid are AES or DES (v3)')
    aparser.add_argument('-L', dest='snmp_security',
                         help='SNMP security level, valid are no_auth_or_privacy, auth_without_privacy or auth_with_privacy (v3)')
    aparser.add_argument('--csv', dest='csv', help='Result should be CSV', action='store_true')
    args = aparser.parse_args()

    ####
    # Setup SNMP connection
    ####

    if args.snmp_version == "2":
        try:
            snmp = Session(hostname=args.host, version=2, use_numeric=True)

        except Exception as e:
            print e

    if args.snmp_version == "3":
        try:
            snmp = Session(
                hostname=args.host,
                version=3,
                security_level=args.snmp_security,
                security_username=args.snmp_user,
                auth_protocol=args.snmp_auth_method,
                auth_password=args.snmp_auth,
                privacy_protocol=args.snmp_privacy_method,
                privacy_password=args.snmp_privacy,
                use_numeric=True
            )

        except Exception as e:
            print e

    ####
    # Init Data Buffer
    ####

    inventory = []
    longids = []

    ####
    # SNMP Walk AP Inventory
    ####

    ## Get longids for APs
    result_longids = snmp.walk(".1.3.6.1.4.1.14179.2.2.1.1.1")

    for rl in result_longids:
        longids.append(rl.oid.replace(".1.3.6.1.4.1.14179.2.2.1.1.1.", "") + "." + rl.oid_index)

    ## Collect informations

    for id in longids:
        # MAC
        result_mac = snmp.get(".1.3.6.1.4.1.14179.2.2.1.1.1." + id)
        mac = ":".join(["%02s" % hex(ord(m))[2:] for m in result_mac.value]).replace(' ', '0').upper()

        # Name
        name = snmp.get(".1.3.6.1.4.1.14179.2.2.1.1.3." + id).value

        # IP
        ip = snmp.get(".1.3.6.1.4.1.14179.2.2.1.1.19." + id).value

        # SN
        sn = snmp.get(".1.3.6.1.4.1.14179.2.2.1.1.17." + id).value

        # Model
        model = snmp.get(".1.3.6.1.4.1.14179.2.2.1.1.16." + id).value

        inventory.append([name, ip, mac, model, sn])

    ###
    # Sort table
    ####

    inv = sorted(inventory, key=itemgetter(0))

    ####
    # Result
    ####

    if args.csv is True:

        print 'Name;IP;MAC;Model;Serialnumber'

        for name, ip, mac, model, sn in inv:
            print '%s;%s;%s;%s;%s' % (name, ip, mac, model, sn)

    else:
        print tabulate(inv, headers=["Name", "IP", "MAC", "Model", "Serialnumber"], tablefmt="orgtbl")


if __name__ == "__main__":
    main()