I did not know Powershell existed

…until a couple months ago. It fell under my radar for the first time during a meeting. I had been pondering how to write a small desktop application that allowed Drupal website content creators to pull down the lessons they had created on an authoring website and package them into a nice, neat folder that could be loaded onto Android tablets for use by our app.

The Goal

I told my colleagues that my application would live on a local machine and should work like this:

  • pull down files from the Drupal site
  • create new files when needed
  • build out its directory structure as it hummed along
  • gave the content person reasonable indications of download progress

While I had been thinking about building it in C#, which would have been quite a learning curve for me, a colleague of mine suggested that I try building it in a language called Powershell. While it is a tool typically used by web admins, and while the final product would have to be a text-based interface, it is fast, can work on both Macs and PCs, and has the functionality necessary to get the job done efficiently.

Some Background

For those of you who are new to this stuff, a shell is a textual user interface that allows you to use different services of your computer’s operating system (OS) and run specific programs.

Windows Powershell is a shell environment built on the .NET framework that was originally developed by Microsoft for administrative and other “under-the-hood” tasks. It has its own scripting language — the commands you can use are called cmdlets - and has been an integral part of the Windows OS for some time now. A new version of it, called Powershell Core, is cross-platform and will run on Macs with an OS of 10.12 and above. Powershell Core is the version I use, as I currently work mainly in a Mac environment.

There are quite a few differences between Windows Powershell and Powershell Core, and to me the most notable difference is that Windows Powershell has quite a few more cmdlets (aka commands.) The differences between the two are discussed in detail on this techgenix.com post.

The Interface

Because Powershell is a shell application, it will run within a Mac’s terminal app, and for Windows, it runs with its own interpreter that can read and execute its code line-by-line. The interface is all textual and a powershell script you write will not have a graphic user interface (GUI) out-of the-box (or at all, if you are on a Mac). So to some users, the interface of a powershell application will be reminiscent of the old-school computers from the pre-GUI days.

If you are building for Windows, you can build a GUI for a Powershell application but you don’t have to if your users are fine using the textual UI. That said, the GUI packages are not yet available for Powershell Core - so a cross-platform application or non-Windows application should not have a GUI. You can learn more about when a GUI may be appropriate via this poshland.pro article.

What I have learned thus far

With some guidance from colleagues, I downloaded PowerShell Core and started exploring. The very first thing I tried to do was a simple GET request to a JSON file living on my Drupal site. I was thrilled at how fast I was able to get it to work!

As I evolved my script, I primarily added the following logic:

  • making an asynchronous GET request to a JSON file
  • saving the file to my desktop
  • using a while loop checking on file size to check download completion
  • converting between JSON text and a JSON object
  • iterating through a JSON object using a for loop
  • creating a directory
  • listing the files in the directory
  • converting a string to an array with a delimiter (ex. ‘/’)
  • creating and modifying an array and a JSON object

Takeaways

Below are some of my takeaways thus far.

  • You can run powershell cmdlets and define variables directly in the interface. You can type them in one-by-one and see how they work.

  • Familiar programming conventions. All the typical programming conventions I have needed, including all the standard loops I use (while, for, foreach, etc.), as well as array logic, server requests, File I/O, and JSON logic, are there.

  • Powershell is dynamically typed. You can also cast variables as particular types, which is handy.

  • Pipeline syntax is available and can make code shorter (but sometimes less clear.) I have not used these much in my script, but it is a strong point of Powershell. You can find a super quick example here at ss64.com.

  • Powershell is very JSON-friendly. If you ask it to print a JSON object, it will actually print some or all of its properties. Switching between JSON Objects and the equivalent strings is easy. Because my script is pulling info from the Drupal site and interpreting it, this particular script is heavy on JSON, so having this functionality is terrific.

  • There is tons of documentation out there! The is tons of great documentation and from what I can tell, the language has stabilized. Just be vigilant about ditinguishing code that uses Windows-specific commands.

  • The language has been easy to pick up. While I have coded in C, Objective-C, OCaml, and PHP, my primary day-to-day programming language is Javascript. That said, learning powershell syntax has been straightforward. Like all languages, it has its own syntax.

  • Testing is quick. There is no compilation step, no browser to refresh, and no device to send the code to - so you can do a lot of rapid testing.

  • Asynchronous requests are supported. As with Javascript, you have to be careful about distinguishing between synchronous and asynchronous commands. Unlike JS, which uses callbacks and promises, it can be tricky to tell whether an async process has completed, so you may need to write some code to check for completion.

  • You can run a script that uses multiple files. As my codebase gets larger, I am finding it helpful to have files containing helper functions. You can include this with a dot and the relative filepath: . ./myfile.ps1

Closing

So my journey with PowerShell has begun, and over the course of the past month, I have created an Powershell script that does its job fast. My goal over the next month will be to start testing in a Windows 10 environment (using Mac Parallels) and make it as easy as possible to use by content creators, who will have to transition from point-and-click GUIs to text-based interfaces. I am also working on adding functionality for swapping in large video files during and after the download process.