{"id":2229,"date":"2010-10-11T01:55:15","date_gmt":"2010-10-11T07:55:15","guid":{"rendered":"http:\/\/gregsowell.com\/?p=2229"},"modified":"2010-10-18T07:37:45","modified_gmt":"2010-10-18T13:37:45","slug":"parse-your-cisco-devices-to-reconcile-customer-information","status":"publish","type":"post","link":"https:\/\/gregsowell.com\/?p=2229","title":{"rendered":"Parse Your Cisco Devices To Reconcile Customer Information"},"content":{"rendered":"<p>Since I work for a datacenter, we have a LOT of ports.  Our customers hang off of a handful of pieces of equipment, but we have a lot of density on these devices.  Every so often we run the numbers for how much bandwidth is subscribed to each customer as well as how much are they contracted for.  We also check to see how much bandwidth we have subscribed in total.<\/p>\n<p>As you can imagine, it takes forever and a day to run all this information&#8230;and I just don&#8217;t have the patience for that!  I wrote two scripts.  One goes out to a list of devices, logs in and dumps the configs as well as interface status to a text file.  The second script goes through these and parses out the info and comma separates everything.  I can then take the files and reconcile in just a couple hours&#8230;which is about all the patience I have for paperwork&#8230;hehehe.<\/p>\n<p>Here&#8217;s the first script.  You will need to create a text file for this guy to read devices from.  Name the file devices.txt and put it in the program&#8217;s root folder.  Entries will need to be like below:<br \/>\nIf you are using ACS, make your entry like below:<br \/>\ncore-router-1,1.1.1.1,ACS<\/p>\n<p>If you are just using passwords, then make your entries like this:<br \/>\ncore-router-2,2.2.2.2,password1,password2<\/p>\n<p>You can mix and match passworded devices with ACS devices.<\/p>\n<p>Here are the compiled files if you don&#8217;t want to compile it yourself: <div class=\"wp-block-button\">\n<a  data-e-Disable-Page-Transition=\"true\" class=\"dlm-download-link dlm-download-default wp-block-button__link wp-element-button\" title=\"\" href=\"https:\/\/gregsowell.com?download=5697&amp;tmstv=1784656587\" rel=\"nofollow\" id=\"download-link-5697\" data-redirect=\"false\" >\n\tCisco-Inventory\t(3507 downloads\t)\n<\/a>\n<\/div>\n<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">; this was shamelessly borrowed from the forums...I have no idea who the original poster was!\r\n#include &lt;File.au3&gt;\r\n#include &lt;Array.au3&gt;\r\n#include &lt;GUIConstants.au3&gt;\r\nDirCreate(@ScriptDir &amp; &quot;\\parse&quot;)\r\n$MoveNext = 1\r\n;TCP starten\r\nTCPStartup ()\r\n\r\n;GUI Creation\r\nGuiCreate(&quot;Telnet Client&quot;, 500, 390,-1, -1 )\r\n\r\n;----------&gt; GUI Control Creation Anfang &lt;----------\r\n\r\n    ;Edit Control f\u00fcr Chat Text\r\n    $Edit = GuiCtrlCreateEdit(&quot;&quot;, 10, 10, 480, 330)\r\n\r\n    ;Input Control f\u00fcr Chat Text Eingabe\r\n    $Input = GuiCtrlCreateInput(&quot;&quot;, 10, 360, 480, 20)\r\n\r\n;-----------&gt; GUI Control Creation Ende &lt;-----------\r\n\r\n;GUI sichtbar machen\r\nGUISetState ()\r\nDim $aSwitches, $Connection, $eingabe\r\nIf Not _FileReadToArray(@ScriptDir &amp; &quot;\\devices.txt&quot;,$aSwitches) Then\r\n   MsgBox(4096,&quot;Error&quot;, &quot; Please create the file devices.txt in this folder.  It needs to have the format:&quot; &amp; @CRLF &amp; &quot;Description,IPaddress,ACS for acs clients or Description,IPAddress,Password1,Password2&quot;)\r\n   Exit\r\nEndIf\r\n$UserName = &quot;&quot;\r\nfor $d = 1 to $aSwitches[0]\r\n\tif StringInStr($aSwitches[$d],&quot;,ACS&quot;) &gt; 1 and $UserName == &quot;&quot; Then\r\n\t\t;this guy is an acs device, ask for username and password\r\n\t\t$UserName = InputBox(&quot;username&quot;,&quot;Put your friggin username here&quot;)\r\n\t\t$Password = InputBox(&quot;Password&quot;, &quot;Put your friggin password here&quot;)\r\n\tEndIf\r\nNext\r\nFor $x = 1 to $aSwitches[0]\r\n\t;pull with telnet\r\n\tToolTip($aSwitches[$x],0,0)\r\n\t$MoveNext = 1\r\n\t_PullConfs()\r\nNext\r\n_CleanFiles()\r\n\r\n\r\n\r\nFunc _PullConfs ()\r\n$Connection = TCPConnect ( StringMid($aSwitches[$x],StringInStr($aSwitches[$x],&quot;,&quot;) + 1,StringInStr($aSwitches[$x],&quot;,&quot;,0,2) - StringInStr($aSwitches[$x],&quot;,&quot;) - 1), 23 ) ;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; change the port\r\nIf @error Then Exit\r\n$Uname = 0\r\n$Pword = 0\r\n$More = 0\r\n$MoresHit = 0\r\nWhile 1 = $MoveNext\r\n    $msg = GuiGetMsg()\r\n    If $msg = $GUI_EVENT_CLOSE Then Exit\r\n    $recv = TCPRecv ( $Connection,2048 )\r\n    If $recv &lt;&gt; &quot;&quot; Then\r\n\t\tif StringRight($recv,10) == &quot;Username: &quot; Then\r\n\t\t\t$Uname = 1\r\n\t\tEndIf\r\n\t\tif StringRight($recv,10) == &quot;Password: &quot; Then\r\n\t\t\t$Pword = 1\r\n\t\tEndIf\r\n\t\tif StringRight($recv,10) == &quot; --More-- &quot; Then\r\n\t\t\t$More = 1\r\n\t\tEndIf\r\n\r\n\r\n\t$text = GUICtrlRead ( $Edit )\r\n    GUICtrlSetData ( $Edit,$text &amp; $recv )\r\n    ControlSend ( &quot;Telnet Client&quot;,&quot;&quot;, $Edit, &quot;{ENTER}&quot;)\r\n\tEndIf\r\n\r\n\tif StringRight($recv,1) == &quot;#&quot; Then\r\n\t\tif $MoresHit = 0 Then\r\n\t\t\t$MoresHit = 1\r\n\t\t\t_IssueCommand()\r\n\t\t\tsleep(1800)\r\n\t\t\t$eingabe = &quot;show int | inc Ethernet&quot;\r\n\t\t\tsleep(1000)\r\n\t\t\t_IssueCommand()\r\n\t\telse\r\n\t\t$eingabe = &quot;exit&quot;\r\n\t\t_IssueCommand()\r\n\t\t_WriteFile ()\r\n\t\tGUICtrlSetData ( $Edit,&quot;&quot;)\r\n\t\tTCPCloseSocket($Connection)\r\n\t\t$MoveNext = 0\r\n\t\tEndIf\r\n\tEndIf\r\n\r\n\tif $More == 1 Then\r\n\t\tsleep(100)\r\n\t\t$eingabe = Chr ( 32 )\r\n\t\tTCPSend ( $Connection, $eingabe)\r\n\t\t$More = 0\r\n\tEndIf\r\n\r\n\tif $Uname == 1 Then\r\n\t\t$eingabe = $UserName\r\n\t\t_IssueCommand()\r\n\t\t$Uname = 0\r\n\tEndIf\r\n\r\n\tif $Pword == 1 Then\r\n\t\tif StringInStr($aSwitches[$x],&quot;,ACS&quot;) == 0 Then\r\n\t\t\t$eingabe = StringMid($aSwitches[$x],StringInStr($aSwitches[$x],&quot;,&quot;,0,2) + 1,StringInStr($aSwitches[$x],&quot;,&quot;,0,3) - StringInStr($aSwitches[$x],&quot;,&quot;,0,2) - 1)\r\n\t\t\t_IssueCommand()\r\n\t\t\tsleep(5000)\r\n\t\t\t$eingabe = &quot;en&quot;\r\n\t\t\t_IssueCommand()\r\n\t\t\tsleep(5000)\r\n\t\t\t$eingabe = stringmid($aSwitches[$x],StringInStr($aSwitches[$x],&quot;,&quot;,0,3) + 1)\r\n\t\t\t_IssueCommand()\r\n\t\tElse\r\n\t\t\t$eingabe = $Password\r\n\t\t\tsleep(800)\r\n\t\t\t_IssueCommand()\r\n\t\tEndIf\r\n\t\t$Pword = 0\r\n\t\tsleep(2000)\r\n\t\t$eingabe = @CRLF\r\n\t\t_IssueCommand()\r\n\t\tsleep(1000)\r\n\t\t$eingabe = &quot;show run&quot;\r\n\t\t_IssueCommand ()\r\n\t\tSleep(1000)\r\n\tEndIf\r\nWEnd\r\nEndFunc\r\n\r\nFunc _IssueCommand ()\r\n        TCPSend ( $Connection, $eingabe &amp; Chr ( 10 ) )\r\n\r\n        If @error Then\r\n            MsgBox (0,&quot;&quot;,&quot;Error&quot;)\r\n            Exit\r\n\r\n        EndIf\r\nEndFunc\r\n\r\nFunc _WriteFile ()\r\n$file = FileOpen(FileGetShortName(@ScriptDir) &amp; &quot;\\parse\\&quot; &amp; StringLeft($aSwitches[$x],StringInStr($aSwitches[$x],&quot;,&quot;) - 1) &amp; &quot;.txt&quot;, 2)\r\n\r\n; Check if file opened for writing OK\r\nIf $file = -1 Then\r\n    MsgBox(0, &quot;Error&quot;, &quot;Unable to open file.&quot;)\r\n    Exit\r\nEndIf\r\nFileWrite($file, GUICtrlRead ( $Edit ))\r\n;ToolTip(GUICtrlRead ( $Edit ),0,0)\r\nFileClose($file)\r\n\r\nEndFunc\r\n\r\nFunc _CleanFiles ()\r\n\r\nFor $x = 1 to $aSwitches[0]\r\n\tDim $aCleaners\r\n\t;MsgBox(0,&quot;&quot;,@ScriptDir &amp; &quot;\\&quot; &amp; $aSwitches[$x] &amp; &quot;\\.txt&quot;)\r\n\tIf Not _FileReadToArray(@ScriptDir &amp; &quot;\\parse\\&quot; &amp; StringLeft($aSwitches[$x],StringInStr($aSwitches[$x],&quot;,&quot;) - 1) &amp; &quot;.txt&quot;,$aCleaners) Then\r\n\tMsgBox(4096,&quot;Error&quot;, &quot; Error reading log to Array     error:&quot; &amp; @error)\r\n\tExit\r\n\tEndIf\r\n\tFor $z = 1 to $aCleaners[0]\r\n\t\t;Msgbox(0,&#039;Record:&#039; &amp; $z, $aCleaners[$z])\r\n\t\t$aCleaners[$z] = StringReplace($aCleaners[$z],&quot;\b\b\b\b\b\b\b\b\b        \b\b\b\b\b\b\b\b\b&quot;,&quot;&quot;)\r\n\t\t; --More--\r\n\t\t$aCleaners[$z] = StringReplace($aCleaners[$z],&quot; --More-- &quot;,&quot;&quot;)\r\n\tNext\r\n\t_FileWriteFromArray(@ScriptDir &amp; &quot;\\parse\\&quot; &amp; StringLeft($aSwitches[$x],StringInStr($aSwitches[$x],&quot;,&quot;) - 1) &amp; &quot;.txt&quot;,$aCleaners,1)\r\nNext\r\nMsgBox(0,&quot;Done&quot;,&quot;pulledem all&quot;)\r\nExit\r\nEndFunc<\/code><\/pre>\n<p>Here&#8217;s the script that actually parses the config.  It creates a CSV file that is listed as thus:<br \/>\nhostname,interface,description,ip address,subnet mask,bandwidth,port status<\/p>\n<p>Bandwidth is whatever the port is configured to with a service policy.  If there is no service policy, then it uses the ports physical rate limit.  If the port is down or admin down, it sets this value to 0.<\/p>\n<p>Port status is up, down or admin down.<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">;here we gooooooooooo\r\n#include &lt;file.au3&gt;\r\n#Include &lt;Array.au3&gt;\r\n\r\n;#########parse the pulled file#######################\r\n\r\n$FileList=_FileListToArray(@ScriptDir &amp; &quot;\\parse&quot;)\r\nIf @Error=1 Then\r\n    MsgBox (0,&quot;&quot;,&quot;No Files\\Folders Found.&quot;)\r\n    Exit\r\nEndIf\r\n\r\nfor $y = 1 to $FileList[0]\r\n\t$hostname = &quot;&quot;\r\n\t$interface = &quot;&quot;\r\n\t$ipAddress = &quot;&quot;\r\n\t$subnet = &quot;&quot;\r\n\t$ratelimit = &quot;&quot;\r\n\t$interfaceDesc = &quot;&quot;\r\n\t$intStarted = 0\r\n\t$exclimationMarks = 0\r\n\tLocal $aCompleted[1]\r\n\t$aCompleted[0] = &quot;0&quot;\r\n\r\n\r\n\tDim $aParse\r\n\tIf Not _FileReadToArray(@ScriptDir &amp; &quot;\\parse\\&quot; &amp; $FileList[$y],$aParse) Then\r\n\t\tMsgBox(4096,&quot;Error&quot;, &quot; Error reading log to Array     error:&quot; &amp; @error)\r\n\t\tExit\r\n\tEndIf\r\n\tFor $x = 1 to $aParse[0]\r\n\t\t;find hostname\r\n\t\tif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;hostname&quot;) &gt; 1 and stringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;hostname&quot;) &lt; 4 Then\r\n\t\t\t;found hostname\r\n\t\t\t$hostname = StringMid($aParse[$x],9)\r\n\t\tEndIf\r\n\t\t;look for interfaces\r\n\t\tif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;interface&quot;) &gt; 1 Then\r\n\t\t\t;mark that we have found the first interface\r\n\t\t\t$intStarted = 1\r\n\t\t\t$exclimationMarks = 0\r\n\t\t\t;set interface name\r\n\t\t\t$interface = StringMid($aParse[$x],10)\r\n\t\t\t;set default rate limit based on interface name\r\n\t\t\tif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;Giga&quot;) &gt; 1 Then\r\n\t\t\t\t;gigabit interface, set the RL to 1000\r\n\t\t\t\t$ratelimit = 1000\r\n\t\t\tElseif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;Fast&quot;) &gt; 1 Then\r\n\t\t\t\t$ratelimit = 100\r\n\t\t\tElse\r\n\t\t\t\t$ratelimit = 0\r\n\t\t\tEndIf\r\n\t\tEndIf\r\n\t\t;look for description\r\n\t\tif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;description&quot;) &gt; 1 Then\r\n\t\t\t;found desc\r\n\t\t\t$interfaceDesc = StringMid($aParse[$x],13)\r\n\t\tEndIf\r\n\t\t;look for ip address\r\n\t\tif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;ip address&quot;) &gt; 1 and StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;ip address&quot;) &lt; 4 Then\r\n\t\t\t;found address\r\n\t\t\t$subnet = StringMid($aParse[$x],StringInStr($aParse[$x],&quot;255&quot;))\r\n\t\t\t$ipAddress = StringMid($aParse[$x], 12, StringInStr($aParse[$x],&quot; &quot;,0,4) - 12)\r\n\t\tEndIf\r\n\t\t;look for rate limit\r\n\t\tif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;service-policy&quot;) &gt; 1 Then\r\n\t\t\t;found SP\r\n\t\t\t$ratelimit = StringMid($aParse[$x],StringInStr($aParse[$x],&quot; &quot;,0,3) + 1)\r\n\t\t\t$ratelimit = StringLeft($ratelimit,StringLen($ratelimit) - 3)\r\n\t\tEndIf\r\n\t\t;look for switch port with access vlan\r\n\t\tif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;switchport access vlan&quot;) &gt; 1 Then\r\n\t\t\t;found access port\r\n\t\t\t$ipAddress = &quot;vlan&quot; &amp; StringMid($aParse[$x],StringInStr($aParse[$x],&quot; &quot;, 0,4) + 1)\r\n\t\tEndIf\r\n\t\t;look for switch port set as trunk\r\n\t\tif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;switchport mode trunk&quot;) &gt; 1 Then\r\n\t\t\t;found trunk port\r\n\t\t\t$ratelimit = 0\r\n\t\t\t$ipAddress = &quot;trunk port&quot;\r\n\t\tEndIf\r\n\t\t;look for ! that signals the end of interface\r\n\t\tif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;!&quot;) &gt; 1 Then\r\n\t\t\t;found !\r\n\t\t\t$exclimationMarks = $exclimationMarks + 1\r\n\t\t\t;write all this good stuff, then clear\r\n\t\t\tif $intStarted == 1 and $exclimationMarks == 1 Then\r\n\t\t\t\t$aCompleted[0] = $aCompleted[0] + 1\r\n\t\t\t\t_ArrayAdd($aCompleted, $hostname &amp; &quot;,&quot; &amp; $interface &amp; &quot;,&quot; &amp; $interfaceDesc &amp; &quot;,&quot; &amp; $ipAddress &amp; &quot;,&quot; &amp; $subnet &amp; &quot;,&quot; &amp; $ratelimit)\r\n\t\t\tEndIf\r\n\t\t\t$interface = &quot;&quot;\r\n\t\t\t$ipAddress = &quot;&quot;\r\n\t\t\t$subnet = &quot;&quot;\r\n\t\t\t$ratelimit = &quot;&quot;\r\n\t\t\t$interfaceDesc = &quot;&quot;\r\n\r\n\t\tEndIf\r\n\t\t;###start the parse of &quot;show int | inc Ethernet&quot;\r\n\t\tif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;line protocol&quot;) &gt; 1 Then\r\n\t\t\t;found interface info.  Search through our existing array to find a match.\r\n\t\t\tfor $z = 1 to $aCompleted[0] - 1\r\n\t\t\t\tif StringInStr(&quot;-&quot; &amp; $aCompleted[$z], StringLeft($aParse[$x], StringInStr($aParse[$x], &quot; &quot;) - 1) &amp; &quot;,&quot;) &gt; 1 Then\r\n\t\t\t\t\t;we have our match!  Append the status\r\n\t\t\t\t\tif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;administratively&quot;) &gt; 1 Then\r\n\t\t\t\t\t\t$aCompleted[$z] = StringLeft($aCompleted[$z], StringInStr($aCompleted[$z],&quot;,&quot;,0,5)) &amp; &quot;0,admin down&quot;\r\n\t\t\t\t\t\t;also clear out RL\r\n\t\t\t\t\telseif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;line protocol is down&quot;) &gt; 1 Then\r\n\t\t\t\t\t\t;also clear out RL\r\n\t\t\t\t\t\t$aCompleted[$z] = StringLeft($aCompleted[$z], StringInStr($aCompleted[$z],&quot;,&quot;,0,5)) &amp; &quot;0,down&quot;\r\n\t\t\t\t\telseif StringInStr(&quot;-&quot; &amp; $aParse[$x], &quot;line protocol is up&quot;) &gt; 1 Then\r\n\t\t\t\t\t\t$aCompleted[$z] = $aCompleted[$z] &amp; &quot;,up&quot;\r\n\t\t\t\t\tEndIf\r\n\r\n\t\t\t\tEndIf\r\n\t\t\tNext\r\n\t\tEndIf\r\n\r\n\r\n\r\n\tNext\r\n\tFileDelete(@ScriptDir &amp; &quot;\\&quot; &amp; StringLeft($FileList[$y],StringLen($FileList[$y]) - 4) &amp; &quot;.csv&quot;)\r\n\t_FileWriteFromArray(@ScriptDir &amp; &quot;\\&quot; &amp; StringLeft($FileList[$y],StringLen($FileList[$y]) - 4) &amp; &quot;.csv&quot;,$aCompleted,1)\r\nNext<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Since I work for a datacenter, we have a LOT of ports. Our customers hang off of a handful of pieces of equipment, but\u2026<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,16,8,7],"tags":[],"class_list":["post-2229","post","type-post","status-publish","format-standard","hentry","category-autoit","category-cisco","category-networking","category-programmingscripting"],"_links":{"self":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/2229","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2229"}],"version-history":[{"count":6,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/2229\/revisions"}],"predecessor-version":[{"id":2283,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/2229\/revisions\/2283"}],"wp:attachment":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2229"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2229"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2229"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}