Build a Troubleshooting Toolkit using PowerShell

If you are an IT pro, then you are most likely the IT pro that’s on call for your family, friends and neighbors. You get a call that a neighbor’s computer is running slow or experiencing odd behavior. Virus? Malware? Rootkit? Application issues? If you are also like me, then you tend to rely on a collection of free and incredibly useful tools like Trend Micro’s HouseCall, Hijack This or CCleaner. Perhaps you might even need a copy of the latest tools from the Sysinternals site. In the past I’ve grabbed a spare USB key, plugged it in and started downloading files. But this is a time consuming and boring process, which makes it a prime candidate for automation. And in my case that means PowerShell.

Using Invoke-WebRequest

PowerShell 3.0 brought us a new command, Invoke-WebRequest. This cmdlet eliminated the need to use the .NET Framework in scripts. We no longer needed to figure out how to use the Webclient class. Cmdlets are almost always easier to use. If you look at the help for Invoke-WebRequest, then you’ll see how easy it is. All you really need to specify is the URI to the web resource. So for my task all I need is a direct download link to the tool I want to grab.

However, in this situation, I don’t want to write the result to the PowerShell pipeline, I want to save it to a file. Invoke-Webrequest has a parameter for that.

I am using a few other parameters since I’m not doing anything else with the connection once I’ve downloaded the file. This should also make this command safer to run in the PowerShell ISE on 3.0 systems. In v3 there was a nasty memory leak when using Invoke-Webrequest in the PowerShell ISE. That has been fixed in v4. So within a few seconds I have the setup file downloaded to drive D:. That is the central part of my download script.

Within the script, there’s a string of CSV data. The data contains a description and direct link for all the tools I want to download. You can add or delete these as you see fit. Just make sure the download link ends in a file name. The download function will parse out the last part of the URI and use it to create the local file name.

All you need to do is specify the path, which will usually be a USB thumb drive.

The script has an optional parameter for downloading utilities from the website. If you opt for this, then the script will create a subfolder for SysInternals tools. That’s the way I like it. To download the tools I first use Invoke-WebRequest to get the listing page.

Within this object is a property called Links, which will have links to each tool.

The first link is to the parent directory, which I don’t want which is why I’m skipping 1. Then for each link I can build the URI from the HREF property.

The only other thing I’ve done that you might not understand is that I’ve created a function with a non-standard name. I always try to avoid repeating commands or blocks of code. I created the _download function with the intent that it will never be exposed outside of the script. And this is a script which means to run it you need to specify the full path.

As I mentioned, I included the CSV data within the script which makes it very portable. But you might want to keep the download data separate from the script. In that case you’ll need a CSV file like this:

And this version of the script.

This version has additional parameters that accept pipeline binding by property name, which means you can now run the command like this:

You will need to dot-source this second script to load the function into your session. Otherwise, it works essentially the same. There is one potential drawback to these scripts in that the downloads are all sequential, which means it can take 10 minutes or more to download everything. To build a toolkit even faster, take a look at this alternate approach.

By the way, if you have any favorite troubleshooting or diagnostic tools I hope you’ll let me know. If you can include a direct download link that would be even better.

Related Topics:

  • PowerShell

    Don't have a login but want to join the conversation? Sign up for a Petri Account