Tome's Land of IT

IT Notes from the Powertoe – Tome Tanasovski

Powershell – Part 2: Opening files, writing to the screen, the pipeline, and dot values

I have found that a great place to start learning a scripting language is by writing scripts to solve word problems.  File input and output operations, text manipulation, variables, arrays, and hashes all need to be understood in order to accomplish a goal like, “find all the 5-letter words in the English language that are palindromes”.  Perhaps the only reason I have found that this is a good place to start is because it is how I started learning Perl.  Regardless, that is where we are going to start today.

The first thing a good puzzle scriptor needs is a decent dictionary file.  I have one that I’ve used for a long time that has been compiled from a few public and private lists.  Sun has one available here.  For this example we’re going to look at ways to open a txt file for reading, read the contents of a file, use a method to go through each line in the file one at a time, and output the results to the screen.

Copy the dictionary file into your working directory or cd to the directory where your dictionary is saved.  get-Content is the method used to read files.  If you look at the aliases available on the definition of get-Alias (see Part 1) you will see some familiar friends: cat, gc, and type.  Try the following (feel free to replace get-Content with your favorite alias):

get-Content dictionary.txt

Before we begin looping through each line of the file we should probably learn the method of writing output to the screen.  Write-Output is the cmdlet that will accomplish this.  It too has some familiar aliases: write and echo.  Try the following:

Write-Output blah blah blah Write-Output "blah blah blah"

When you look at the help page for Write-Output you see that the cmdlet has two functions.  The first is to pass the parameters to the next command in the pipeline.  The second is to output to the console if it is the last command in the pipeline.  This brings us to an extremely important concept within powershell that truly makes it a powerful and simple scripting language: the pipeline.

In DOS or *Nix you may have had to pipe a command at one time or another.  For example a long directory listing would require dir |more in order to stop at every page.  Powershell uses the pipeline to pass objects or collections of objects from one command to the next.

Using this pipeline concept we can take the contents of the get-content cmdlet and pass it straight into a foreach loop so that we can iterate over each object in the collection:

Get-Content dictionary.txt | foreach {Write-Output $_}

Perl developers will immediately notice that Microsoft has stolen one of the greatest features within perl.  The special variable $_ has an almost identical purpose in powershell.  In powershell the $_ variable represents the current object when using specific types of loops or blocks of code.  The following table shows a list of all of the special variables available in powershell.  It comes from an article that digests and discusses variables in great detail:


Variable Name Description
$_ The current pipeline object; used in script blocks, filters, the process clause of functions, where-object, foreach-object and switch
$^ contains the first token of the last line input into the shell
$$ contains the last token of last line input into the shell
$? Contains the success/fail status of the last statement
$Args Used in creating functions that require parameters
$Error If an error occurred, the object is saved in the $error PowerShell variable
$foreach Refers to the enumerator in a foreach loop.
$HOME The user’s home directory; set to %HOMEDRIVE%\%HOMEPATH%
$Input Input piped to a function or code block
$Match A hash table consisting of items found by the –match operator.
$MyInvocation Information about the currently script or command-line
$Host Information about the currently executing host
$LastExitCode The exit code of the last native application to run
$true Boolean TRUE
$false Boolean FALSE
$null A null object
$OFS Output Field Separator, used when converting an array to a string.
By default, this is set to the space character.
$ShellID The identifier for the shell.  This value is used by the shell to determine the ExecutionPolicy and what profiles are run at startup.
$StackTrace contains detailed stack trace information about the last error

In addition to using some great features from Perl, Microsoft has also kept some of the best features from vbscript/c#.  For example Powershell uses dot-notation to further explore the properties of objects stored in variables.  This can best be seen with the following line of code:

Get-Content dictionary.txt | foreach {Write-Output $_.length}

In the above example we are getting the length of the string that is currently in the $_ special variable.  Since the object is currently a string the available properties of the object come straight from the .Net string object.  You can use any of the string properties or methods available within .Net straight from Powershell:

Get-Content dictionary.txt | foreach {Write-Output $_.toupper()}
Get-Content dictionary.txt |foreach {Write-Output $_.chars(0)

One final note.  We’ve been using Write-Output to display data and pass it through the pipeline, but this is optional.  Write-Output is implied.  A variable or a string on a line by itself is really all you need to get the same effect as Write-Output.

Get-Content dictionary.txt | foreach {$_.length}
"Hello World"

We’ve hit a lot of topics in this post that show some of the power behind Powershell.  The ability to pass objects via the pipeline, special variables, and the interoperability between Powershell and .Net make this simple scripting language a very complete and robust programming language as well.  In future posts you will begin to see that Powershell has a certain flexibility that allows users to write scripts their own way.  The perl motto, “There’s more than one way to do it” holds true with Powershell.

5 responses to “Powershell – Part 2: Opening files, writing to the screen, the pipeline, and dot values

  1. Pingback: Powershell – Part 5 – Regular Expressions, oh my! « Tome's Land of IT

  2. Pingback: Powershell – Part 4 – Arrays and For Loops « Tome's Land of IT

  3. Pingback: Powershell – Part 3 – Variables « Tome's Land of IT

  4. Pingback: More on String Performance « The Surly Admin

  5. Jon Miller April 20, 2015 at 9:11 pm

    Get-Content dictionary.txt | foreach {Write-Output $_.toupper()}
    Get-Content dictionary.txt |foreach {Write-Output $_.chars(0)<- missing closing bracket

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: