PowerShell 3.0 – a game changer for every IT professional!

I’ll assume that if you are reading this post, you are an IT professional who probably works at least some of the time on Microsoft technologies. If so, I want to try to sell you on PowerShell. If you are like me, you’ve heard the name, saw a lot of Get-Some-Name type syntax, but it didn’t quite make sense. After all, isn’t PowerShell just a script-friendly version of cmd.exe? And that answer is no, not even a little bit! It’s an unbelievably-impressive platform – truly!!

I have since had a few “ah-ha!” moments with this platform, and now I “get it”. So, between this crash-course of a blog post, and the resources listed at the bottom, I think anyone can become fairly fluent in PowerShell in a matter of days.

I haven’t been this impressed with a technology in a long time. It is tremendously powerful tool for any IT professional.

OK, first – just some of the facts:

  • PowerShell 3.0 comes pre-installed on Windows 8 and later, and Windows Server 2012 and later. Previous versions of server or workstation operating systems including older versions of PowerShell and require a download (see here) if you want to use 3.0 (which you should do).
  • PowerShell is a combination of: a scripting language, a way to interact with the .NET Framework, a “REPL” (similar to F#, Python, etc), Windows Explorer, regedit, a command-line shell, a certificate manager, a WMI client, and adhoc reporting tool, etc, etc, etc – all rolled into one.
  • PowerShell would be useful for:
    • A systems manager – because you can manage/edit/monitor virtually every part of a Windows computer or domain.
    • A security professional – because you can manage/edit/monitor certificates, event viewer logs, policies, etc for a computer or domain.
    • A developer – because you can not only automate functionality on your workstation, you can also consume SOAP and RESTful web services (and even output data to a UI), or connect to a web page and screen scrape with a remarkably small amount of code.

Hopefully, I’ve piqued your interest, if so – let me try to give you the shortest summary possible to get started. Below are some of the major highlights – or at least some of the categories of awesomeness in PowerShell!

Getting Started…
If you are on Windows 7 or 8, you can hit the WindowsKey on your keyboard and type “powershell” and launch the program. However, it will be easier if you right-click and Run As Administrator – as some features need admin abilities:

image

This is what you should see:

image

PowerShell has an amazing help system, but it’s not installed by default. So, one of the first things you want to do is update the help.

Update the Help System:
You must be running as Administrator to do this. You simply run:

Update-Help -Module * -Force

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

and You’ll see a screen like this which will flash as it’s updating the help for all of the modules:

image

Not all modules have help, so it’s normal to get something like this at the end which tells you it couldn’t get help for some modules:

image

Where do I start?
Well, you can run a bunch of commands from PowerShell, but how do you find them and how do you find the syntax?

You can run Get-Help – to see how to use Get-Help. You can also start with a command like:

Get-Help Get*

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

This will list all of the commands which start with Get:

image

You might have noticed that a zillion lines went scrolling by. So, now is a good a time as any to start learning how to format output! Before we dig into that though, let’s cover how to bring up help for exactly one thing so that we at least have that covered.

There is a command call Get-Process which brings back all the processes running on the current computer. To find out how to use it, type:

Get-Help Get-Process

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

As you can see, you have some additional options.

mx3D0A5

For example, you might call Get-Help Get-Process –Examples to just show examples on how to use the command. Or, you might call Get-Help Get-Process –Full to see the complete documentation for that particular function.

Formatting the help:
There are two particularly useful ways to make this documentation easier to use. First, is to have the help page scroll. To do this, you can “pipe” the help command to “more”. This will make it so you can use your arrow keys to scroll up or down, use spacebar to page down and use the letter “q” to to quit the help and go back to the prompt:

Get-Help Get-Process -Full | more

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

You can tell the content is being handled by “more” because you see that description at the bottom line of the window:

mx37E50

This is great, but what if you want a GUI? Well, there is a really easy way to do that too:

Get-Help Get-Process -ShowWindow

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

That pops open a window like this:

image

Not only can you search for and zoom text, click on that settings and you get:

image

So this is all the same content from the command-line, but all viewable in a GUI. Cool, eh?!

At this point, we know how to show the help for a given command, how to browse that help one page at a time, and to even show the help in a GUI window. This syntax is exactly the same regardless of which command you need help with.

Formatting Output: List
OK, so getting back to our first problem of “what commands can I call?”. You might recall we did something like this:

Get-Help get*

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

but all of the results went flying by. Well, one thing we could do is pipe it to “more”, like we did before. That would be a step in the right direction – because then we could page through the data:

Get-Help get* | more

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

and sure enough, that works:

image

Use the up and down arrow keys to scroll up and down, use the space bar to advance one page, and use the letter “q” to quit.

However, depending on the kind of data coming back – you can automatically format it as a list, as a table, or as a grid. A good example of formatting data as a list might be:

Get-UICulture

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Which outputs a table like this:

mx37F1A

However, we can do something like this:

Get-UICulture | Format-List

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Which formats this data in a “details view” sort of way:

mx35CF6

If you are coming from a development background, it might blow your mind about what is happening right now. How is this possible? Well, PowerShell doesn’t actually pass text around, it passes “objects” around via a “pipeline” (whenever you see that | symbol).

So, Get-UICulture actually has these 2 dozen properties in an object, and it puts that object in the pipeline for someone else to format or use as input! This becomes an immensely useful and powerful feature later too!  …and yes you can pipe a command like this to a Select-Object which can be used to limit which fields are shown, add calculated fields, and rename the headers. For example, you could do something like this:

Get-UICulture | Select-Object -Property @{Name="Language-Culture";Expression={$_."Name"}}, DisplayName | Format-List

This results in something like this:

mx3F56A

I just want to expose you to the idea that you can have calculated columns (like the “Language-Culture” column) which you can manipulate.

Formatting Output: Table
We’ve already seen a table, but here is some more detail about how that works. I can do something like this:

Get-Service | Select-Object -First 10 | Sort-Object -Property status, name -Descending | Format-Table

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

And that results in something like this:

mx3D721

To recap, we are calling Get-Service to get all of the local services, piping that to Select-Object which is going to pull the first 10, then it gets piped over the Sort-Object which sorts the results, and that gets piped over to Format-Table. Now, you can pass –AutoSize to Format-Table, and that will clean up the table a bit too:

mx325E8

So, instead of showing the “…”, it just made the columns wider – pretty nice!

Formatting Output: GridView
There are two really, really cool things you can do with a table of data. You can simply show it in a UI gridview, or you can pipe it to a gridview so that the user can use it to select a value – and you use that further processing.

Let’s start with the simpler case. Let’s get the services and simply dump them to a grid view:

Get-Service | Out-GridView

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

That pops open a window like this:

image

You can click on the columns to sort, type in the filter box to filter, or use the Add Criteria to add specific filtering criteria. Very cool stuff, right?!

Just to be very clear – this isn’t a UI for managing services, this is a general purpose gridview for display a bunch of data. That is all we are doing here. You can dump ANY object to a grid like this, and have it be sortable and searchable.

What if I want to go get a list of running services, prompt the user for which one I should stop, and then stop that service? We could do something like this:

Get-Service | Where-Object Status -eq Running | Out-GridView -PassThru | Stop-Service -WhatIf

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

The “-WhatIf” argument is supported by most commands that actually DO something, and allows you to run the command, but not actually execute it. It allows you to mock up a command first and make sure you have the syntax correct. So, in this case, I’m going to pretend to stop those services.

When I run this command, I see a window like this:

image

I hold down the CTRL key to select multiple entries, click OK and I see:

mx3634

And by the way, you can set the title bar text, height, width, etc – it’s a very powerful tool. I’m just trying to cover some of the basics, here.

So wait, what commands can I run?
Oh yeah, so let’s put together what we’ve learned. We should be able to now do something like this:

Get-Help get* | Out-GridView

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

That pops up a window like this – showing you all of the Get* commands:

image

The good news is, this is still not the best solution. See the Show-Command feature later in the post – or better, using the shell editor and it becomes much easier to browse available commands AND the parameters which you can pass to them. Both are covered later in this post.

Understanding “Providers”:
This is a very powerful concept. Have you ever noticed that there are hierarchies of things on our computers which are all very similar?

mx3CE0E mx32585 mx3DAB7

well, in PowerShell, these things (the file system, the registry, a certificate store – among many other things) can all be traversed the same way. You can add, edit, view, delete, and manage each one of these the same way simply by setting your location (with Set-Location).

Want to work on the file system (create, edit, delete, find things) – use Set-Location C:

Want to work on the HKEY_CURRENT_USER registry hive – use Set-Location HKCU:

Want to work on the certificate store where you personal certificates are – use Set-Location Cert:CurrentUser

For example, let’s try each of these (note that Get-ChildItem is called on each one):

mx35288

mx3323A

mx3AE01

So, this means that the syntax for creating, editing, deleting new items is very similar for ANY hierarchical item. So, what other providers are there? You can run:

Get-PSProvider

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

to see:

mx37837

So, this means that you can step into your environment variables and your list of aliases (shortcut expressions in PowerShell so you don’t have to keep typing long words). I haven’t tried it, but supposedly you can install a SQL Server provider, which means you can then operate inside of a SQL server with all of these commands too – which means you could programmatically access or modify various aspects of your SQL Server (see here) – amazing, right?

Just a note on aliases, I’ve been using long-hand, but there is short-hand for most of the things we’ve done so far. For example, “gps | fl” does a Get-Process | Format-List. You can see all the built-in aliases by setting your location and doing a “dir” (which is an alias for Get-ChildItem):

mx33AF7

You can create your own aliases and even store them in a file which you can set up on all your machines too.

Using Show-Command:
Let’s say you are sick of typing and running Get-Help constantly. Well, you can run:

Show-Command

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

and that pops open this window:

image

You can start typing and/or browse though all available commands. When you pick one:

image

it shows you all the possible settings for that command, in a UI. Fill it out and click Run and it generates the correct command for you and runs it:

mx37E2

Again, this is yet another aspect of the help system which makes PowerShell pretty easy to learn, in my opinion.

Using the ISE:
The Windows PowerShell Integrated Scripting Environment (ISE) is most of the things we’ve learned so far, put into one place. At the PowerShell prompt, simply type ISE and hit <enter> – that should bring up something like this:

image

On the top is a file editor where you can write and test PowerShell scripts (which end in a .ps1 file extension). The bottom pane is where those scripts are run, or where you can type in commands – it’s a regular PowerShell window. On the right is the Show-Command utility, but it too is tied in with the shell. So, when you create a command, it gets executed in the PowerShell prompt in this app.

This is a really great, full-featured little app. It even has intellisense in the editor!

mx3B768

and not just while editing files, you get intellisense in the console window too!

image

Using PowerShell for accessing the web:
Lastly, I wanted to show that you can use PowerShell to easily work with web services, JSON, RSS feeds, and even for screen-scraping HTML! Here are a few examples:

mx36574

In this case, I went out to the RSS feed of this blog, put the contents into a variable called $content – and then was able to show the channel details. This is an object – which means I could also dump this out as a table, put it to a gridview, etc. Once the data (the object) is in PowerShell, it can be used like any other object that we’ve seen already – and pass it down the pipeline.

mx3E19

In this second example, I can connect to a REST web service which returns JSON, and PowerShell simply knows how to deserialize it into an object. This means that I can now do what I want with it, as a first-class dynamic object in PowerShell. Very powerful stuff!

Using PowerShell to interact with the .NET Framework:
You can use any part of the .NET Framework using syntax like this:

mx3655

As you might imagine, if the method call returns back an object, it’s a PowerShell object, which means you can pass it via the pipeline, and output it how you like. For example, here’s a System.IO.FileInfo object:

mx3CF31

To recap – we loaded a .NET assembly, created a new instance of a .NET type, took the result of that .NET call, turned it into a PowerShell object, and then sent it to the Pipeline for Format-List to format. Cool!

Resources:
I stumbled across all of this because I got the book Windows PowerShell 3.0 Step-By-Step (Wilson) – which is pretty good by the way. I recommend it! Then, I went on Pluralsight and watched a handful PowerShell 3 courses (or parts of them).

Between those two source and simply playing around with PowerShell on my own computer, that was all I needed to get off the ground!

Bottom line:
I was absolutely blown away at how powerful this platform had become. The book listed above is what got me going on this, and after a few days of messing around with it – I am no pro, but I certainly feel pretty comfortable with it.

What’s even better is that for any question that I’ve had, a google search had an answer for me in a minute. There are tons, tons, tons of forums, discussion boards, blog posts, documentation, etc on PowerShell. So, between the powerful help system that is already included, plus what’s available on the web, this becomes a pretty easy platform to learn and adopt.

I obviously didn’t even begin to scratch the surface with what PowerShell can do, but hopefully just with some of these highlights, it’s enough to get you interested. I know for me, this is absolutely a technology I will continue to learn and use. Whether it’s for managing my workstation, doing infrastructure stuff, or messing with web services – I can see this being handy for many, many things.

Posted in Infrastructure, PowerShell, Professional Development, Uncategorized
One comment on “PowerShell 3.0 – a game changer for every IT professional!
  1. Jamie Dixon says:

    Nice write up

    Like

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s

Archives
Categories

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 2 other followers

%d bloggers like this: