PowerShell Live - being retired

Please go to http://www.shelltools.net for more information

Welcome to PowerShell Live - being retired Sign in | Join | Help
in
Home Main Site Blogs Forums Videos Chat Customer Support

Mastering PowerShell in your Lunch Break

Day 1: Getting Organized

Hi, I am Tobias, maker of the WSH script IDE “SystemScripter” (www.scriptinternals.de) and I use WSH and VBScript for many years now.

PowerShell has a lot of faces and purposes. One is to be a much more powerful replacement for the very limited cmd.exe based console, and this is what we are exploring today. After this, you will be able to use PowerShell as replacement for cmd.exe. Other topics follow.

I'll focus on some simple things and facts and restrain myself from theoretical blabla and hysterical how great all of this is. Let’s just check out the basics in your lunch break and have some fun.

Downloading And Installing The PowerShell Stuff

All the PowerShell downloads are available at:

http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx.

PowerShell runs on Windows XP SP2, Vista and Longhorn Server. On the download page, you find a version for each of the OS and also localized versions if you care. You may need to download and install the .NET framework if it is still missing on your machine. The installation routine will notfiy you in this case.

The download is straight-forward, and after installing the package, I find a new item in my start menu. A click on it launches the new PowerShell console which looks pretty much like a normal console window.

The Console Look-And-Feel...

In fact, the PowerShell console is designed to work as a replacement for the traditional console window, so you can launch pretty much anything that works in a cmd.exe window.

Ping 127.0.0.1

Is that true for batch files as well? Let’s check it out! I open my batch file development system “notepad”:

Notepad

Next, enter some batch code:

Echo Hello World

Now save the file as c:\test.bat. When you launch the file from inside Powershell, things seem to work:

C:\test.bat

Different Things Work Different 

However, PowerShell does contain differences. Check this out:

Cd \

Test.bat

I changed the directory to c:\ and tried to launch the batch file using a relative path. PowerShell throws an error and tells me that the file isn’t there. What’s that?

As it turns out, PowerShell does not allow you to run files with relative paths. Unfortunately, the error message really does not give you any meaningful clue of the true cause. It simply complains about a missing file.

You would have to call the batch file like this:

.\test.bat

This is a new security measure designed to prevent you from accidentally launch malicious files. Let’s examine this a bit more closely.

I was able to launch my notepad editor simply by typing in “notepad”, without a qualified path. I was also able to use "ping" as-is. Why could I do that but cannot run my batch file in the current directory?

Notepad is located in one of the folders that is part of the %path% environment variable. You can run anything that's located there without a qualified path.

A virus author could place a malicious script in your current folder and call it “notepad.exe”. Then, the next time you type in “notepad”, a traditional console would launch the first instance of “notepad.exe” it finds, which unfortunately would be the virus. To avoid this, PowerShell makes you specify the entire path name if the file is not located inside of one of the %PATH% folders. If you explicitly want to launch a file in the current folder, you have to use “.\”.

Now let’s take another look at what you can actually launch from inside a PowerShell console. In a traditional console, you can either launch external programs and files such as “ping.exe” or “test.bat”, or you can use one of the internal commands built into cmd.exe like “cd” or “dir”.

Of course, you can still launch external programs as you have seen with "notepad" and "ping". What about the internal commands?

Commandlets: Internal PowerShell Commands

PowerShell provides replacements for these internal console commands so you can still use them. So when you type in the following line, you get a directory listing, just as expected:

Dir

The directory listing looks slightly different from what a Dir result would look in a classic console. That’s an indicator that you are no longer using the old “Dir” command built into the classic cmd.exe but instead you are using a similar – not identical – PowerShell command.

These PowerShell commands are called Commandlets. So in addition to any executable you can also use any of the 100 or so built-in PowerShell Commandlets.

Let’s check out this example:

Dir > c:\temp.txt

Type c:\temp.txt

With these two lines, you have stored the result from Dir in a text file and then outputted the result using “type” – just as you would do it in a classic console.

Aliases Make You Feel At Home

To reveal the “real” PowerShell commandlets that actually did the work, you can use the commandlet get-alias:

Get-Alias Dir

Get-Alias Type

As it turns out, Dir really is an Alias name (a shortcut) to the commandlet Get-Childitem. Type really invokes the commandlet Get-Content. That’s why you could also use these lines:

Get-Childitem > c:\temp.txt

Get-Content c:\temp.txt

Aliases make it easier to type commands because aliases allow you to use the command names you are used to and also are shorter than the official commandlet names. Before I explore how aliases really work, I strongly recommend using TAB-completion. TAB-completion works by pressing the TAB key to complete your input. This way you don’t have to type long command names. In fact, TAB-completion completes not only command names but also variables, methods and much more. Let’s focus on commands for the moment. When you type in the following line and hit TAB, you get an automatic completion:

Get-Ch (TAB)

If there is more than one possible match, you can hit TAB multiple times and see all the available matches until you get to the one you want to use.

To list all of the aliases available, you use the commandlet get-alias:

Get-alias

You can now identify the aliases and which “real” commands/commandlets they refer to. If you want to see only certain aliases, let’s say anything that starts with a “d”, you use:

Get-alias d*

But wait! How would I list all aliases that refer to the commandlet “get-childitem”? To do that, you have a number of choices, but first we need to look at “Piping”. I’ll discuss piping in a lot more detail in a later post, but here’s the short story:

Instead of outputting the results of a command, you can also feed it right into another command. This is called “piping”, and piping works in a classic console as well. The major difference is that PowerShell hands over not only the text-based results a command returns. Instead, it hands over “objects”. Each alias returned by “get-alias” would be handed over to the next command as “alias object”. If that sounds strange to you, hang in. The major advantage of passing objects instead of strings is that you can access all the object properties. You do not loose any information.

In a traditional approach where commands simply return text information, you could filter information like this:

Get-Alias > c:\alias.txt

Type c:\alias.txt | select-string "Get-Childitem"

By redirecting the output of “Get-Alias” into a text file, I simulate a text result. I can then take the text result and feed it via “Type” (or Get-Content for that matter) into the Pipeline. The “|” symbol sends the output to the next command. In this case, “Select-String” filters out all lines that contain the search phrase. The result is quite interesting because it reveals that PowerShell has a number of aliases for the same commandlet:

PS C:\> type c:\info.txt | select-string "Get-Childitem"

Alias           gci                                                 Get-ChildItem

Alias           ls                                                  Get-ChildItem

Alias           dir                                                 Get-ChildItem

So in PowerShell, it really does not matter whether you use “Dir”, “ls” or “gci”. Aliases allow you to keep your existing knowledge no matter if you are used to a classic console or have a unix background.

Since PowerShell really pipes objects, however, you could have retrieved this information in a much easier and more exact way. The previous example would have listed any text line that contained the search phrase anywhere inside of it. With objects, you can explicitly ask for specific properties to be evaluated.

So try this line:

Get-Alias | where-object {$_.Definition -match "Get-Childitem"}

You get almost the same result. In this case however note the column headers that indicate that the result contains the actual alias objects that match “get-childitem” in their definition property. Actually, the column headers resemble the available obejct properties.

A quick note on properties: By default, PowerShell only outputs default properties, so with Alias objects you only see the most common properties. If you'd like to see them all, use this:

Get-Alias | format-table -property *

Instead of the "*", you could also list the properties you want to see to create a custom view. However, to really see and enjoy all of the properties, you would have to expand your consoles screen buffer width (because otherwise most of them are cut-off) or redirect the output to a text file and open that in your editor of choice.

Check out how verbose the output gets when you choose to display every single property an object contains:

Dir | format-table -property *

Format-table therefore is a great commandlet to examine results in a more detailed way. It also illustrates why object piping is so valuable. As you can see, objects contain much more information than is usually outputted to the screen. By piping the live objects instead of the text result, you keep that rich information and can use it i.e. for evaluating or filtering. Yo do not loose that information as you would in case of text piping.

The other strange commandlet is where-object. where-object evaluates all of the objects one by one that are on the pipeline. where-object therefore loops through the alias objects returned by get-alias much similar to a for each...next loop.

The loop itself is defined by the curly brackets. Inside the loop, $_ refers to the object the loop is currently evaluating. 

So what does the -match thing do? It is actually an operator. I am sure you are familiar with simple arithmetic operators such as "+" or "*". There are also more subtle operators like -match. This operator returns true if the expression evaluated matches the text that follows the operator.

In this case, the loop evaluates the Definition property of the current object and compares it against "Get-Childitem". If it matches, this object is returned (therefore outputted to the screen). If it does not match, it gets nuked.

There are tons of other operators that help you evaluate expressions, replace characters etc. To find out more about operators, use this command:

get-help about_operator

If your lunch brake is long enough, there's a lot more reading material that you can display in just the same way. To get the full picture, try this:

get-help about_*

To further prove that you are actually working with objects, you could limit the output to a specific column, let’s say Name, just to get the alias names tied to “get-childitem”. Simply take the result from where-object and pipe it into yet another commandlet:

Get-Alias | where-object {$_.Definition -match "Get-Childitem"} | fl name

“fl” really is another alias that refers to… find it out yourself! It creates a list where only the “name” property is displayed. Instead of “fl”, you can also use “ft” which creates a table instead of a list. And if you just want to see the names and omit the property name “name”, you could do it this way:

Get-Alias | where-object {$_.Definition -match "Get-Childitem"} | fw name –column 1

You have now seen a couple of commandlets in action, and you have seen how easy it is to glue together different commandlets to process results until you get what you are looking for. Let’s next examine how to fully exploit commandlets and learn about all of their parameters and arguments.

To see all available commandlets, you can use this command:

Get-command

Note that in the first column, the results tell you what kind they are. Initially, all of them will be marked as “Cmdlet”, indicating that they are internal commandlets built into PowerShell. You may also discover other kinds but initially, get-command shows only commandlets. We’ll go over other options shortly.

I Want Help!

To find out more about what a commandlet can do for you, simply use the parameter “-?”. So to find out more about get-command, type this:

Get-Command -?

You now get a short description that tells you the most important details. The parameter “-?” is a good choice when you already know a commandlet and want to quickly look up let’s say the correct syntax, or when you want to find related commandlets. If you want to learn the capabilities of a commandlet from scratch, I recommend you open the detailed help for it:

Get-help get-command -detailed

Now, PowerShell dumps a lot more information on you including lots of helpful sample code.

This way, you find out that get-command supports a number of parameters. Parameters are the pieces of extra information you supply with a commandlet, and parameters always start with a “-“. Let’s pick three parameters to play with: -verb, -noun and -commandType.

You have seen that get-command alone will dump all available commands. Initially, all of them are commandlets but there may be others as well. If you want to see all commands, try this:

Get-command -commandType All

Here’s a little annotation from a syntax geek: The command uses a parameter and an argument. In many other languages, both are the same. In PowerShell, parameters work like switches and always start with a “-“. If the switch needs additional data like the kind of command types you wish to list, this additional data is called “argument”. An argument belongs to a parameter, and a parameter belongs to a command.

Equally important: Up to now, you have discovered that there are two things that both start with a "-": parameters (that belong to a commandlet) and operators like -match that do not belong to a specific commandlet but rather do some evaluation and return a result.

Now PowerShell needs some time to think and then dumps all available commands. As you will see, this is a list of just about anything you can type in and launch from your PowerShell console: Application (external exes and documents that reside in a %PATH% folder like ping.exe), Alias (the alias shortcuts to other commands), Cmdlet (the true internal PowerShell commands) and Function (scripts that consist of PowerShell commands). This is a good example for a first summary because it sums up anything that you can launch.

The other two parameters, -verb and -noun, reveal the nature of commandlets. To provide for some consistency, commandlet names always use a verb-noun-pair. Check it out yourself! All of the commandlets we used so far use this pattern. And you can use that pattern to find related commandlets easily:

So to sum up the alias experiment, check out which other commandlets deal with aliases. Since “Alias” is the noun in the commandlet get-alias we used before, to find related commandlets, you could use:

Get-command -noun Alias

Again a note: You could also write: Get-command -noun "Alias". The quotes are not really necessary, though. The short story is: Use quotes only when there are whitespace characters in your argument OR if the argument conflicts with an existing command name like the name of an existing commandlet AND could be wrongly interpreted. Use single quotes if you want the text to be as-is. Use double quotes if you want to expand variables inside of your argument.

Forget about all of these details if you feel confused. We’ll be covering them later anyway. If you are in doubt, enclose your arguments with single quotes: get-command -noun 'Alias'. This way, you are always safe.

With the above command, you get a list of commandlets related to aliases. And now you know how to create your own aliases:

Set-alias editor notepad.exe

This creates a new alias called “editor” and launches the notepad editor. As you can see, aliases are not limited to commandlets. You can use any command listed by get-command as target for your alias. The only limitation to aliases is: you cannot specify arguments to your commands.

Now, how do you delete an alias once you created one? That’s a last thing for today. PowerShell gives you access to a lot of information stores in pretty much the same way as you are used to it from the file system. For example, when you want to list the content of drive c:, you say:

Dir c:\

In pretty much the same way, you can also dump the content from other information stores such as the registry, your environment variables or your certificate store:

Dir HKCU:

Dir env:

Dir cert:

Another note: PowerShell for the most part is case-insensitive as you may have guessed by now!

To remove an alias, you use the virtual “alias:” drive and remove it either with the alias you are used to like “del” or with the commandlet remove-item that is tied to “del”:

Del alias:editor

Remove-item alias:editor

Summary 

PowerShell is a free add-on for XP SP2, Vista and Longhorn. It replaces the traditional cmd.exe based console, and you can do almost anything with it you could do with the traditional console.

The internal cmd.exe commands have been replaced by aliases that point to some of the approximately 100 internal PowerShell commandlets. This allows for a nice and seamless transition of your existing cmd knowledge to PowerShell.

The real "meat" is in the commandlets, though, that you can list and examine with get-command and get-help. Commandlets take parameters which work like switches, and those parameters always start with a "-". Some parameters need additional info which then is called arguments. You have also discovered the family of operators that evaluate expressions and return results. Some operators like -match also start with a "-", and to find out more about them, you can use the command get-help about_operator.

We also scratched one of the single most powerful new functionality: object piping. You have seen how you can glue together commands to process results until they match what you were looking for. We'll talk about objects and piping in a lot more detail in a later post, but for now you have used the where-object loop that lets you examine each returned object and filter unwanted objects by using operators like -match.

In the next column, I’ll show you how to peacefully transition from existing WSH/VBScripts to PowerShell. And then we dive deeper into more subtle topics, closely examine the object pipeline and PowerShell functions and scripts.

By the way: I strongly urge you to get one of our GUI PowerShell editors. Get PowerShellAnalyzer from www.powershellanalyzer.com or PowerShellIDE from www.powershell.com. The latter still states it’s for PowerShell RC2 but works fine with the final PowerShell RTM release as well.

Also I’d like to invite you to comment this blog. Please add questions that you find not answered (but related) to the blog, correct things I may have explained wrong and leave your feedback.

Cheers for today

Tobias

 

Comments

 

aleksandar said:

Application, Alias, Cmdlet, Function and All are not the only arguments that you can use with parameter -commandtype. If you try this:

get-command -commandtype *

you will get the error:

Get-Command : Cannot bind parameter 'CommandType'. Cannot convert value "*" to type "System.Management.Automation.Comma

ndTypes" due to invalid enumeration values. Specify one of the following enumeration values and try again. The possible

enumeration values are "Alias, Function, Filter, Cmdlet, ExternalScript, Application, Script, All".

At line:1 char:25

+ get-command -commandtype  <<<< *

So, there are three more - Filter, ExternalScript and Script.

When I use argument Filter I get the same output as with argument Function.

There is no any Script commands on my system, and I can't tell you what that represents.

But, what about ExternalScript? If you add some of your scripts to the %path% environment variable, you will get them when you type:

get-command -commantype ExternalScript

And, to end this comment, let's look what PowerShell tells us about ExternalScript:

get-command -commandtype externalscript | gm

  TypeName: System.Management.Automation.ExternalScriptInfo

Name            MemberType Definition

----            ---------- ----------

Equals          Method     System.Boolean Equals(Object obj)

GetHashCode     Method     System.Int32 GetHashCode()

GetType         Method     System.Type GetType()

get_CommandType Method     System.Management.Automation.CommandTypes get_CommandType()

get_Definition  Method     System.String get_Definition()

get_Name        Method     System.String get_Name()

get_Path        Method     System.String get_Path()

ToString        Method     System.String ToString()

CommandType     Property   System.Management.Automation.CommandTypes CommandType {get;}

Definition      Property   System.String Definition {get;}

Name            Property   System.String Name {get;}

Path            Property   System.String Path {get;}

Cheers,

Aleksandar

April 20, 2007 3:06 PM
 

make money online said:

About Us This community blog has since existed 2 years ago, with the primary focus on HYIP (High Yield Investment Programs) then. Author Jude has a small vision of establishing a community of authors and readers that can form a close niche on passive

March 29, 2008 6:11 PM
 

PowerShell ??? Friend to every MOSS developer « Thoughts on computing, SharePoint and all the rest said:

June 26, 2008 8:19 AM
 

Community Web Directory said:

Press releases have some unique characteristics that can contribute to an increase in search engine positioning for your site. They are similar in many ways to pages that use search engine copywriting techniques. They have a narrow focus, include copy

July 20, 2008 4:31 PM
 

einsurance said:

the three greatest metropolises are good for Paris and London. The three greatest metropolises is so relaxing and friendly. There is also an inviting proposition in each room. Paris and London sometimes like to mention: “ pierre hotel in new york” Today,

September 9, 2008 5:04 PM
 

fx training said:

If you answered Yes to either of these questions, please join us for a webinar on August 26th at 10: 00 AM Pacific Time as we introduce our partnership with OnForce. OnForce is a marketplace for IT professionals to connect with each other through an interactive

September 18, 2008 9:10 AM
 

Forex Demo Account said:

There are many good books and references that are relevant to club investing. Some suggested readings might include Peter Lynch’ s One Up on Wall Street , Beating the Street , and Learn to Earn , Robert G. Hagstrom’ s The Warren Buffet Way , and Graham

September 20, 2008 3:36 AM
 

click here said:

A- Train Approved Arohan’

September 21, 2008 8:13 AM
 

forex software said:

NooshaFox. Com-

September 23, 2008 12:42 PM
 

Forex Broker said:

Currently market is quite flat, waiting for important fundamental data later. Dollar will probably try to regain pips it has lost yesterday. I’ ...

November 14, 2008 11:03 AM
Anonymous comments are disabled