Check for BIOS Update with Python on Linux Mint

Michael Shoemaker
7 min readMar 3, 2023

--

When the pandemic hit several years ago one of the projects I took on was to build a new PC. Honestly, it was my first time doing so and with a few hiccups it went great. For my mother board I chose an Aorus B450 Pro Wifi. The issue? Their app to check for and install BIOS updates was only for Windows https://www.gigabyte.com/Support/Utility. Boo Aorus, booooo!

Getting BIO Info on Linux Mint:

But I did have access to the page to download the BIOS. So first step for me was to see how to check my BIOS version. A quick Google search later I found I could run.

sudo dmidecode | less

Ok. There’s a lot of info going on here, but the piece I’m intersted in is the Version.

I don’t want to hard code my password anywhere or start changing permissions unnecessarily so I’ll go ahead and make note of it.

Web Scraping the BIOS Update Page

The next step was to get the latest version of the BIOS from the website. Googling Aorus B450 Pro Wifi Bios pointed me right to the correct page. Then I highlighted the latest BIOS version, right clicked and clicked inspect.

From this we can tell that the version is contained in a div tag with a class of “div-table-cell download-version” Of course scraping a website in Python usually means Beautiful Soup so time for Beautiful Soup!

from bs4 import BeautifulSoup
import requests

CURRENT_BIOS = 'F63c'

url="https://www.gigabyte.com/Motherboard/B450-AORUS-PRO-WIFI-rev-1x/support#support-dl-bios"

resp = requests.get(url)

html_content = resp.text
soup = BeautifulSoup(html_content, "lxml")
mydivs = soup.find_all("div", class_="div-table-cell download-version")
for tag in mydivs:
if 'F' in tag.text:
if tag.text.strip() > CURRENT_BIOS:
print(f"Newer Version Available! Current verion {CURRENT_BIOS}")
print(f"Version {tag.text.strip()} is available")

Python and programming in general sometimes has odd ways of comparing strings. I believe it is by ascii value in this case, but honestly I just did some quick testing and it appeared to work so I went with that.

Here we have the CURRENT_BIOS hardcoded to F63a and the output lets us know that F64a is higher and available for download

Slack Webhook

The next step is how to get notified. My first thought was to schedule a Cron Job that would execute 30 seconds after each login and make an alert box. This worked great when run manually, but that didn’t work when scheduled. After some research apparently it has to do with the session server and that Linux and I found a workaround, but still decided to go with a Slack Notification as that seems to be a very popular way fo getting notifications.

First go to Slack.com and click Create a New Workspace

Then Create a Workspace. You may be asked to sign in. If so, just enter your email.

Choose a descriptive name for your Workspace. In my case I’ll call mine Bios_Update

You can skip the step to Add Teammates.

And just put whatever for What’s your team working on right now?

Once in the workspace click the little three dot ellipse next to Browse Slack

And click on Apps

Search for webhook and add Incoming WebHooks

And then choose Add to Slack (seems a little repetitive to me, but 🤷)

Then choose the channel where your message will be posted to. Slack by default gives you channels that are general, random and the name you provided for the what are you working on answer you gave when setting up the Workspace.

After choosing the channel push the button for Add Incoming WebHooks integration.

Bam! Now we have the Webhook URL that we can use to post to the Slack Channel from our local PC or wherever. There are also some nice examples of the usage of the webhook on this page.

The easiest way to get going is to install the Slack SDK shown in the code snip below. There is also a great example not using the Slack SDK that I actually use from Michael King that you can find here: https://medium.com/@neonforge/how-to-send-automated-slack-notifications-with-python-the-easy-way-ed1889f5a30

pip install slack_sdk

Now let’s try a quick example:

from slack_sdk.webhook import WebhookClient
url = "https://hooks.slack.com/services/<bunch of characters here :-)>"
webhook = WebhookClient(url)

response = webhook.send(text="Hello!")
assert response.status_code == 200
assert response.body == "ok"

Now just run it in and you should see “Hello” in your channel.

Let’s make this a little more useful by making it a function. You could just set it to let you know when a new BIOS Version is available, but we might want to use it in other projects so let’s turn it into a function which can take text as a parameter.

from slack_sdk.webhook import WebhookClient

def notify_slack(message: str) -> None:

url = "https://hooks.slack.com/services/<characters here>"
webhook = WebhookClient(url)

response = webhook.send(text=f"{message}")
assert response.status_code == 200
assert response.body == "ok"

Now we’ll do a quick test with:

notify_slack("Hello from my function")

Success!

So putting it all together we have code similar to this.

import sys
import requests
from bs4 import BeautifulSoup
from slack_sdk.webhook import WebhookClient

CURRENT_BIOS = "F63a"
BIOS_URL = "https://www.gigabyte.com/Motherboard/B450-AORUS-PRO-WIFI-rev-1x/support#support-dl-bios"


def check_bios() -> str:
resp = requests.get(BIOS_URL)

html_content = resp.text
soup = BeautifulSoup(html_content, "lxml")
mydivs = soup.find_all("div", class_="div-table-cell download-version")
for tag in mydivs:
if "F" in tag.text:
if tag.text.strip() > CURRENT_BIOS:
return tag.text.strip()


def notify_slack(message: str) -> None:
url = "https://hooks.slack.com/services/<some characters here>"
webhook = WebhookClient(url)

response = webhook.send(
text=f"Your current BIOS versoin is {CURRENT_BIOS}, but version {message} is now available\n{BIOS_URL}"
)
assert response.status_code == 200
assert response.body == "ok"


if __name__ == "__main__":
message = check_bios()
if not message:
sys.exit(1)
notify_slack(message)

So to sum up we:
1) Grab the BIOS update html
2) check the BIOS versions
3) if there is not a newer version, exit the program gracefully
4) if there is a newer version, send a notification to the Slack Channel

Scheduling our script:

We can save our script to /usr/local/bin on Linux. It will run fine as a .py file, but if there are issues for some reason you could always save it to a file adding the !#/path/to/where/python/is/installed/python and then chmod +x the file.

To schedule our script to run we can use:

crontab -e

and add our cron job to the bottom of the file. If you are unfamiliar with cron syntax Crontab.guru is an AWESOME resource to learn and to use to double check your schedule.

I decided to go the easy route and just use the “@reboot” and pass two commands using && so that my job looks like this:

@reboot sleep 300 && /usr/local/bin/check_bios.py

So after a reboot start running, but when you do sleep for 300 seconds (5 minutes) and then run our python script.

Conclusion and other thoughts:

I am not a data or software engineer. However, I do like to tinker, program and play with technology in general. As technology continues to grow as an integral part of our everyday lives I think that it is important that everyone have some level of technological literacy in order to leverage the devices and services that surround us to make a more productive, efficient and engaging existence.

This project could also be adapted to notify you for any event. Some ideas might include:

  • Doing Bug Bounties — You are hunting subdomains and want to know when new records are entered into the database where you are storing them.
  • Gardening — You have moisture sensors around your plants and want to know when they are too dry and you need to water them.
  • Train Schedule — You know when you head to the train station in the morning and have a call to the train operator API around that time to get the estimated arrival time of the next x number of trains.

Keep learning, keep teaching, stay curious and don’t give up.

--

--