Powershell Training–Beginner

Table of Contents

·        Working with the script editor

·        Powershell File Types

·        Code Comments

·        Variables

o   Assigning data to a variable

o   Running Scripts

o   Running Scripts – continued

o   Assigning data to variables – continued

·        If-Else Statements

·        Looping

·        Getting Help

·        Pipeline

o   Out-GridView, Out-Null

o   ForEach-Object

o   Where-Object

·        VMware Examples

o   Piping vs. Dot-Notation

·        Code Format

Working with the script editor

You can use the out-of-the-box editor (Powershell ISE), or download and install PowerGUI. Both will give you code markup (coloring, auto-suggestions, etc) and the ability to run code within the same window.

Powershell File Types

·        MyScript.ps1 – This is the default Powershell script extension

·        There are other file types, but 99% of the scripts you write will be .ps1 files

Code Comments

You can write comments inside your script a few different ways.

001
002
# Script comments
$MyVariable = “Hello World!”

Use the hash symbol “#” to comment out a line, shown in green above.

001
002
003
004
005
006
007
<#
 
Lots of code comments here.
 
#>

$MyVariable = “Hello World!”

You can also comment out multiple lines using “<#” and “#>”, shown in green above.

Variables

Variables are declared with “$” at the beginning of the variable name and assigned a value with one equals sign “=”:

001
$MyVariable = “Hello World!”

A variable is just a container for data. It can be a string (“Hello World!”), a numeric value (100), or other types of data such as Powershell Objects or arrays.

Assigning data to a variable

·        Assigning string data (enclose the string in quotes): $MyVariable = “Hello World!”

·        Assigning numeric data: $MyVariable = 100

·        Assigning data to an array:

001
002
003
004
005
$MyVariable = @()
$MyVariable += “Value1”
$MyVariable += “Value2”

Write-Host $MyVariable

o   Above, you declare the variable to be an array by assigning a value of “@()”. This converts the variable to an array and allows you to start adding data to the array. You don’t have to do this, but it’s a best practice to declare your variable types before adding data to it. Powershell isn’t as strict as other coding languages, so you don’t have to declare a variable to be a string/decimal/etc before assigning data to it.

o   The second line in the above code is adding a value to the array by using “+=”. You can add data to the array in other ways as well. The last line in the code above will output the contents of the array to the screen.

Running Scripts

·        To run the above script inside a script editor, copy the contents of the code into the code editor (Powershell ISE or PowerGUI) and press F5 or hit the green arrow button

·        To run the above script in a PowerCLI window, save the script as a “ps1” file. Then run this command within the PowerCLI window:

clip_image002

·        Above, the script name is “wip7”. Use “.\” before the name of the script to run the script within the PowerCLI window

·        To run scripts like this, you need to “cd” into the same directory where you saved the script. So above you would need to run “cd H:\Documents\PowerCLI” to change directory first, and then run “.\wip7.ps1”

Running Scripts – continued

Powershell has an extremely useful feature called “Tab Completion”. If you type the partial name of a cmdlet and then press the Tab key, it will try to autocomplete the name of the cmdlet for you.

Assigning data to variables – continued

You can assign variables to other variables:

001
002
$MyVariable = “Hello World!”
$MyVariable2 = $MyVariable

Assigning additional data to variables:

001
002
003
$MyVariable = “Hello World!”
$MyVariable2 = $MyVariable
$MyVariable2 = $MyVariable2 + ” Powershell Knowledge Transfer”

MyVariable2 started out as the string “Hello World!”, and then had another string added to it using the “+” operator.

If-Else Statements

Once you have gathered some data, you will want to run checks on the data to manipulate it.

The basic format of “If” statements are as follows:

If(Condition) {

               Do something if the condition is met

}

Copy this code:

001
002
003
004
005
$MyVariable = 100

If($MyVariable -eq 100) {
      Write-Host “MyVariable equals 100.”
}

Above, we assign the numeric value “100” to MyVariable, and then run an “If” check to test the data we assigned. The “-eq” statement is checking if something is –equal or not. A full list of comparison operators is here.

 

“If” statements can be chained together like this:

If(Condition) {

               Do something if this condition is met

}

ElseIf(Condition) {

               Do something if this condition is met

}

Else {

               Do something if none of the other conditions are met

}

An example of this is below:

001
002
003
004
005
006
007
008
009
010
011
012
013
$MyVariable = 200

If($MyVariable -eq 100) {
      Write-Host “MyVariable equals 100.”
}

ElseIf($MyVariable -eq 200) {
      Write-Host “MyVariable equals 200.”
}

Else {
      Write-Host “MyVariable equals “ $MyVariable
}

Looping

There are lots of ways to loop through data. Let’s build on the previous array example:

001
002
003
004
005
006
007
$MyVariable = @()
$MyVariable += “Value1”
$MyVariable += “Value2”

ForEach($obj in $MyVariable) {
      Write-Host $obj
}

Above, we created the array and assigned data to it. Then we used a “ForEach” loop to step through each piece of data within the array, and then output the result every step of the way. “$obj” is a variable that we created to store the contents of each element in the array. The value of “$obj” will change after each time it loops – “$obj” will have “Value1” stored within it on the first loop, then “Value2” on the second loop.

Let’s combine a loop with an “If-Else” chain:

001
002
003
004
005
006
007
008
009
010
011
012
013
$MyVariable = @()
$MyVariable += “Value1”
$MyVariable += “Value2”

ForEach($obj in $MyVariable) {
      If($MyVariable -eq “Value1”) {
            Write-Host “MyVariable element equals Value1”
      }

      ElseIf($MyVariable -eq “Value2”) {
            Write-Host “MyVariable element equals Value2”
      }
}

This will loop through every element in the “$MyVariable” array, and run checks on the data stored within “$obj”. Notice that we don’t need an “Else” statement – this is optional.

Getting Help

Scripts (aka “cmdlets”) will most likely have built-in help that you can use. Run this command to get help on the “Write-Host” cmdlet:

001
Get-Help Write-Host –Full

Pipeline

The pipeline is comparable to water pipes that run through a home. Each water pipe is separate from each other, but they are also linked together to form a chain. The water flowing through the pipeline is the data that you send through it. A brief explanation of the pipeline is here.

There are a variety of ways to manipulate data in the pipeline:

1.      Out-Gridview , Out-Null

2.      ForEach-Object

3.      Where-Object

Out-GridView, Out-Null

Out-GridView will redirect the output from your command to a new window that has sortable columns. You can copy and paste from the Out-GridView window.

001
Get-Process -Name “explorer” | Out-GridView

Out-Null is sort of like a “catch all” cmdlet that will suppress the output from the command you run. The unsuppressed command looks like this:

clip_image004

With suppression:

clip_image006

ForEach-Object

A great explanation of ForEach-Object is here.

Where-Object

“Where-Object” is a way to filter out data in the pipeline. Take the original code example above:

001
Get-Process -Name “explorer” | Out-GridView

Instead of writing the code like that, you could use “Where-Object” to filter out the data instead (this isn’t efficient, but useful for our learning purposes):

001
Get-Process | Where-Object {$_.Name -eq “explorer”} | Out-GridView

“Where-Object” takes data that is sent to it from another cmdlet (shown as “Get-Process” above) and then filters out the data based on the checks you run against it. Above, the check to run follows this format:

Cmdlet | Where-Object {$_.ObjectName –ComparisonOperator ConditionToMatchOn}

The “$_” section of code is the current object in the pipeline to run checks against. In the example above, we are checking the “Name” property to see if it equals the name “explorer”. If you didn’t know the name of the property you want to match on, you would start out by examining the “Get-Process” object (remember, it’s just a big box full of data that you can explore):

001
Get-Process | Get-Member

clip_image007

So we see above that the “Get-Process” object has a smaller object named “ProcessName” which we can use to filter out data with “Where-Object”.

It’s important to note that the pipeline works by sending one object at a time to the next cmdlet in the chain:

001
Get-Process | Where-Object {$_.Name -eq “explorer”} | Out-GridView

Above, the first object that “Get-Process” retrieves would be sent to “Where-Object”:

clip_image008

Above, the “ApMsgFwd” object would be sent through the pipeline first, and then “AptEx”, etc. Each “ProcessName” is an object, which is why you reference the objects with “$_.Name”. The “$_.” section in the preceding code basically means to take the current object in the pipeline, and reference the “Name” property within the object (“$_.Name”). Another way to visualize this in action is to view it like this (this is an abstract example):

001
Get-Process | Where-Object {CurrentPipelineObject.Name -eq “explorer”} | Out-GridView

VMware Examples

VMware created a series of scripts and packaged it into a snap-in. To load the snap-in within a script, use this code:

001
Add-PSSnapin VMware.VimAutomation.Core

PowerCLI sits “on top” of Powershell. PowerCLI is a customized Powershell window that automatically loads the above snap-in.

To connect to a vCenter server and begin running commands, use this code:

001
Connect-VIServer “vCenterServerName”

Some initial cmdlets to get familiar with that VMware created:

001
002
003
004
Get-VM
Get-VMHost
Get-Cluster
Get-Datacenter

Each of these can accept different parameters. For example:

001
Get-VM -Name “lappmab00035009”

Everything in Powershell is an object. Think of an object as a box. This box can contain other boxes (other objects), and it can also have tools (object methods) within the box to manipulate data. To open up the box and view its data, you can use the “Get-Member” cmdlet:

001
Get-VM -Name “lappmab00035009” | Get-Member

The output from this command will display everything within the object you retrieved:

clip_image010

Above, there are some tools you can work with (Methods), and also “Properties”. Properties are just collections of data – other, smaller boxes within the larger box.

First, we retrieve the data with “Get-VM”. Then we use the pipe command “|” to send the larger object into the pipeline. Once the object is in the pipeline, we can manipulate and filter the data. We decided to use the “Select-Object” cmdlet to pick out only one smaller object to view:

001
Get-VM -Name “lappmab00035009” | Select-Object Name

clip_image012

So above, there is a single column “Name” that contains the “lappmab00035009” piece of data. This result is still an object – let’s view the contents of this smaller object:

001
Get-VM -Name “lappmab00035009” | Select-Object Name | Get-Member

clip_image013

There is much less going on inside this object. Notice the “NoteProperty” section of the “MemberType” column. Within this object there is a piece of data we can retrieve:

001
Get-VM -Name “lappmab00035009” | Select-Object -ExpandProperty Name

clip_image014

Above, we are using the “Select-Object” parameter “-ExpandProperty” to pull out the “Name” property within the object.

So let’s tie it all together with a script:

001
002
003
004
005
006
007
008
009
010
011
012
013
Add-PSSnapin VMware.VimAutomation.Core

Connect-VIServer “wmgtmab00001012”
$VM1 = Get-VM -Name “lappmab00035009”
$VM2 = Get-VM -Name “lappmab00035010”

$MyVariable = @()
$MyVariable += $VM1
$MyVariable += $VM2

ForEach($obj in $MyVariable) {
      Write-Host $obj | Select-Object -ExpandProperty Name
}

The script does the following:

1.      Adds the VMware snap-in (not necessary if you run the script from a PowerCLI window)

2.      Connects to the vCenter server

3.      Retrieves two “Get-VM” objects and stores the objects into the $VM1 and $VM2 variables

4.      Creates an array $MyVariable

5.      Assigns the $VM1 and $VM2 objects as elements of the array (elements are like individual cells of data within Excel)

6.      Loops through the array and outputs the “Name” property within each object stored in the array

 

Piping vs. Dot-Notation

Instead of using the “|” (pipe) operator, you can use dot-notation to reference values within an object. Dot-notation looks like this:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
Add-PSSnapin VMware.VimAutomation.Core

Connect-VIServer “wmgtmab00001012”

$VM1 = Get-VM -Name “lappmab00035009”
$VM2 = Get-VM -Name “lappmab00035010”

$MyVariable = @()
$MyVariable += $VM1
$MyVariable += $VM2

ForEach($obj in $MyVariable) {
      Write-Host $obj.Name
}

Above, we referenced the “Name” Property using dot-notation. Compare this code with what was shown in the original example.

Code Format

It is a best practice to indent your code and use code comments. See below.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
<#
Below is a block of code that performs some function.
The script comments are above the block of code to increase
readability without breaking up the “flow” of the code.
#>

ForEach($obj in $MyCollection) {

    If($Something -eq $SomethingElse) {

        Write-Host “Properly indented code is wonderful!”

  } # End “If($Something -eq $SomethingElse)”

} # End “ForEach($obj in $MyCollection)”

  1. Leave a comment

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 )

Connecting to %s

%d bloggers like this: