×close

Voigt-Kampff replicant detection test

Before sending the message, I've to be sure that you are not a bot.
Please choose the not dilated pupil.

  • LOADING...

You fail! You are a replicant! Run away!

You are human! Great! Write your message and submit it.






You sent me a message: thank you!

Error sending the message. Please, try again later.

The Real Power of PowerShell

January 28, 2018
powershell windows bash

I’m working on a new project: a desktop application 1 developed with Qt Framework on Windows. Typically, I use Bash scripts to govern the pipeline, but to reduce dependencies, I decided to introduce in my development tools the PowerShell.

On Windows systems, I always suffer the missing of a decent console terminal. But, this time, instead of trying to emulate the Linux feeling by Cygwin or MinGW2 – and after tested the immature integrated native Ubuntu environment – I decided to give an opportunity to the Micro$oft response to Bash: the PowerShell.

PowerShell is a power shell. Really.

The first time I tried PowerShell, it was very poor in performance. I abandoned it after a quick try: too verbose and too slow for me.

Today, after a matter of years, the PowerShell is grown enough to be used. Also, with smart use of aliases, the impact for *nix users is quite smooth: tab completion, well-known command names (es. ls for listing files, less to read a file, touch to create an empty file, and so on). But, working more on PowerShell I’ve started to appreciate the differences with Bash, in particular, the different architectural design.

PowerShell gives direct access to entire .Net layer. So you can access all the feature exposed to the OS by each application.

An architectural diagram of PowerShell

An architectural diagram of PowerShell. The figure is extracted from the set of Youtube videos that I refer at the end of the article.

The “power” of PowerShell is the fact that it works on objects instead of strings.

In Bash, you pipe executables concatenating standard output of a command with the standard input of the next one. By this mechanism, you connect commands with the exchanging of strings. Instead, a PowerShell commandlet (this is the name of a command in PowerShell glossary) returns a collection of .NET objects. The output of each instruction passes a set of object that you can manipulate and filter in a syntax very close to C#. Say goodbye to regexp manipulation or fancy textual string filter, welcome to fully semantic and typed expression. This changes the game entirely.

An example: scripts for supporting my blog

Coding as a God

Because I move very often form Mac OS X to Windows, I decided to set up my blogging environment, so it is easy to use on both the systems.

The following code is the script I use to publish my blog in OS X:

123456
#!/bin/sh
user_name=myusername
site_host=my.host.name
dir_name=blog/folder/ 

hugo && rsync -avz -e "/usr/bin/ssh"  --bwlimit=2000 --delete public/ ${user_name}@${site_host}:~/${dir_name}

This code is straightforward. Lines 2-4 defines a set of local variables to describe host and path where to move the blog from local to online.

The core of the script is in line 6 where I concatenate Hugo static code generator CLI command that generates the HTML, with rsync that move all the stuff on the website server.

The PowerShell version is:

123456
$username="matteodesimone"
$site_host="matteo.desimone.name"
$dir_name="log.matteo.desimone.name/"

hugo.exe
rsync.exe -avz -e "/usr/bin/ssh"  --bwlimit=2000 --delete public/ "${user_name}@${site_host}:~/${dir_name}"

Please note that the code is remarkably similar.

Lines 1-3 defines the variables. Notice the slight difference in use of $ in variable definitions.

Lines 5 and 6 are quite identical.

An example to understand the architectural difference between bash environment and PowerShell point of view is the script I use to optimize images before using in blog posts.

 1 2 3 4 5 6 7 8 91011121314
#!/bin/sh
export TINYPNG_API_KEY=XXX_THE_TINYPNG_SERVICE_API_KEY

# extract name and extension of the file to convert
filename=$(basename "${1}")
extension="${filename##*.}"
filename="${filename%.*}"

# convert the input image to PNG
sips -s format png ${1} --out ${filename}.png

# optimize PNG image
# It use: go get -u github.com/peterhellberg/tinypng/tinypng
tinypng ${filename}.png

As described in my previous post, to optimize images I use TinyPNG.com service by a small tool written in Go.

Line 2 exports the TinyPNG API Key as environment variable so the tinypng tool can access it.

My code accepts the image file name to process as script parameter (stored in ${1} pseudo variable). Lines 4-7 decompose command line parameter so I can substitute the initial extension in the file name with “.png”. To achieve the goal, I leverage parameter expansion rules of bash (very powerful!).

The conversion of the input image to PNG format is performed by the line 10 with sips command that is preinstalled on Mac OS X environment.

The last line calls TinyPNG service with the client written by Peter Hellberg.

The PowerShell version of this script highlights what I call the architectural differences between the *nix and the Micro$oft approach.

 1 2 3 4 5 6 7 8 91011121314151617
$env:TINYPNG_API_KEY="XXX_THE_TINYPNG_SERVICE_API_KEY"

$file = (Get-Item $args[0])
$filename=$file.BaseName
$filepath = Split-Path -parent $file
$outFile = Join-Path -Path $filepath -ChildPath ("${filename}.png")

# Image conversion. No sips command available
# so I use directly the function of the .Net Framework
Add-Type -AssemblyName system.drawing
$imageFormat = [System.Drawing.Imaging.ImageFormat]::Png
$image = [System.Drawing.Image]::FromFile($file)
$image.Save($outFile, $imageFormat::png)

# Optimize!
# It use: go get -u github.com/peterhellberg/tinypng/tinypng
tinypng.exe "${filename}.png"

Line 1 is the way as PowerShell access to Environment variables. The $env: prefix behave as a namespace that gives you access to all the dictionary of variables defined at the moment on the system.

Lines 3-6 show as PowerShell manipulates objects instead of strings. Get-Item assigns to $file a file object so that I can access to his attributes by dot operator. Also, I can use Split-Path to manipulate the file path and reuse it to build destination file name.

After that, I need to substitute sips command that it isn’t available on Windows. Instead of installing a new application (es ImageMagick) I can access directly to all functions that .Net framework exposes to the operating system. See lines 10-13: if you know C# you can recognize as typical this bunch of code.

The last line is practically unchanged from OS X version.

Well done, Micro$oft guys!

I was happily surprised by the big step forward that Windows 10 did respect to past releases concerning stability and functionality and one of the most underestimated novelty is the PowerShell environment. I think Micro$oft, in the end, gave up obsession for legacy code and releases a promising operating system and application environment.

PowerShell is a comfortable and powerful new approach to terminal tools in Windows.

If you are curious, you can find a clear introduction to PowerShell, in this great series of video lessons covering the basis by Sapien Technologies. Enjoy!


  1. More details about this will follow. [return]
  2. Probably the best compromise between the Bash feel-and-look and the Windows integration is MinGW porting, HIMO. [return]
comments powered by Disqus