Monday, January 31, 2011

Technical difficulties

I'm currently experiencing technical difficulties. I'll be back next week with a new post.

Friday, January 7, 2011

Pipelines, String Methods, Read-Host, and Aliases - A Brief primer

Last week I showed some of the most basic PowerShell cmdlets. And I was shown something that takes me nicely into this week. In the example I was given, there was use of string manipulation, pipelines, and aliases.

Pipelines

PowerShell is designed to allow one cmdlet to be piped into another, passing the results of one cmdlet to the next one. So in the example, the ForEach-Object cmdlet received an array of characters from the result of the string method invoked. Then within the loop construct, each element is returned individually using the $_ variable which refers to the current object being processed. The exact inner workings of this is something I'm still understanding


String Manipulation

The example shows another topic I wanted to cover, string manipulation. Using a string method, a string was converted into a character array, same outcome of what I did without as much typing. Less typing is less room for error. You could easily write a complicated script that finds every letter O in a string and replace it with a 0, or you could just use the .Replace() method. Here's an example

(“Hello world”).ToCharArray() | ForEach
{
if ($_ -eq “o”)
{
$_ = “0”
}
Write-Host $_ -nonewline
}

This will result in the exact same result as with this example:

(“Hello world”).Replace('o','0')

As Jeff pointed out, you can pipe a string into the Get-Member cmdlet. This will return all the properties on any given object. So we can assign a value to a string and pipeline it to the Get-Member cmdlet. For example:

$foo = “Hello world”
$foo | Get-Member

You get this:

Get-Member (Click to enlarge)
Anything with a MemberType of Method can be used to manipulate the value of the string. Some Methods require parameters in order to execute properly, other do not. For example:

Write- Host $foo.ToUpper()

Will display the value of the object $foo in all capital letters. However, if you try this:

Write-Host $foo.Substring()

You will get an error

Method Error (Click to enlarge)
Looking at the Get-Member again for the object $foo, listed under Definition you can see what parameters are required for each Method. Some end in just (), not requiring a parameter. However, .Substring() is listed as Substring(int startIndex), string Substring(int startIndex, int length). This shows that at the minimum, the .Substring() method requires at least one number, and at most two. So, for example:

Write-Host $foo.Substring(6,5)

Returning just the second half of the phrase. This has all sorts of useful implications. First, it wouldn't do anyone good to have a script fail because the user entered “YES”, and it was only checking for the value of “yes”, or even just “y”. By using different Methods you can get it down to just what you want and still maintain versatility for the user.

Methods exist for all types of objects, but strings have to be the most common use for methods.

When it comes to strings, chances are you will typical used, hard coded string values as above. While there are reasons for doing so, you can simply do like Jeff did and work with a constant string like (“Hello World”). Still an object, but only one that PowerShell keeps around long enough to use it than forgets all about it. The true power of strings comes in the for of user interaction. Which brings us to Read-Host.

Read-Host

Read-Host allows the script to take direct input for the user. This allows the user to input the value of an object each time the script is executed. Scripting normally all about automation, and you typically get your input from elsewhere, but in some cases, it's best to let the user decide what the value is. In this example, I'll get the value of an object when the script is run and process it within the script.

$firstName = Read-Host “What's you first Name”
$lastName = Read-Host “What's you last name”
$fullName = $firstName + “ “ + $lastName
Write-Host “Your full name is $fullName”

There is just something satisfying about making a computer greet the world then say your name. The most common use for user interface is to get the name of an object you want to use in an up coming cmdlet. I'll show examples of that when I cover other cmdlets.

Alias

An Alias is a like a nickname for a cmdlet. The example from last week showed an example of an alias, with the ForEach alias for the ForEach-Object cmdlet. Another alias for ForEach-Object is %. For a list of useable aliases you can use, just type Get-Alias into the console.
Get-Alias (Click to enlarge)
So, to change directories, sl will do the same thing as Set-Location.
Set-Location (Click to enlarge)
Next Week
Next week I'm going to start the with the scripting challanges from the 2010 Scripting Games and complete with the first one and do one a week, writing scripts in PowerShell to do so. I'll post my scripts here with the best write up I can to help understand what each script is doing. That gives me something to do over then next ten weeks, and I hear it's a great way to learn. Here's the link: 2010 Scripting Games - All Links on One Page. The first challenge is to search the local registry and check for an entry, and either add it or update it. New stuff for me. Until then...

Thursday, December 30, 2010

Hello World!

Hello World! The famous first words that fledging programmers get to watch appear on the screen as they write the first bit of code. My first Hello World program in QBASIC over 15 years ago. After an unsuccessful attempt to learn C in many of it variants, I have moved to Windows scripting as my preferred choice in Windows programming. I guess you can so: "For those that can't code, script". I have been learning VBScript for the past year until I came across this new wonderful language called PowerShell. PowerShell allows you to do everything VBScript does and more. Like access to Windows .Net framework and such. Now, I have no .Net experience, it's almost Latin to me, but as I continue on this journey of learning to write PowerShell scripts, maybe I'll figure it out. Most everything I know is self taught, pulled from existing scripts I have access to. Dissecting them to find out how they work. And PowerShell is a great language for dissecting code. Which brings us to our first topic today: Get-Help

Get-Help
Whenever you come across a command, called cmdlet, in PowerShell you don't understand, you can always use the Get-Help cmdlet.

Get-Help Example (Click for larger image)
 Which brings us to our next command: Write-Host

Write-Host
Write-Host does exactly that, it writes customized output to the host, aka the console windows. It can't be used, to the best of my knowledge, for anything else. For example, it wont pipe into an Out-File cmdlet, but more on Out-File and piping later, for now, let's write our first bit of code:

Write-Host "Hello World"
Hello World!
Pretty simple right? But what if you didn't want to type this <sarcasm>long</sarcasm> command every single time? Open your favorite text editor, or my personal favorite the PowerShell ISE and put this command in it and save it as a .ps1 file. In this example HelloWorld.ps1. Now you can run it from the PowerShell console just like this.

.\HelloWorld.ps1
HelloWorld.ps1
But wait, that's not all! No true code is complete without some kind of loop in it. PowerShell supports a myriad of loop constructs. The first one I will cover is the ForEach loop.

ForEach
ForEach is a loop construct that allows you to move through an object, such as an array, assigning each element to a variable to be worked with. Let's make our little script from before slightly more complicated.

$HelloWorld = "H","e","l","l","o"," ","W","o","r","l","d","!"
ForEach ($letter in $HelloWorld)
{
    Write-Host $letter
-nonewline

}
Write-Host

Let us examine each line here. The first line establishes an array called $HelloWorld. There are a couple of different ways to establish an array, but I will use this one for now. It's the next line we want to focus on, ForEach. This is the beginning of the loop construct and, in my opinion, one of the easiest to master. What happens here is: The script loops through the $HelloWorld array and assigns each element to the variable $letter. Then using our friend Write-Host with the switch -nonewline, which prevents carriage returns between the letters, we display our message. The last Write-Host after the loop gives us a new line after the message is written.

A quick note about how PowerShell works. You can take the above code, and save it as a .ps1 file, nothing wrong with that, but PowerShell has the ability to do a line by line execution straight from the console window. Now, to me, that's amazing. Just look at the above code in this example:
Line by Line Execution (Click for a larger image)
Another thing to remember about PowerShell is, it is not case sensitive. Write-Host, write-host, wRITE-hOST, and any other combinations of capitalization that you can think of, all do the same thing. I will do my best to stay uniform with capitalization to ensure readability.

In conclusion, I haven't even begun to scratch the surface of what is possible with PowerShell. The is pretty much no way anything I have put down today could be of practical use, but this is just the start. Once I get this up to speed with what I know, I'll begin to add other elements as I learn them

Coming Next
Next week, I will try to cover: Read-Host, String Manipulation, Aliases, and Piping. All very useful, and a great next step for the beginner. Until then...