Morning all. So, at a conference where we needed to push an update to an app immediately because of bugs, etc. Whilst you can go into a device's info page and push, and also do this from other pages, we wanted to ensure that we only did this for devices where the app version DIDN'T match a particular version, to avoid disruption to other devices You'll need the following libraries installed: Meraki logging, sys, getopt, csv pandas json You'll call it with: python3 PushAppByAppIDReadFromCSV.py -k <YOURAPIKEY> -n <YOURMERAKINETWORKID> It requires a download of the CSV for the app in Question. This is from Systems Manager > Software. Click on the required app, then Export to CSV : It requires this to be called : devices_with_software.csv It also requires your network ID: Go to Systems Manager > General and scroll all the way to the bottom of the page Lastly, it requires the SM app ID: Go to Systems Manager > Apps and click on the required app. In the URL will be the SM app ID We use PANDAS for three reasons: It's really good for importing multi columned CSVs It's fast! It's really easy to import a list of dictionaries and working with it, which is what the response is from the GetNetworkSMDevices API call import meraki
import logging, sys, getopt, csv
import pandas as pd
import json
def main(argv):
# static args:
# Most recent version number of the app
search_value = '5.0.0'
# app ID in SM
app_ids = ['57814960XXXXXXXXXXXXXXXXXXX']
# init vars
arg_apikey = ''
arg_network_id = ''
# read ARGs
try:
opts, args = getopt.getopt(argv, 'k:n:')
except getopt.GetOptError:
printhelp(argv)
sys.exit(2)
for opt, arg in opts:
if opt == '-k':
arg_apikey = arg
elif opt == '-n':
arg_network_id = arg
if arg_apikey == '' or arg_network_id == '':
printhelp(argv)
sys.exit(2)
# Read the CSV
df = pd.read_csv('devices_with_software.csv')
# Filter rows where 'column_name' equals the search_value
# and create a new data frame
filtered_df = df[df['version'] != search_value]
client = meraki.DashboardAPI(api_key=arg_apikey)
# get all devices in the sm network
deviceList = client.sm.getNetworkSmDevices(networkId=arg_network_id)
# MUCH easier to work with DICTs in a LIST in Pandas, so let's import the
deviceListDF = pd.DataFrame(deviceList)
# iterate through filtered_df to get serial number
for index, row in filtered_df.iterrows():
serialNumber = row["serialNumber"]
# now search through deviceListDF and get SM device ID
try:
# we'll have a try, just in case the device weirdly doesn't exist
deviceIDList = deviceListDF.loc[deviceListDF['serialNumber'] == serialNumber, 'id'].values
deviceID = str(deviceIDList[0])
print("Device ID: ", deviceID, " serial number: ", serialNumber)
try:
response = client.sm.installNetworkSmDeviceApps(
arg_network_id, deviceID, app_ids,
force=True
)
except meraki.APIError as e:
print(e.message)
sys.exit(2)
except Exception as e:
print(e)
def printhelp():
# prints help information
print('This is a script that updates a given app where the app is not the most recent version.')
print("You'll need to export the CSV from:")
print("* Systems Manager > Software")
print("* Click on the app in question")
print("* Export to CSV on the right")
print(" ")
print(" It needs:")
print("serial, name,,NetworkName")
print('')
print('Mandatory arguments:')
print(' -k <api key> : Your Meraki Dashboard API key')
print(' -n number : Your Meraki Network ID ')
if __name__ == '__main__':
main(sys.argv[1:]) Good luck!
... View more