Search
Generic filters
Exact matches only
Filter by Custom Post Type

Do Anything in One Line of PowerShell

PowerShell provides a tremendous boon to productivity for computer professionals of all types. But, you have to admit: it can be a bit daunting to get up to speed! Indeed, as someone who has a fair amount of experience using it, I still find myself having to look up how to do things--frequently. So I started keeping track of the recipes I was using the most. And came up with a list of 400 or so, published in 4 parts.

Though I actually wrote these a couple years back they are certainly still relevant today, just covering a bit less of the ever-expanding PowerShell universe of discourse!

(Note that at the end of each web article listed above is a link to download it as a PDF that is more tidily formatted.)

PowerShell Gotchas

You can certainly find a number of articles around that present PowerShell pitfalls that can easily trip you up if you are not careful. I took a different approach in my three-part series, A Plethora of PowerShell Pitfalls.

The first two parts are presented in quiz format, together covering the top 10 "gotchas". They will help you test your awareness to see if you even realized the danger and did not know you've been skirting those traps for awhile. After you've had an opportunity to consider the conundrums presented, I then go into detailed explanations for why they happen and how to fix them.

The third and final part is a compendium of all the common "gotchas" that I put together after reviewing all the other lists out there. The more than 35 entries in the list cover, I believe, a good 98% of the issues you would likely encounter. Yes, there are more esoteric pitfalls as well, but I ran out of web page... 🙂

Part 1: Pesky Parameter Problems

Part 2: A Portion of Potential Puzzles

Part 3: The Compendium

 

Pitfalls of the Pipeline

Pipelining is an important concept in PowerShell. Though the idea did not originate with PowerShell (you can find it used decades earlier in Unix, for example), PowerShell does provide the unique advantage of being able to pipeline not just text, but first-class .NET objects.

Pipelining has several advantages:

  • It helps to conserve memory resources. Say you want to modify text in a huge file. Without a pipeline you might read the huge file into memory, modify the appropriate lines, and write the file back out to disk. If it is large enough you might not even have enough memory to read the whole thing.
  • It can substantially improve actual performance. Commands in a pipeline are run concurrently-even if you have only a single processor, because when one process blocks, for example, while reading a large chunk of your file, then another process in the pipeline can do a unit of work in the meantime.
  • It can have a significant effect on your end-user experience, enhancing the perceived performance dramatically. If your end-user executes a sequence of commands that takes 60 seconds, then until 60 seconds has elapsed he/she would see nothing without pipelining, whereas output could start appearing almost immediately with pipelining.

PowerShell provides a variety of techniques for using pipelining but it is all to easy to do it wrong, so you think you are pipelining but in fact you are not. In my article Ins and Outs of the PowerShell Pipeline, I discuss the most common things that can trip you up with implementing pipelining and how to avoid them.

Create Custom Monitors with PowerShell

Sometimes, as a developer, you want to be be able to keep track of free space on a drive, the size of a log, the load on your CPU, the number of users logged in, etc. With PowerShell, it is typically just a matter of finding the right cmdlet amidst the large (and rapidly growing) pool of cmdlets provided by Microsoft and by third parties. Then you just run Get-Foo to check details about the foo resource. And then you come back 5 minutes later and run it again because you want to see how it changes over time.

But wouldn't it be nice if you could just have it run automatically at regular intervals in a separate window that you could just keep in the corner of your screen? Well, I found the barebones of just such a utility sometime ago (authored by Marc van Orsouw,  aka ‘thePowerShellGuy’). His original post is no longer available, but I expanded upon his code and, over time, added features, bug fixes, and enhancements, making it more useful and more user-friendly. Here are a few screenshots of the Monitor Factory in action.

Monitor the size of a database

Start-Monitor -AsJob {
    Invoke-Sqlcmd 'DBCC SQLPERF(logspace)' |
    Select-Object 'Database Name','Log Size (MB)','Log Space Used (%)',HasErrors
}

Database Size Monitor

Monitor drives on a system
Drive Capacity Monitor

Monitor longest running DB queries
Long-runnning DB Query Monitor

Build Your Own Resource Monitor in a Jiffy reveals how quick and easy it is to get started with the Monitor Factory.

Every pithy witticism begins with quotation marks

"To be or not to be". Without getting into a debate over whether Shakespeare was musing about being a logician, suffice to say that in writing prose, the rules of when and how to use quotation marks are relatively clear. In PowerShell, not so much. Sure, there is an about_Quoting_Rules documentation page, and that is a good place to start, but that barely covers half the topic. It assumes you need quotes and then helps you appreciate some of the factors to consider when choosing single quotes or double quotes.

But do you need quotes? Remember PowerShell is a shell/command language so "obviously" you can do things like this:

PS> Delete-Item C:\tmp\foobar.txt
PS> Get-ChildItem *.log
PS> Get-Process svchost, conhost, powershell

It would certainly be cumbersome if you needed to quote each of those arguments, so PowerShell was designed well, in that respect.

But what if you ran the same commands just slightly differently?

PS> "C:\tmp\foobar.txt" | Delete-Item 
PS> "*.log" | Get-ChildItem 

Here you must use quotation marks or you will suffer the wrath of a terminating error from the PowerShell host most certainly!

Those are just a couple of the many examples I consider in When to Quote in PowerShell. Accompanying the full article, I also included a wallchart that condenses all the article's salient points into a single-page reference. Here's a fragment of the wallchart:

Guide to PowerShell Quoting wall chart

Read the article and download the wallchart here.

Complete Guide to PowerShell Punctuation

Quick as you can, can you explain what each of these different parentheses-, brace-, and bracket-laden expressions does?

${save-items}
${C:tmp.txt}
$($x=1;$y=2;$x;$y)
(1,2,3 -join '*')
(8 + 4)/2
$hashTable.ContainsKey($x)
@(1)
@{abc='hello'}
{param($color="red"); "color=$color"}
$hash['blue']
[Regex]::Escape($x)
[int]"5.2"

When you're reading someone else's PowerShell code, you will come across many of these constructs, and more. And you know how challenging it can be to search for punctuation on the web (symbolhound.com not withstanding) !

That is why I put together a reference chart containing all of PowerShell's symbology on one page. making it much easier when you need to look up a PowerShell symbol as you read code--or to browse for the right construct when you are writing code.

PowerShell Punctuation wall chart

Download the Complete Guide to PowerShell Punctuation wallchart from here.

Practical PowerShell Unit-Testing

By the time you are using PowerShell to automate an increasing amount of your system administration, database maintenance, or application-lifecycle work, you will likely come to the realization that PowerShell is indeed a first-class programming language and, as such, you need to treat it as such. That is, you need to do development in PowerShell just as you would with other languages, and in particular to increase robustness and decrease maintenance cost with unit tests and--dare I say--test-driven development (TDD). I put together several articles on getting started with unit tests and TDD in PowerShell using Pester, the leading test framework for PowerShell. This series introduces you to Pester and provides what I like to call "tips from the trenches" on using it most effectively, along with a gentle prodding towards a TDD style.

Part 1: Getting Started with the Pester Framework

Starting with the ubiquitous "Hello, World", this introduces Pester, showing how to execute tests, how to start writing tests, and the anatomy of a test.

Part 2: Mock Objects and Parameterized Test Cases

To be able to create true unit tests, you need to be able to isolate your functions and modules to be able to focus on the component under test; mocks provide great support for doing that. Another topic of "power" unit tests is making them parameterizable, i.e. being able to run several scenarios through a single test simply by providing different inputs.

Part 3: Validating Data and Call History

The final part of this series provides a "how-to" for several other key parts of Pester: how to validate data, how to determine if something was called appropriately, and how to address a particular challenge with Pester, validating arrays. I've included a library for array validation to supplement Pester.

For a more general treatment of unit tests, I refer you to Roy Osherove's canonical text on the subject, The Art of Unit Testing.

... you wanted to know about Unit Testing in .NET | Coding in .NET

Documenting your PowerShell API--solved!

Long has it been known how to easily document your PowerShell source code simply by embedding properly formatted documentation comments right along side your code, making maintenance relatively painless...

 

Sample Doc-Comments for PowerShell source

But if you advanced to writing your PowerShell cmdlets in C#, you have largely been on your own, either hand-crafting MAML files or using targeted MAML editors far removed from your source code. But not anymore. With the advent of Chris Lambrou's open-source XmlDoc2CmdletDoc, the world has been righted upon its axis once more: it allows instrumenting your C# source with doc-comments just like any other C# source:

csharp doc-comment sample

All of the above provides fuel for Get-Help, i.e. providing help one cmdlet at a time. But we are a civilized people; we also need a web-based version of our full custom PowerShell API. That is, a hierarchical and indexed set of Get-Help pages for all the cmdlets in our module. For this task, my own open-source effort, DocTreeGenerator, nicely fills the gap, requiring very little beyond the doc-comments described above to do the complete job.

I have written extensively on using both XmlDoc2CmdletDoc and DocTreeGenerator, and just this week, released a one-page wallchart that shows how all the pieces work together:

doc wallchart thumbnail

Here's the link to get you started on this fun journey:

Unified Approach to Generating Documentation for PowerShell Cmdlets

Skip to toolbar