Cowboy Scripting & Network Automation

I am an avid listener of networking/nerd podcasts out there – Heavy Networking (Packet Pushers), Network Automation Nerds (now Packet Pushers), Art of Network Engineering, amongst others. I’m also hoping to get to the AutoCon2 event in CO later this year. I consider myself a huge proponent of automation in all facets of IT, but obviously this blog, and my passion, is in the networking realm. Throughout my career, I’ve worked as the lone-wolf IT person for a small 50-person company, to being a part of a service desk at a small hospitality chain, to working on a dedicated infrastructure team for a multi-hundred-unit brand. I have not, however, worked for a large enough company that allowed me to solely focuses on one specific IT component – i.e. routing, firewall, etc. What’s my point? The “proper” way to do automation, either something free like Ansible, or paid like Itential, has never been feasible for me. There was never enough time to research, design, implement, or make a good enough business case for these frameworks.

What’s the quote again, “There’s nothing more permanent than a temporary solution.”? Either way, little scripts that perform a task have been critical to my career. One of the earliest ‘automation’ scripts I recall developing was a PowerShell script which ran through a list of DDNS entries, confirming or denying if a host (Fortinet firewall) replied or not. Maybe this isn’t something you’d consider in the same universe as network automation, but we didn’t have a source of truth at the time, and I just needed a list of reachable devices.

Network automation has seemingly exploded in recent years, and we’re starting to see an increase in both adoption, as well as options and ways to implement – APIs provided by device manufacturers & platforms which are device agnostic. That being said, we should all be chomping at the bit to pick one, or a few, and get moving, right? From my own experience, that’s still a loaded question. You might be part of a smaller org with little resources, namely time, who is forever stuck in a ‘keeping the lights on’ role. On the flip side, you might be part of a large org with too many layers of approvals and lack of buy-in from key stakeholders.

So where does that leave us? Do we feel guilty for not spending outside work time researching this stuff? Do we feel angry that our co-workers and leadership can’t see the bigger picture? Do we feel annoyed, and maybe even depressed, that we can’t bring these amazing tools into our day-to-day work? Do we feel inadequate in our roles because we hear about other teams who are leveraging automation today?

I think the answer is simply, ‘Yes’. It is normal to have a lot of feelings throughout your career, and network automation is just another stop along the journey. My experience has been more on the digital range (so to speak), where roping in JSON data from an API and mutating it before shoving it back out into another API has felt the most like home. Do I have “automation” scripts I share amongst co-workers? Of course! Are they still prone to breaking if I’m not handling all possible errors? Oh, hell yeah! Do I feel bad about it? Sometimes!

At the end of the day, I try to keep my head up, continue listening and learning, and always remember to giddy up! I’ve got a glorious bit of cowboy automation in my neck of the woods, and I’ll be damned if I ain’t proud of it!

Credit: xkcd

Epson TM-L90 TCP/IP update via PowerShell

Sometimes it’s not the networking devices that need the automating. Sometimes, you have to automate the things to fit the network. In this case, I was given the task of manually logging in and updating a bunch of Epson receipt printers to use DHCP/auto IP config instead of the static/manual IP config they have configured today.

When you hit the web UI, you’re presented with a fairly generic login popup, asking for a username and password. In this case, I was able to use the default credentials combo for nearly all of the devices, which things easy. You can use a simple Invoke-WebRequest command to initiate your connection:

Invoke-WebRequest -Uri "https://<local_printer_ip>"

This will very likely fail for a few different reasons, the first being that it redirects to HTTPS but also has a default SSL certificate which PS does not like. To get around that you just need to add the -SkipCertificateCheck parameter to the end of the code line. From here, you will find that you get an HTTP 401 auth error which will require you to pass the creds on with the request. I handled this by issuing a Get-Credential request and storing that in a variable which is passed on during the call using the -Credential parameter.

Rather than break down the rest of the findings, I’ll just share what I came up with (update <local_printer_ip> to value of your printer):

#Enter credentials to be used for login later
$c = Get-Credential

#Build a new authenticated session using credentials from above
Invoke-WebRequest -Uri 'https://<local_printer_ip>' -SessionVariable temp_session -Method GET -Credential $c -SkipCertificateCheck

#Issue update to auto/DHCP IP config
Invoke-WebRequest -UseBasicParsing -Uri 'https://<local_printer_ip>/tcp_setv4.cgi?W_IP8=4&W_IP10=0&W_IP11=1' -WebSession $temp_session -Method GET -SkipCertificateCheck

#Issue reset command to save config
Invoke-WebRequest -Uri 'https://<local_printer_ip>/reset.cgi?' -WebSession $temp_session -Method GET -SkipCertificateCheck

There are a few things to note in this so I’ll quick break them down:

  • -SessionVariable creates the session to be used, -WebSession allows you to use the session later. Variable name can be whatever you’d like, but you do not use a $ during the setup.
  • -UseBasicParsing was needed in my case I got a page not found error without it.
  • The tcp_setv4 CGI command was found using the Developer Tools in my browser, and that’s how I’d suggest finding the command for anything else you’d want to modify.
    • W_IP8 refers to the drop down menu, 1 = Manual/Static, 4 = Auto/DHCP
    • W_IP10 refers to the Set Using Automatic Private IP Addressing (APIPA) setting and is required to issue the update.
    • W_IP11 refers to the Set IP Address Using ARP + Ping setting and for Auto/DHCP needs to be set to 1, 0 would be Disable.
  • If you need to do the opposite as I’ve done here, the command to update the printer to static is:
    • https://<local_printer_ip>/tcp_setv4.cgi?W_IP8=1&W_IP1=<printer_ip>&W_IP2=<subnet_mask>&W_IP3=<gateway>&W_IP10=0&W_IP11=0
    • E.g. https://192.168.1.213/tcp_setv4.cgi?W_IP8=1&W_IP1=192.168.1.10&W_IP2=255.255.255.0&W_IP3=192.168.1.1&W_IP10=0&W_IP11=0
    • Remember to issue the reset command as that is seemingly what saves the config.

For my task, I included a few other things which included pulling in a list of printer IPs from a CSV, looping through that list and running the updates, sending the response HTTP codes to an array, and exporting that to a CSV. If you for some reason had your printers secured with different credentials, you could also include those in your initial CSV and build new credential objects during each loop.

Hope this has been helpful! And happy automating!