A script that saves our team more than 90 minutes a week!

Small wins

Little wins are a major theme that I have been focusing on recently. Automating the little struggles and time wasters are a really great way to boost your morale.

I had an interesting moment at work today as I reflected on a small win that is saving time on our team each week. I have been working on a project that installs software on a client's Windows machine.

The old way before the script

This process was very manual and took way too much time. You had to do the following:

  • Open a browser
  • Log into a site
  • Navigate to the correct page
  • Look up the license number for a client
  • Navigate to the directory where the software runs
  • Select and remove some library files that are different between each client
  • Change the license number that you looked up earlier.

In all it took well over a minute to do all the steps and, worst of all, I would often forget why I was switching to another client.

About nine months ago, I wrote a script that makes it very easy to switch between clients. The script takes less than 5 seconds to run. I am guessing it saves about a minute each time you need to switch between clients.

One minute isn't the huge savings that people get excited about. Especially when my co-workers found out that it took me over 4 hours to get the script to work. But we all look at how useful the script is and can't imagine what our work life would be like without it.

The savings from the script

This is where I reflected on the power of a small win. I am guessing that each of us work on 5 clients a day. The small team of 4 people each work on 5 clients, 5 days a week. That little script is saving so much time. If I am doing my math correctly that saves our team about 100 minutes of work each week.

That really is the kind of little win that I have been focusing on lately. I really like when I can find a small item that is wasting my time throughout the day and then find a way to automate that process.

I suppose that is one of my favorite parts about programming in general. I have the ability to write something that can save myself and others minutes or even hours throughout the week.

The actual PowerShell script

The script is really simple, it takes less than 100 lines. In fact, here it is in all of its PowerShell glory:

# Reference the library that hits our web service.
Add-Type -Path "..\Path\To\BaseLibrary.dll"  
# Get the clients from the web service. Returned object is a C# DataSet.
$client_data = [BaseLibrary.DataAccess]::SendWebServiceSelectQuery("SELECT lic_num AS license_number, UPPER(company) AS company FROM clients")

# Put all the client information in a set.
$clients = @{}
for($i=0;$i -lt $client_data.Tables[0].Rows.Count;$i++)  
{
    $clients.Set_Item($client_data.Tables[0].Rows[$i]["company"], $client_data.Tables[0].Rows[$i]["license_number"])
}

# Remove libraries that are different versions for each client.
Remove-Item "C:\Path\To\Software\Library1.*"  
Remove-Item "C:\Path\To\Software\Library2.*" -exclude *.config  
Remove-Item "C:\Path\To\Software\BaseLibrary.*"

$clientName = Read-Host -Prompt "Switch to which client?"
$clientName = $clientName.ToUpper()
If (!$clients.ContainsKey($clientName))  
{
    $possibleClients = @()
    # The user didn't enter a client name exactly as it is spelt.
    # Get all cients that start with what the user entered.
    foreach ($name in $clients.Keys)
    {
        If ($name.StartsWith($clientName))
        {
            $possibleClients += $name
        }
    }
    If ($possibleClients.length -eq 1)
    {
        $clientName = $possibleClients[0]
    }
    ElseIf ($possibleClients.length -gt 1)
    {
        # Have the user pick a number that corresponds to a possible client.
        $length = $possibleClients.length
        for ($i = 0; $i -lt $length; $i++)
        {
            $name = $possibleClients[$i]
            Write-Host "$i) $name"
        }
        Write-Host ""
        $j = -1
        $limit = $length - 1
        while ($j -lt 0 -Or $j -ge $length)
        {
            [int]$index = Read-Host -Prompt "Which client did you want? (0 - $limit)"
            $j = $index
        }
        $clientName = $possibleClients[$index]
    }
    Else
    {
        $sorted = $clients.Keys.GetEnumerator() | sort
        foreach ($name in $sorted)
        {
            Write-Host $name
        }
        Write-Host ""
        Write-Host "Your client name does not match any clients. Please pick one from the list above."
        return
    }
}

$licenseId = $clients[$clientName]
Write-Host "LicenseID: $licenseId"  
Start-Process "change_license.bat" $licenseId  
Write-Host "Starting Software as the $clientName client."  
Invoke-Item "C:\Path\To\Software\Software.exe"  

I'll summarize the script now. It grabs all the client's name and license number that is in the system. We'll need this information later when once the user selects a client that they want to switch to. Next, it goes to the removes all the libraries that change between clients. This step was actually the first thing I wrote in this script. After that we ask the user "Switch to which client?".

This next part is where a lot of logic takes place. After the user types in the full client name or only a part of it, that name is checked to see if what they typed is an exact match. If the name is an exact match then moves to the last part. Otherwise, the script grabs all the clients that start with what the user typed in.

Now there are 3 different cases that need to be accounted for. When the script finds one client that starts with what the user typed in it moves to the last part. If the script didn't find any clients that start with what the user typed in then in prints out all the client names and tells the user that nothing matched what was typed in and ends. The last case is when multiple clients start with what was typed in. In that case the script will print out the client and a number that corresponds to the client. The user can select the client by typing in a number.

At this point the script has a client and so it changes the license and starts the software. When the software starts it will download their latest files.

This is huge improvement over the old process. I don't have to look up a client's information or manually type anything. In fact, sometimes I just type the first letter of a client's name and then pick the number that corresponds to that client from a list of all the clients that start with that letter. That is really fast and the best part is that I don't forget why I am switching to another client.

What we do with that extra 90 minutes a week

We now invest our time and effort into other projects that speed up the team and help improve the morale. This includes things like the following:

  • A library for all of our common functions
  • System monitoring application that checks for known errors
  • Time to refactor small items in our to do list
  • Applications that improve the communication between our team and other departments

Happy coding!