Useful PowerShell

I joined my third Windows project as a consultant in May 2014. Over the past five years I’ve become more dependent on shell. While many folks seem content to mouse their way around Windows or jump to cygwin, I found PowerShell capable of doing just about everything I needed to. Here is my guide to Useful PowerShell.

The Basics

Everything in PowerShell follows the same ‘Verb-Noun’ convention. Many common commandlets are also aliased to their unix equivalents. For example, Get-ChildItem is aliased to ls. If you’re interested in the aliases of a known command, you can use Get-Alias.

# known command
Get-Alias -Definition Get-ChildItem

# all defined aliases

The Get-Help commandlet is one of the most useful, especially if you prefer to learn by example.

Get-Help Get-ChildItem -Examples

Everything native to PowerShell can tab-complete, including parameters. The verbosity is not as bad as it seems. When it comes to reading scripts, it’s actually kind of nice to get that clarity. It’s also a surefire laugh for folks with unix shell backgrounds and a sense of humor. After all, who needs touch when you have New-Item -Type File?

The environment variable syntax is often confusing for new folks. We have access to all of .NET, so there are multiple ways to get this done, but the easiest way I’ve found is to just stick a $env: on the front.

# Add something to the PATH for the current session only
$env:PATH += ";c:\tools\bin"

# show all environment variables, note there is no '$' and the ':' is required
Get-ChildItem env:

# using familiar aliases
ls env:

The Profile

It’s easy to customize bash by popping open ~/.bashrc and proceeding to define functions, choose the folder to start in, set environment variables, or anything. PowerShell has the same thing going on, but it’s slightly more difficult to get going.

PowerShell’s profile is at a really long path in a folder that doesn’t exist by default. To create a brand new profile on your system, you’ll first need to create it.

New-Item -Path $Profile -Type File -Force

This is nice because none of the directories have to exist before the command is run. It reminds me of mkdir -p on unix, and indeed behaves exactly the same way for -Type Directory.

After you have the profile created, you can edit it with any text editor on your system.

notepad $Profile

Any valid PowerShell command will be executed when the shell loads. This is where I cd into my code directory and define a few useful functions.

Useful Commands

These are some things I used just about every day.


Get-Content myfile.log -Wait


# Where is git installed?
$results = Get-ChildItem -Path C:\ -Filter git.exe -Recurse -ErrorAction SilentlyContinue
$git = $results | % { $_.Directory } | Select-Object -First 1

Note: appending -ErrorAction SilentlyContinue is not necessary, but often produces better output. PowerShell will fill the screen with red errors when searching folders the current user doesn’t have access to.


Useful for copying output from the command line. pbcopy is actually mac-specific, but similar tools exist for unix.

Get-Content '.\version.txt' | clip.exe

Previously Covered

Look Out!

Dot-separated properties do not work the same in PowerShell as cmd.exe. For example, if you had a deploy task whose default http.port could be overridden, you’d find that this worked great in cmd.exe and failed silently in PowerShell.

ant deploy -Dhttp.port=8888

This can be dangerous when it is not immediately obvious the value wasn’t taken. To get the same thing working in PowerShell, you’d need to quote the entire define.

ant deploy -D'http.port=8888'

Importantly this is only for dot-separated properties, which are very common in ant. If your project has properties defined with hyphens (http-port), camelCase (httpPort), or most any other way, it’ll work without quotes in both PowerShell and cmd.exe.

Wrapping Up

I had a good time picking up a new skill set while in Windows. I still prefer unix, but it’s nice to know many of the tools I’ve come to depend on have native Windows equivalents. We were able to script lots of tasks that were formerly drag-and-drop with a tool that just worked on every machine. This saved us a ton of time over the course of a year.

Dodging Dependency Nightmares with a Serialization Module

A simple module for serialization can make life a lot easier. When the server and client share the same serialization objects, it eliminates the chance of them getting out sync. I followed this pattern, modeled after the dropwizard recommendation, in my last project and it saved us many headaches.

Read More

Serializing POJOs with Jackson

Plain old Java objects dedicated to serialization help make life easy. This article looks at Jackson's built-in POJO serialization and how to create classes that define a serialization structure without specific library annotations.

Read More

Commitment Book

The graphic novel about project management and risk that can either be great reinforcement or eye-opening. The book walks through an engaging example, focusing on deferring commitment by creating real options.

Read More

grep for Windows

Searching through a huge stack of text files for a particular string can take forever with some of the standard Windows search tools. Reach for PowerShell’s Select-String to quickly find patterns inside files.

Read More

Removing Unwanted Files with PowerShell

This simple-but-common problem is a perfect candidate for combining PowerShell’s Get-ChildItem with Remove-Item, leaving our directory nice and clean.

Read More

How Do I Make Cross-Platform File Paths in Java?

It’s a lot easier to deploy your Java application cross-platform if you consider a few small details like file paths first.

Read More

McAfee Edition: The “CreateRiaClientFilesTask” task failed unexpectedly

Every clean build on my build server was failing with the message The "CreateRiaClientFilesTask" task failed unexpectedly. Usually when a second build ran without a clean, it would pass. Eventually I discovered group policy was forcing a virus scanner to run in the .NET compilation directories, which locked files mid-compilation. This article covers how I solved the mystery.

Read More