Windows PowerShell in Action

Bruce Payette

Mentioned 7

A guide to using Windows PowerShell to script Windows administrative tasks and control Windows from the command line.

More on

Mentioned in questions and answers.

I played with one of the early beta versions of PowerShell V1, but haven't used it since it went "gold". What is the best way to get started using PowerShell?

Which version of PowerShell should I be using (V1.0 vs 2.0 CTP's)? What are you using PowerShell for? Are there any tools that make using PowerShell easier (that is, development environments)?

There are a number of PowerShell tools, for example,

And the Powershell team has a blog.

Count me in with a vote for PowerShell in Action. There are a bunch of blogs out there as well, check out //\O//'s blog, The Huddled Masses, and JB's Powershell (SQL) as well, they go way back with the shell and have gobs of good scripts & snippets to look at.

You can exit PowerShell by typing exit. So far so good. But what exactly is this?

PS Home:\> gcm exit
Get-Command : The term 'exit' is not recognized as the name of a cmdlet, function, script file, or operable program. Ch
eck the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:4
+ gcm <<<<  exit
    + CategoryInfo          : ObjectNotFound: (exit:String) [Get-Command], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand

So it's neither a cmdlet, function, script or program. It leaves the question what exactly it is.

This unfortunately also means that one can't create aliases to exit:

PS Home:\> New-Alias ^D exit
PS Home:\> ^D
Cannot resolve alias '♦' because it refers to term 'exit', which is not recognized as a cmdlet, function, operable prog
ram, or script file. Verify the term and try again.
At line:1 char:2
+ ♦ <<<<
    + CategoryInfo          : ObjectNotFound: (♦:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : AliasNotResolvedException

Are there any more such commands which are no commands?

ETA: Just for reference: I know I can simply wrap it into a function. My profile has the lines

# exit with Ctrl+D
iex "function $([char]4) { exit }"

in them. My question was just to know what exactly this command is.

It's a reserved keyword (like return, filter, function, break).


Also, as per Section 7.6.4 of Bruce Payette's Powershell in Action:

But what happens when you want a script to exit from within a function defined in that script? ... To make this easier, Powershell has the exit keyword.

Of course, as other have pointed out, it's not hard to do what you want by wrapping exit in a function:

PS C:\> function ex{exit}
PS C:\> new-alias ^D ex

I have this idea that I should switch over from cmd.exe to powershell. It's so much more powerful than the tried and tested cmd.exe. It is the shell of the future for Windows.

But my facility in powershell is so limited, in comparison with cmd.exe. Around every corner I discover another seemingly small obstacle that is insurmountable.

Today I tried to ctrl-C to stop a running program, inside a powershell, and it had no effect. ??
Last time through it was "how to do a 'dir /o' in powershell?" I know how to do for loops in .cmd scripts, how do I do that in powershell?

I need some advice: First, is it a good idea to try to switch to powershell?

If so, question 2 is: what are your recommendations on how to break the cmd.exe habit?

  • Should I just post every question to Stackoverflow?
  • Should I dedicate a full day to learning powershell? is there a training course I can take?
  • is there a good cookbook of common powershell recipes? a powershell wiki I can ingest?

I'd suggest reading Windows Powershell in Action. And then just do everything you can in powershell.

I've been in the same situation. What I finally did was close my CMD window that was normally open all day and keep the PowerShell window and force myself to only use it.

I only resorted to CMD when something was urgent and I didn't feel I could take the time to figure it out in PS.

I'm still not quite as proficient in PS yet, but I'm getting better everyday.

Below are a couple good books and some links to some good resources.

I liked these two books a lot:

Also, check out these sites:

PowerShell is definitely in the category of dynamic languages, but would it be considered strongly typed?

It can be if you need it to be.

Like so:

[1] » [int]$x = 5
[2] » $x
[3] » $x = 'haha'
Cannot convert value "haha" to type "System.Int32". Error: "Input string was not in a correct format."
At line:1 char:3
+ $x  <<<< = 'haha'
[4] »

Use the [type] notation to indicate if you care about variables being strongly typed.


As edg pointed out, this doesn't prevent PowerShell from interpreting "5" as an integer, when executing (5 + "5"). I dug a little more, and according to Bruce Payette in Windows PowerShell in Action, PowerShell is actually a "type-promiscuous language." So, I guess, my answer is "sort of."

    PS C:\Projects> 
    get-childitem  -recurse 
 |  where { $_.Extension -eq ".csproj" }
 | foreach { Get-Content $_.FullName 
          | foreach { $_.Length } }

This prints the line size of every line in a csproj (pretty pointless true). How can I also output a outer variable (so to speak) when I've dived further. So for example let's say for pointeless reasons I wanted to have it print the filename too so I would get:

Dog.csproj: 10 Dog.csproj: 50 Dog.csproj: 4 Cat.csproj: 100 Cat.csproj: 440

I figure I want to do something like this but this does not work obviously, (and yes the example is pointless)

  PS C:\Projects> 
        get-childitem  -recurse 
     |  STORE THIS IN $filename | where { $_.Extension -eq ".csproj" }
     | foreach { Get-Content $_.FullName 
              | foreach { $filename ":"  $_.Length } }

I played with tee-object and outputvariable but I'm a bit lost. If a powershell guru could answer it would help, also if you could recommend a book or resource that explains the language syntax fundamentals rather than API monkey stuff of COM/WMI/VB etc.. (that seems most of what I came across) it would be most appreciated. Thanks

This the straightforward way:

`gci . -r "*.csproj" | % { $name = $; gc $_.fullname |
         % { $name + ": " + $_.length }  }`

If you don't yet know the abbreviations, that is equivalent to:

`Get-ChildItem . -recurse "*.csproj" | 
      foreach { $name = $; Get-Content $_.fullname | 
      foreach { $name + ": " + $_.length }  }`

As for a book recommendation, it has to be Bruce Payette's book: