• No results found

Windows PowerShell: A First L k. Charlotte McGary

N/A
N/A
Protected

Academic year: 2021

Share "Windows PowerShell: A First L k. Charlotte McGary"

Copied!
35
0
0

Loading.... (view fulltext now)

Full text

(1)

Windows PowerShell:

A First L

k

(2)

Copyright © 2007 Charlotte McGary. All Rights Reserved.

No portion of this book may be reproduced by any means whatsoever without the expressed written permission of the author.

(3)

Table of Contents

GETTING STARTED ... 5

Setting the Default Directory ... 5

WORKING WITH FILES AND DIRECTORIES ... 7

Get-ChildItem (View Directory Information) ... 7

New-Item (Create a Directory or File)... 7

Copy-Item (Copy a Directory or File) ... 8

Move-Item (Move a Directory or File) ... 9

Rename-Item (Rename a Directory or File) ... 9

Remove-Item (Delete a Directory or File) ... 9

VARIABLES IN POWERSHELL ... 10

The PowerShell Version of the Batch File Environment Variable ... 10

The PowerShell Version of the Batch File Command-Line Argument ... 10

LOOPS ... 12 FOREACH LOOP ... 12 FOR LOOP ... 13 WHILE LOOP ... 14 DO WHILE LOOP ... 14 DO UNTIL LOOP ... 15

STRING SEARCHES AND PIPING ... 16

Write-Host versus Write-Output ... 17

GETTING INPUT ... 21 User Inputs ... 21 File Inputs ... 21 CONDITIONAL STATEMENTS ... 23 Comparison Operators ... 23 If/ElseIf/Else…. ... 24 CASTING—STRINGS VS. NUMBERS ... 26 ARRAYS ... 29 Defining Arrays ... 29 Combining Arrays ... 30 COMMAND REFERENCE ... 31 PRACTICE ... 32 PowerShell Lab #1 ... 32 PowerShell Lab #2 ... 33 PowerShell Lab #3 ... 34 PowerShell Lab #4 ... 35

(4)
(5)

Windows PowerShell: A First Look

This tutorial provides a step-by-step introduction to Windows PowerShell. After completing the tutorial, you should be comfortable with the PowerShell window and with creating and running simple scripts.

GETTING STARTED

1. Create folder C:\PowerShell\MyScripts. 2. Create a shortcut to PowerShell on Desktop.

3. Double-click on PowerShell shortcut to open PowerShell. (Note the folder in the command window that PowerShell opens in.)

4. Change to the C:\PowerShell\MyScripts directory by typing set-location C:\PowerShell\MyScripts

5. Create Hello1.ps1 by typing notepad Hello1.ps1 then enter the following text in the Notepad window:

# file: Hello1.ps1 The # symbol makes any line a comment write-host 'Hello world!'

# end script

6. Try to execute Hello1.ps1 by typing .\Hello1.ps1 in the PowerShell (PS) command window.

7. If it doesn't execute, type Get-ExecutionPolicy.

8. If the command returns "restricted" then reset the execution policy by typing

set-executionpolicy remotesigned or set-executingpolicy unrestricted

9. Now try running the program again. 10. Exit PowerShell.

Setting the Default Directory

By default PowerShell opens in your home directory. Now we're going to change that default directory to the MyScripts directory you created earlier so that you don't have to set your location to that directory each time you open PowerShell.

1. Right-click on the PowerShell shortcut on your desktop.

2. Change the %HOMEDRIVE%%HOMEPATH% in the Start in: window to

C:\PowerShell\MyScripts as shown in the screen shot to the right.

3. Click OK then re-open PowerShell. Notice that you now are in your MyScripts directory.

(6)

4. Type Get-ChildItem and you should see your Hello1.ps1 file. 5. Type Copy-Item –whatIf Hello1.ps1 Hello2.ps1. 6. Now do the actual copy by typing

Copy-Item Hello1.ps1 Hello2.ps1

7. Type Get-ChildItem and you should see both .ps1 files now. 8. Type notepad Hello2.ps1 and edit the file so it has the following text:

# file: Hello2.ps1

write-host # outputs a blank line to the screen

# Note that single quotes around text or # double quotes around text is okay when # displaying simple text.

write-host 'Hello World!' write-host "Have a nice day!" # end script

9. After saving the changes, run Hello2.ps1 by typing .\Hello2.ps1 at the PS command line.

10. Now copy Hello2.ps1 to Hello3.ps1 and edit Hello3.ps1 to read as follows then run the script.

# file: Hello3.ps1 write-host

write-host 'Hello World!' write-host 'from Charlotte' write-host "Have a nice day!`n"

# `n above produces a new line like the first # write-host command in this file

(7)

WORKING WITH FILES AND DIRECTORIES

Like Linus and DOS/Windows file and directory manipulation, PowerShell has its own set of cmdlets for getting around. This section touches on some of the indispensable cmdlets you'll want at your disposal.

Get-ChildItem (View Directory Information)

As you saw in the previous section, the Get-ChildItem cmdlet displays the contents of the current directory. Just type the cmdlet to get a listing of the current directory or add the path to view information for a different directory. For example, to see a directory listing of the folder "SubFolder" (a sub folder of MyScripts), type the following:

get-childitem .\SubFolder

New-Item (Create a Directory or File)

To create a new directory, use the New-Item cmdlet. This cmdlet can also create a file, so you'll want to differentiate between the two using the –type parameter. For example, to create a subfolder called "MyNewFolder" in the current directory, type the following code: new-item . –name MyNewFolder –type directory

The resulting screen output should look like this:

Now create two more directories—one a subdirectory of MyNewFolder, and the other a subdirectory of MyScripts:

new-item –path .\MyNewFolder –name SubFolder –type directory new-item . –name Test –type directory

To create a new empty file, use the New-Item cmdlet. As previously mentioned, this cmdlet is also used to create directories. Use the –type parameter to define what you are creating. For example, to create an empty file called "MyNewFile" in the subdirectory created in the section on "Working With Directories," type the following code (it is assumed you are still in your MyScripts directory):

(8)

Note that the use of quotes around the values "MyNewFile" and "File" are optional, but it's always a good idea to put them in, as in many cases they are required (see the example after this one).

The resulting screen output after creating MyNewFile should look like this:

The 0 length indicates the file is empty.

If you want to add some text to a file at the time you created it, you can do that by adding the –value parameter. For example, to create a file called File2.txt with the content "This is Charlotte's file." in the same directory as MyNewFile, type the following line of code:

new-item –path .\MyNewFolder –name File2.txt –type file –value "This is Charlotte's file"

The resulting screen output should look like this:

Copy-Item (Copy a Directory or File)

To copy the complete contents of one directory to another, use the Copy-Item cmdlet shown in the following example The –recurse parameter copies all subdirectories also. If the destination directory does not already exist, the command will create it.

copy-item .\MyNewFolder –destination .\Backup -recurse

Note that no output will be generated unless there is an error. You can use the Get-ChildItem cmdlet to confirm that the copy was successful.

To copy one or more files from one location to another, use the Copy-Item cmdlet shown in the following example. To copy all .txt files from your .\Backup directory to

.\MyNewFolder\SubFolder, enter the following code. (The original files will not be deleted.) copy-item .\Backup\*.txt –destination .\MyNewFolder\SubFolder

(9)

After using the Get-ChildItem cmdlet to view the contents of the Backup folder, you should see output similar to this:

Move-Item (Move a Directory or File)

To move a file or directory from one location to another, use the Move-Item cmdlet shown in the following example. It works just like Copy-Item except the file or directory no longer exists in its original location after the move. If you had wanted to move rather than copy all .txt files in the previous example, you would have typed the following code instead: move-item –path .\Backup\*.txt –destination .\Test

Rename-Item (Rename a Directory or File)

To rename a file or directory, simple use the Rename-Item cmdlet shown in the following example. If the item to be renamed is in a location outside of the current directory, you must preface the name with the path.

rename-item oldname newname

Now change to your .\Test directory and rename File2.txt to test.txt.

Remove-Item (Delete a Directory or File)

To move a file or directory from one location to another, use the Remove-Item cmdlet.

To remove an entire directory, whether or not it is empty, use the –recurse parameter. For example, if you wanted to delete the sub folder of MyScripts called Test, you'd type

remove-item .\Test -recurse

Suppose you want to remove all files from a directory named SubFolder that have an extension, i.e. have a "." in the file name. To do that you would type:

remove-item .\MyNewFolder\*.*

(10)

VARIABLES IN POWERSHELL

Up to this point, you have "hard-coded" all your text. Now we'll explore the use of variables in PowerShell. Suppose, instead of the line of code above that writes "from yourname" to the screen, you want to store your name in a variable. The following example shows you how to accomplish this.

The PowerShell Version of the Batch File Environment Variable

Copy the file Hello3.ps1 to Hello4.ps1 and edit Hello4.ps1 to read as follows then run the script.

# file: Hello4.ps1

# Assigning the string "Charlotte" to the variable called # $name is like setting an environment variable in a Windows # Batch File.

$name = "Charlotte" write-host

write-host "Hello World!" write-host "from" $name

write-host "Have a nice day!`n" # end script

The PowerShell Version of the Batch File Command-Line Argument

Now suppose you want to be able to change "Charlotte" in the above example to any name. The way your script is currently set up, you'd have to edit it each time you want to change the name. A better way is to send the name through to the script at the time you execute it at the PowerShell command line. (Sound familiar? i.e., the Command Line

Argument/Pass-Through Parameter in Windows Batch Files.)

Copy the file Hello4.ps1 to Hello5.ps1 and delete all the text. Enter the following code into Hello5.ps1 then run the script by typing in

.\Hello5.ps1 "Capt. Kirk" "Mr. Spock" "Dr. McCoy"

# file: Hello5.ps1

# To pass a value through at the command line type # the value after the script name.

# For example: .\Hello5.ps1 "Capt. Kirk" "Mr. Spock" "Dr. McCoy" # will send the above three strings through to the script as the # first argument. (Arrays start their numbering at zero, so an array # with 5 elements will number those elements 0-4.)

# In the line of code below, the variable named $name is assigned # the value of the first argument passed through at the command # line ($args[0]). Note that $args is a special object which stores # command-line input.

$name1 = $args[0] # First argument

$name2 = $args[1] # Second argument

$name3 = $args[2] # Third argument

write-host

write-host "Hello World!"

write-host "from" $name1"," $name2", and" $name3 write-host `n$name1 "says have a nice day!`n" write-host $name2 "says have a nice day!`n"

(11)

write-host $name3 "says have a nice day!`n"

write-host "Actually" $name2 "says live long and prosper.`n" # end script

(12)

LOOPS

Up till now, we've executed one line at time systematically to display the output we wanted. That is, in the example from Hello5.ps1, we had to type a write-host line three times to have each of our input names say "have a nice day!"

FOREACH LOOP

We can reduce those three lines to single line using a foreach loop. To see an example, copy Hello5.ps1 to Hello6.ps1, delete all but the first and last comments, and edit Hello6.ps1 to read as follows. Run the script by typing in

.\Hello6.ps1 "Capt. Kirk" "Mr. Spock" "Dr. McCoy" # file: Hello6.ps1

write-host

write-host "Hello World!" foreach ($name in $args) {

write-host $name "says have a nice day!`n" }

# end script

Your output should look like this:

So exactly is that foreach statement doing? If you remember FOR statements from Windows Batch Files, the foreach is acting in a similar fashion. In the above example,

foreach ($name in $args) {

write-host $name "says have a nice day!`n" }

temporarily defines the variable $name to each value of $args one at a time, then does whatever you tell it to do within the curly braces{}. In this example, there are three values stored in the array $args (args[0], args[1], and args[2]), so $name first takes on the value stored in $args[0], then displays the contents of $name followed by the text "says have a nice day!" Next $name takes on the value stored in $args[1], displays the contents of $name followed by the text "says have a nice day!" and so on until it runs through all the arguments that were passed through at the command line.

(13)

FOR LOOP

Another type of loop is called a For Loop, which executes until the specified condition is true. You initialize the counter, set the limit, and define the increment value, all in one statement.

for (initialization; limit; increment) {

# Do stuff here }

The following example initializes a variable called $i, displays the value of $i as long as the value of $i is less than 5.

Create the file ForLoop.ps1 in your MyScripts directory and add the following code:

# File: ForLoop.ps1

for ($i = 0; $i –lt 5; $i++) {

write-host $i }

# end script

Execute the script by typing .\ForLoop.ps1.

Your output should look like this:

Now create the file called ForLoopArray.ps1 and enter the following code. You will need to pass in six command line arguments to the script, which will display every other one. (Note that the write-host line and the one following it should all be typed on a single line.)

# File: ForLoopArrays.ps1 for ($i = 0; $i -lt 5; $i+=2) {

$passOrder = $i + 1

write-host Command line argument number $passOrder = args[$i] = $args[$i]

}

# end script

Execute the script by typing in .\ForLoopArrays.ps1 1 2 3 4 5 6.

(14)

WHILE LOOP

Another type of loop is called a While Loop, which executes only as long as the condition specified within the parentheses is true. In the following example, we initialize a counter then set up a while loop to continue executing as long as the counter is less than or equal to five. Each time we go through the loop, we increment the counter by one.

Create a file called WhileLoop.ps1 in your MyScripts directory. Enter the following code into the file:

# File: WhileLoop.ps1 $counter = 0

while ($counter -le 5) {

write-host $counter

$counter++ # Increment counter by one

}

# end script

Your output should look like this:

DO WHILE LOOP

The Do While loop works just like the While loop except that the Do While loop will always execute at least once.

To change the above example to a Do While loop, modify the code as follows. By starting the counter at 6, if this were a While loop, the loop would never execute. In this example, however, the Do causes it to execute at least once, then checks to see if the While condition is true or false.

Create the file DoWhileLoop.ps1 in your MyScripts directory and modify the code as shown below:

(15)

# File: DoWhileLoop.ps1 $counter = 6 do { write-host $counter $counter++

} while ($counter -le 5) # end script

Your output will display the value of $counter as 6 then jump out of the loop.

DO UNTIL LOOP

Just like the Do While loop, the Do Until loop will execute at least once. Then it continues executing until the condition is true (unlike the While and Do While loops which execute

while a condition is true). Another way to put it is a Do Until loop continues executing as

long as the condition is false.

To change the previous While loop to a Do Until loop, create the file DoUntilLoop.ps1 in your MyScripts directory and enter the following code:

# File: DoUntilLoop.ps1 $counter = 0 Do { write-host $counter $counter++

} until ($counter -eq 6) # end script

Your output should look like this:

Now it's time to get a little more hands-on experience with PowerShell scripting. Go to the Practice section at the end of this document and write the script described in Lab #1.

(16)

STRING SEARCHES AND PIPING

Searching for strings within text files can be a bit tricky in PowerShell as there is no simple FIND command like there is in DOS/Windows. On the other hand, once you create a script to find a string, there is a multitude of ways you can sort, group, and display the results.

Let's start by creating a simple script called "FindText1.ps1" in your MyScripts directory. Enter the following code into the file:

# file: FindText1.ps1 # Variable Name Stores

# $target string to search for # $files all text files

# $matches all files in $files with target string $target $target = "orange"

write-host "`nSearching for 'orange' in current dir and all subdirectories" # The search for matches can be broken down into two steps as

# shown below, or in one step as follows:

# $matches = get-childitem . -include *.txt -recurse ¦ select-string $target $files = get-childitem . -include *.txt -recurse

$matches = $files ¦ select-string $target

# $null is a special variable representing the null (nothing) character if ($matches -eq $null)

{

write-host 'No matches found' }

write-host $matches # end script

Before you run this script you will need to create three text files in MyScripts: fruits.txt, trees.txt and colors.txt in your MyScripts directory. Then make a subdirectory of MyScripts called SubFolder (C:\PowerShell\MyScripts\SubFolder) and create desserts.txt in that folder.

Contents of fruits.txt: Contents of trees.txt: Contents of colors.txt: Contents of desserts.txt oranges blueberries mangos cherries apples apple orange cherry oak walnut purple green orange red blue apple crisp blueberry pie cherry pie pecan pie orange sherbert

Let's examine some particularly interesting lines of code from the above script.

$files = get-childitem . -include *.txt -recurse

The above line executes a directory listing (get-childitem) of the current directory (.), including in the listing only those files with the extension *.txt (-include *.txt) and also looks for those files in all subdirectories (-recurse). It stores the file names found in the variable $files.

(17)

$matches = $files ¦ select-string $target

The above line searches all files whose names are stored in $files for the string stored in the variable named $target (select-string $target). The ¦ symbol is a "pipe" through which the data in $files is input to the select-string cmdlet.

if ($matches -eq $null)

The above line checks to see whether or not any matches were found. If not, the value stored in $matches will be the null character, which is stored in a special variable called $null. So the line can be read as "if the value stored in $matches equals the null character)." The

operator for "equals" is -eq. An IF statement must always be followed by some action within curly braces { }.

Now run the script by typing .\FindText1.ps1 at the PS command line.

Your output should look similar to this:

Not very readable is it?

Let's change the code slightly by substituting the line write-host $matches with

write-output $matches in your file FindText1.ps1. Your output should look like this:

Write-Host versus Write-Output

The write-host cmdlet sends objects to the command line (Out-Host), which, by default, displays objects on the screen (host window) with no formatting applied. It also allows for customization of the window (i.e., text and background colors with –foregroundcolor and – backgroundcolor, respectively). Objects displayed with write-host cannot be piped to other cmdlets.

Although the write-output cmdlet does not allow customization of the host window, it's more versatile than write-host. The write-output cmdlet writes objects to a "pipeline",

(18)

sending them to a default formatter and to the default output cmdlet (Out-Default). (It is this default formatter which accounts for the difference in how the output is displayed in the above two screen shots.) From the pipeline, an object is available to be piped to other cmdlets which can then perform additional operations on the object, e.g., writing it to a file.

Let's created a second script that uses both write-host and write-output. We'll also pipe the object from a write-output cmdlet to the sort-object cmdlet to list files in alphabetical order.

Copy the file FindText1.ps1 to FindText1a.ps1 then edit FindText1a.ps1 to read as follows:

# file: FindText1a.ps1 # Variable Name Stores

# $target string to search for # $files all text files

# $matches all files in $files with target string # $result matches sorted in alphabetical order $target = "orange"

write-host "`nSearching for $target in current dir and all subdirectories" # The search for matches can be broken down into two steps as shown below, # or in one step as follows:

# $matches = get-childitem . -include *.txt -recurse ¦ select-string $target $files = get-childitem . -include *.txt -recurse

$matches = $files ¦ select-string $target

# null is a special variable representing the null character if ($matches -eq $null)

{

write-host 'No matches found' }

write-host

write-host "*** COMPARISON OF write-host AND write-output ***" write-host

write-host "Matches displayed using write-host:`n"

write-host $matches –foregroundcolor blue –backgroundcolor white write-host

write-host "Matches displayed using write-output:`n" write-output $matches

write-host

write-host "*** END COMPARISON ***`n`n"

write-host "Results sorted alphabetically..." $result = $matches

write-output $result ¦ sort-object # end script

Run the script by typing .\FindText1a.ps1 in the PS window.

Notice the line displaying $matches has a different text and background color than the rest of the window. This is the result of adding the parameters and values

–foregroundcolor blue –backgroundcolor white For more information about changing output colors, type

(19)

Your output should look like this:

Right now we are constrained to search only for the string "orange" in our script. Let's give the script more functionality by changing it to accept the search string from the command line.

Copy FindText1.ps1 to FindText1b.ps1 and edit FindText1b.ps1 to read as follows:

# file: FindText1b.ps1 # Variable Name Stores

# $args command line input (an array) # $target string to search for

# $files all text files

# $matches all files in $files with target string #

# Enter search string at command line by typing # .\FindText1b.ps1 string

# where string is apple, orange, or whatever string you're searching for. # You must use quotes around the string if it contains spaces.

# Define the target string as whatever is passed through at the command line $target = $args[0]

write-host "`nSearching for" $target "in current dir and all subdirectories"

# The search for matches can be broken down into two steps as shown below, # or in one step as follows:

# $matches = get-childitem . -include *.txt -recurse ¦ select-string $target $files = get-childitem . -include *.txt -recurse

$matches = $files ¦ select-string $target

# null is a special variable representing the null character if ($matches -eq $null)

{

write-host 'No matches found' }

# The group cmdlet below groups the files by the filename property # (i.e., it will show how many matches were in each file name without # displaying the found text itself)

write-output $matches ¦ group -property filename # end script

(20)

Run the script by typing .\FindText1b.ps1 orange at the PS command line.

Your output should look like this:

Notice that the data held in the variable $matches was piped to the group cmdlet and

displayed by filename property (-property filename); i.e., only file names are displayed with the number of occurrences of the search string found in each.

Replace "orange" with "blue" at the command line and you should see this result:

(21)

GETTING INPUT

User Inputs

Until now, the only way a user could send data to any of our scripts was through the command line at the time the script was executed. But what if you want to ask the user to input additional data while the script is running? For that you need to use the Read-Host

cmdlet.

Create the file WhatIsYourName.ps1 in your MyScripts directory. Input the following code:

# File: WhatIsYourName.ps1

$firstName = read-host –prompt "Enter your first name" $lastName = read-host –prompt "Enter your last name" write-host

write-host "Your name is" $firstName $lastName write-host

# end script

When you run the script, your output should look similar to this:

File Inputs

Another way to get data after a script has begun executing is by reading that data from a file. Suppose you have a file called listing.txt that contains the names of all text files in a directory (you will create that list in the next example). You want read in the names of those files from the list and display the contents of each file in the PS command window. With the use of redirection (>) and Get-Contents, this is a fairly simple process.

Create a file called ReadFiles.ps1 in your MyScripts directory and enter the following lines of code:

# File: ReadFile.ps1

# List only the names of .txt files in the current # directory and redirect the output to a file # called listing.txt

#

get-childitem -name *.txt > listing.txt

# Retrieve the contents of the file listing.txt and # store in the variable $fileNames

(22)

#

$fileNames = get-content listing.txt

# Read the name of each file from listing.txt and # display its contents on in the PS command window. #

foreach ($file in $fileNames) {

write-host

write-host $file -foregroundcolor yellow get-content $file

}

write-host # end script

Examine the code get-childitem -name *.txt > listing.txt. You're already familiar with the Get-ChildItem cmdlet; get-childitem *.txt by itself would produce a directory listing of all .txt files in the current directory.

The name parameter specifies that only the file names will be listed (without additional information). The redirection operator (>) specifies that the output from the Get-ChildItem command will be redirected to a text file called listing.txt instead of displaying in the PS command window.

In the line $fileNames = get-content listing.txt, the Get-Content cmdlet retrieves all data from the file, line-by-line and, in this example, stores that content in a variable named $fileNames. Then, within a foreach

loop, each file is read in turn, and each line of the current file is displayed in the PS command window.

When you run the script, your output should look similar to the screen shot on the right.

(23)

CONDITIONAL STATEMENTS

A conditional statement performs some kind of test, then performs a specific action based on the results of that test (i.e., the resulting of the test is either true or false). An example of one type of test is to see if two strings are equal. Another test would be to evaluate two numbers and determine if one is less than the other. To conduct such tests, we use what are called comparison operators, usually with some form of IF statement (more on that later).

Comparison Operators

Unlike the equal sign (=), which is an assignment operator that takes the value to the right of the equal sign and assigns it to the variable to the left of the operator, comparison operators do not change the values on either side of the operator. Rather, they compare the two values to see if they meet the specified condition. To understand the difference, review the example below.

Assignment Operator Comparison Operator –eq $myName = "Charlotte" if ($myName –eq "Spock")

The example on the left assigns the string "Charlotte" to the variable $myName. Whatever was stored in $myName has now been replaced with "Charlotte". The variable will contain that string until replaced with something else or the script finishes executing.

The example on the right checks to see if whatever is stored in $myName is equal to the string "Spock". Whether it is or is not (i.e., whether the condition is true or false), the value held in $myName is not changed. In PowerShell, comparison operators always start with a dash (–) character.

COMPARISON OPERATORS PowerShell Operator Description

-eq Equal to -lt Less than -gt Greater than

-ge Greater than or equal to -le Less than or equal to -ne Not equal to

Of important note is string comparisons are not case-sensitive. You need to add a "c" just before the operator name in order to force case-sensitive comparisons (e.g., -ceq).

Copy your file WhatIsYourName.ps1 in your MyScripts directory to a file called

CompareNames.ps1. Change the code as follows, but use your first and last names in the IF statements.

# File: CompareNames.ps1

$firstName = read-host –prompt "Enter your first name" $lastName = read-host –prompt "Enter your last name" write-host

(24)

{

write-host "Your first name is" $firstName }

if ($lastName -eq "McGary") {

write-host "Your last name is" $lastName }

write-host "Your name is" $firstName $lastName write-host

# end script

Run the script three times, the first time using your correct first and last names, the second time using only your correct first name, and the third time using only your correct last name.

Your output should look similar to the screen shot to the right.

Now edit the script to force the first name comparison to be case-sensitive and rerun the script with the same inputs, adding a test case with your first name in lowercase. Compare the new results with the old.

If/ElseIf/Else….

So far, we've compared two objects by checking to see if they're equal by using a single IF statement. We then executed a line of code only if that comparison was true. Sometimes, however, you want to perform different actions based on multiple conditions. That's where a series of IF's, ELSEIF's, and finally, an ELSE, comes in handy.

The if/elseif/else combination works like this: it executes the first conditional statement (IF), and if the result is true, skips the other two conditions. Only if the first condition is false does it execute the next conditional statement (ElseIf). Only if that statement is false does it finally execute the Else statement. Basically the Else statement handles all conditions not specified by the IF and IfElse statements. Note that there can be more than one ElseIf statement, but only one Else, and it must be the last in the series.

Create the file CompareColors.ps1 in your MyScripts directory. Enter the following code:

# File: CompareColors.ps1

$color1 = read-host –prompt "Guess the first color" $color2 = read-host –prompt "Guess the second color" write-host

if ($color1 -ne "purple") {

write-host "You should have entered purple for your first color. You lose." }

elseif ($color2 -eq "green") {

write-host "You chose" $color1 "and" $color2 "in the correct order. YOU WIN!" }

(25)

else {

write-host "You entered the colors" $color1 "and" $color2". You lose." }

write-host # end script

Run the program three times, the first time entering Yellow and Blue, the second time entering Purple and Blue, and the third time entering Purple and Green.

Your output should look like this:

Let's analyze what this script does with our series of inputs.

The first time through, we entered Yellow for $color1 and Blue for $color2. Since Yellow is not equal to Purple, the condition if ($color1 -ne "purple") is true, so we get the message "You should have entered Purple for your first color. You lose." and the ElseIf and Else statements are ignored.

The second time we executed the script, we entered Purple and Blue for our two colors. Since Purple is obviously equal to Purple, the condition if ($color1 -ne "purple") is false, so the ElseIf is then executed. Since Blue is not equal to Green, the condition ($color2 -eq "green") is false, so it executes the Else statement.

(26)

CASTING—STRINGS VS. NUMBERS

If you were to create a variable and assign it a value in your code or pass the value through at the command line then perform some type of arithmetical operation on it, PowerShell would assume the value is a number not a string, as in the following example.

Create the file AddNumbers.ps1 in your MyScripts directory and enter the following lines of code: # File: AddNumbers.ps1 $x = $args[0] $y = 2 $sum = $x + $y write-host `n"x + y =" $sum `n # end script

Run the script by typing .\AddNumbers.ps1 3 at the command line.

Your output should look like this:

Read-Host, however, accepts input as a string value, not a numerical value. In other words, if you type in 100, it sees the value as the string "100" not the number 100. With strings, addition is in reality something called concatenation. Therefore, if you add the string "1" to the string "100", you get "1001" not "101".

To use input from Read-Host as a number and perform actual arithmetical operations on it, you must tell PowerShell to interpret it that way. For example, if you were to enter our two strings in the example above ("100" and "1") into $x and $y when prompted by Read-Host, you would represent them as integers by casting them as such. You do this by prefacing the variable name with [int], such as [int]$x

Create a file called Conditions.ps1 in your MyScripts directory and enter the following code:

# File: Conditions.ps1

$x = read-host -prompt "Enter a value for x" $y = read-host -prompt "Enter a value for y" $stringCat = $x + $y

write-host "The value of x + y as a concatenated string is" $stringCat # Read-Host retrieves input as strings, which are concatenated

# rather than 'added' so that $x + $y = $stringCat #

# To use them as numbers, we have to 'cast' them as integers # by prefacing the variables with [int]

$x = [int]$x $y = [int]$y $sum = $x + $y

(27)

$difference = $x - $y $product = $x * $y write-host "x = " $x ", y =" $y write-host $x "+" $y "=" $sum write-host $x "-" $y "=" $difference write-host $x "*" $y "=" $product if ($sum -eq $product)

{

write-host "Two is special because 2+2 = 2*2." }

elseif ($sum -gt $product) {

write-host "One is special because 1 + a number is > 1 * that number." }

else {

write-host "Nothing special about these numbers." }

write-host "`nDone!" # end script

Run the script three times. The first time you should enter 2 and 3 for x and y, respectively. The second time, enter 1 and 2. The third time 2 and 2.

Your output should look like this:

How does this script work? The if ($sum -eq $product) statement compares the values of $sum and $product to see if they are equal. If they are, the message about the number two is displayed.

(28)

If the if comparison is false, the elseif ($sum -gt $product) statement compares the values of $sum and $product to see if $sum is greater than $product. If true, the message about the number one is displayed.

If both the if and elseif comparisons are false (meaning all conditions are true except $sum equals $product or $sum greater than $product), the else statement displays the nothing-special message.

(29)

ARRAYS

Arrays are just variables which hold an indexed list of values. You've already seen one example of an array variable ($args) in previous examples which used command line

arguments. The first element of an array always has an index of 0, the second index is 1, the third is 2, etc. You access the value stored in an array element by referencing the array variable name and that element's position in the array. The index number is always enclosed by square brackets [].

For example, to retrieve the value stored in the first element of an array named $myArray, you access it as follows:

$myArray[0]

Defining Arrays

There are two ways to define an array. You can either create an empty array then add the values later, or you can populate the array at the time you create it. We'll do both in the next example.

Create a script called Arrays.ps1 in your MyScripts directory and enter the following code:

# File: Arrays.ps1

# Create an empty string array

# then populate with three characters $sArray = @()

$sArray = $sArray + "a" $sArray = $sArray + "b" $sArray = $sArray + "c"

write-host `nsArray[0,1,2] = $sArray

#Create an integer array with three numbers $intArray = @(1,2,3)

write-host intArray[0,1,2] = $intArray `n # end script

(30)

Combining Arrays

PowerShell allows you to create a new array by combining two or more existing arrays. You use the "+" operator just like when you concatenate strings. If you want to find out how many elements the new array holds, you can use the length property as in the following example.

Create a script called CombineNames.ps1 in your MyScripts directory. Enter the following code:

# File: CombineNames.ps1

$list1 = @("Kirk", "Spock", "McCoy")

$list2 = @("Uhura", "Scotty", "Sulu", "Checkov") $crew = $list1 + $list2

Write-host `nAnd the crew is ... Write-host $crew

write-host

write-host Number of elements in list1: $list1.length write-host Number of elements in list2: $list2.length write-host Number of elements in crew: $crew.length write-host

# end script

(31)

COMMAND REFERENCE

Command/Symbol(s) DOS/Batch Equivalent Description -eq -ne -lt, -gt, -le, -ge -cOperator = = NOT “__” = = if /i Comparison Operators: “Equal to”

“Not equal to”

“Less than”, “Greater than”, “Less than or equal to”, “Greater than or equal to”

Case-sensitive comparison

# rem Comment

$ set var=string %var%

Defines a variable name and access what's stored in that variable

$args[] %1 - %9 Special array that holds command-line input(s). May contain more than 9 inputs.

.\ Path to .ps1 file in current directory Clear-Host cls Clears the screen

Copy-Item copy Copies a file

do while Executes a loop once, then continues as long as a condition is true

for Executes a loop a set number of times

foreach for Command that loops through items in an array Get-ChildItem dir Lists files and folders within a directory Get-ChildItem -name dir /b Gets listing of names only

Get-Content type Retrieves the content from a file and processes one line at a time

Get-ExecutionPolicy Retrieves current policy on allowing PowerShell scripts to execute

Get-Help help Help cmdlet

Get-Help command command /? Gets help related to a cmdlet

If/ElseIf/Else if Conditional statements that perform comparisons and execute in series (or are skipped) based on the results of the previous comparison(s) Move-Item move Moves a file or directory

New-Item md Creates a directory or a file

Read-Host set /p Gets user input after script has begun execution Remove-Item del, rd, rd/s Deletes a file or directory

Rename-Item ren Renames a file or directory Select-String find Identifies a string pattern Set-ExecutionPolicy Resets executionpolicy

Set-Location cd Changes to a different directory Sort-Object sort Sorts objects (default is alphabetical) while Executes a loop while a condition is true Write-Host Displays object on the screen

Write-Output echo Writes objects to default formatter and default output for display

(32)

PRACTICE

PowerShell Lab #1

Requirements

1. Create a PowerShell script named Lab1.ps1 in your MyScripts directory.

2. The first five lines should be comments indicating the name of the file, your name, this course (CSNT xxx), the above lab number, and what you must type at the command line to run the program. For example, if Hello6.ps1 were the lab, the first five lines of that file would be

# file: Hello6.ps1 # author: Charlotte # course: CSNT xxx # lab: 1

# execution: .\Hello6.ps1 "Capt. Kirk" "Mr. Spock" "Dr. McCoy"

3. Although PowerShell recognizes most DOS and Unix commands, your script MUST use the appropriate PowerShell commands.

4. When you run the script, you will enter three command-line inputs. These three inputs will be the paths to three different directories on your hard drive, one of which must be the path to your MyScripts directory.

5. Store your name in a variable inside the script.

6. Display the contents of the above variable on the screen followed by the text "wrote this script."

7. You will then use a foreach loop to display a directory listing of each of the three directory names you passed through.

8. Initialize a counter, then increment the counter by one each time the foreach loop executes.

9. End your script with the End Script comment like we did in the examples.

10. After getting your foreach loop to work, add code to your script to perform the same function with these additional loop structures:

a. FOR b. WHILE c. DO WHILE d. DO UNTIL

(33)

PowerShell Lab #2

Requirements

1. Create a PowerShell script named Lab2.ps1 in your MyScripts directory.

2. The first five lines should be comments indicating the name of the file, your name, this course, the above lab number, and what you must type at the command line to run the program.

3. Create a subdirectory under your MyScripts directory if you don't already have one. Place copies of at least two .ps1 files in that subdirectory.

4. Write your script to find all .ps1 files in your MyScripts directory and all subdirectories which contain a string you will pass through at the command line.

5. Just in case you missed it direction in Step 4, the string you're searching for must be entered at the command line.

6. You will display the results of the search in four ways (the fourth way is explained in Step 8):

a. Sorted alphabetically by file name

b. Sorted in reverse alphabetical order (HINT: get-help is your friend) c. Grouped by the filename property

7. Test your script by searching for the string write-output.

8. Now change your script so that your search is case-sensitive (HINT: get-help is still your friend).

9. Test your script by running it once, searching for the string write-output, and again searching for the string Write-Output.

(34)

PowerShell Lab #3

Requirements

1. Create a PowerShell script named Lab3.ps1 in your MyScripts directory.

2. The first five lines should be comments indicating the name of the file, your name, this course, the above lab number, and what you must type at the command line to run the program.

3. Enter two numbers $n1 and $n2: one at the command line and one through a Read-Host

command (make sure you prompt the user for input).

4. Multiply the two numbers and assign them to a variable named $product.

5. Square each number by multiplying it by itself. The results should be stored in the variables $n1Sq and $n2Sq.

6. Add the two squares and assign to a variable named $sumSq.

7. Now subtract the variable $product from the variable $sumSq and store in a variable named $result.

8. Check to see if the values stored in $result and $product are equal.

a. If they are equal, output the text "You entered the same value for both numbers." and display one of the values.

b. Otherwise, just display what's stored in both $n1 and $n2. 9. Finally, you will output three lines of text:

a. The value of $product b. The value of $sumSq c. The value of $result

10. Test your script by entering two different numbers, then by entering the same value for both numbers.

(35)

PowerShell Lab #4

Requirements

1. Create a PowerShell script named Lab4.ps1 in your MyScripts directory.

2. The first five lines should be comments indicating the name of the file, your name, this course, the above lab number, and what you must type at the command line to run the program.

3. When you run this script you will need to enter at least two values at the command line 4. Create an empty array called $userArray.

a. Using a foreach loop, populate $userArray with the command line arguments you entered.

b. Display the number of elements in the filled array using the length property. c. Display the values in the array.

5. Create an array called $myArray with at least two elements in it (define these values at the time of creation).

a. Display the number of elements in the array using the length property. b. Display the values in the array.

6. Combine the two arrays into an array called $comboArray.

a. Display the number of elements in the array using the length property. b. Display the values in the array.

7. Initialize a counter variable.

8. Using a while loop, which increments the counter, display each value of each element of $comboArray using the value of the counter as the index (HINT: The length property will be very helpful here).

References

Related documents

Lower rental rate, operating expense and overall tax perspective when compared to conducting business in Manhattan 24/7 CBD setting offers around-the-clock amenities, a

Configure the fundamental service and logical components of a SharePoint implementation Administer SharePoint using the user interface, the command line, and Windows PowerShell

In addition to the general qualifications of a preceptor, t he appropriate preceptor for these courses is a master's- or doctorally-prepared nurse who is experienced in the role of

The draft subprogram also specifies all the available funding sources and the total volume of funding for the development of import substitution over a five-year

When a Puerto Rico card issuer has decided to provide customers (or holders of Puerto Rico or any other common carrier with prepaid credit cards) with this policy: • the card

One possible explanation for di fferent effects on immigrants and natives as well as for men and women may be di fferent resource allocation within intermar- riage: Native partners

With the evolution of the need for more rigorous cost accounting, many suppliers are adding new cost analytics capabilities to enterprise data warehouse environments and

We examined genetic variation, gene flow, and population structure at five microsatellite loci in samples from five pre-fur trade populations throughout the sea