It finally happened, I actually needed to make a script to write scripts. There’s been a few times where I needed to write multiple scripts that are basically the same minus a few variables and in the past I’ve just done this manually. An example of this is a BitDefender Gravity Zone install script, I have a basic PowerShell script that I use and the only items I need to change are the Gravity Zone ID and the company name.
However all of the scripts broke because the URL to get the BitDefender MSI changed and the MSI used to be in a ZIP file. Now all the PowerShell scripts are trying to download from a dead URL and are written to handle an MSI in a ZIP file.
This is what the original install script looked like
# Some Company Bit Defender install
# url to get BitDefender installer
$BDURL = "Download URL"
# the BitDefender Gravity Zone ID to match the install to the correct customer
$GZID = "GZ_PACKAGE_ID=GZID_here"
# check if temp exists if not make it
$temp = "temp"
if (-not (Test-Path $Env:SystemDrive\$temp))
{
New-Item -ItemType Directory $Env:SystemDrive\$temp | out-null
}
# download the file to temp
Invoke-WebRequest -Uri $BDURL -OutFile "$Env:SystemDrive\$temp\eps_installer_signed.zip"
# extract files and overwrite if another version happens to be there
Expand-Archive -force "$Env:SystemDrive\$temp\eps_installer_signed.zip" -DestinationPath $Env:SystemDrive\$temp
# install BitDefender silently with no reboot and like with the Gravity Zone id
msiexec /i "$Env:SystemDrive\$temp\eps_installer_signed.msi" /qn $GZID
write-host "Bit Defender install is running"
Code language: PowerShell (powershell)
This is what the the updated install script looks like
# Some Company Bit Defender Silent install
# the BitDefender Gravity Zone ID to match the install to the correct customer
$GZID = "GZ_PACKAGE_ID=GZID_HERE"
# url to get BitDefender installer
$BDURL = "BitDefender MSI Download URL here"
# check if temp exists if not make it
$temp = "temp"
if (-not (Test-Path $Env:SystemDrive\$temp))
{
New-Item -ItemType Directory $Env:SystemDrive\$temp | out-null
}
# enable TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# download the file to temp
Invoke-WebRequest -Uri $BDURL -OutFile "$Env:SystemDrive\$temp\BEST_downloaderWrapper.msi"
# install BitDefender silently with no reboot and like with the gavity zone id
msiexec /i "$Env:SystemDrive\$temp\BEST_downloaderWrapper.msi" /qn $GZID
write-host "BitDefender install is running"
Code language: PowerShell (powershell)
There were far too many scripts that needed to be updated that doing it manually was not realistic. Originally I tried to write PowerShell script to write a PowerShell script but that got messy and confusing quickly. I gave up on the PowerShell route and decided to try using Python to write the PowerShell scripts.
In order to do this I created a CSV that had each company name, company short name, and their Gravity Zone ID. I also created a text file that had the part of the PowerShell install script that didn’t change. Using Python I was able to import the CSV and loop it for each row to output a new PowerShell script for each company using the variables in the CSV file.
This is what the Python script looks like.
# the BD Install script maker script
# author theDXT
print("Starting the script to make scripts")
from csv import DictReader
# load the csv file with the variables and define it as the list
with open('clients.csv', 'r') as the_list:
# define new variable to load the list as object mapping
csv_dict_reader = DictReader(the_list)
# run a loop for each item in the csv
for item in csv_dict_reader:
# make powershell files for each client using the shortname and define it as script
with open((item['shortname'])+ "_BD_Install.ps1", 'w') as script:
# define the header comments and load in the client full name
header_comments = ["# ", (item['client']), " Bit Defender Silent install\n \n"]
# save the header comments to the file
script.writelines(header_comments)
# define the GZID stuff and load in the client keycode for the correct mappings
GZID = ["# the BitDefender Gravity Zone ID to match the install to the correct customer\n", '$GZID = "GZ_PACKAGE_ID=', (item['Keycode']),'"']
# save that to the file
script.writelines(GZID)
# load the rest of the install script that doesnt change
source = open("template.txt", "r")
# loop it for each line because I didnt find another way that worked
for line in source:
script.write(line)
print("all done")
Code language: Python (python)
Now all I have to do is run the script and it makes the scripts for me.
Here’s a link to the script on my GitHub https://github.com/thedxt/Python#bd-script-maker