This article is a brief introduction to PowerShell at
a level suitable for our course CEG233. For more details, see the
listed references. It assumes that the CEG 233 Bash Introduction has
happened, and that you are familiar with control structures. It
also expects you to read the PowerShell book chapter(s) given in the
References. PowerShell is a sophisticated scripting
language. In particular, PowerShell error messages are too
cryptic. So do not get discouraged if some issues are too hard
to understand, and do not get disappointed because CEG233 omits many
items. PowerShell is a "large" language. In CEG 233, we cover a small
subset of the language. In particular, we do not dwell on its object-oriented
features. Our coverage is implied by the sections this article has.
The objectives of this article are to make you :
PowerShell scripting In Windows XP and later, two shells (CLI, command line interpreter) are installed by default in the Windows partition. The program known simply as cmd is now considered obsolete. The newer shell is known as powershell; it is typically found in the Windows drive as
C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe C:\Windows\system32\WindowsPowerShell\v1.0\powershell_ise.exe
(The version number may be different on the machine you are using.
The above is actually PowerShell v2 despite the fact that the parent
folder is named v1.0.) It can be invoked for interactive use through
the Run... facility as an ordinary unprivileged user. If you
wish to execute privileged operations, "search" for
powershell and then Run-as-administrator.
The powershell.exe is a plain looking console text
application. The powershell_ise.exe is a GUI
application that includes script development and debugging
support.
PowerShell is an interpreter for a language that has no explicit
name; so, we often refer to it as the PowerShell
language. In Windows, it is typical to see not only PowerShell but
also Visual Basic, Perl and Python used for scripting purposes.
As you read this article, open a PowerShell window, and try the commands shown. Frequently, we omit explaining what can be readily seen and understood by trying it out. PowerShell code is shown in a rectangle with Antique White background color. For now, the prompt string. is omitted.
Remember that in Windows, file names and command names can be written in either upper or lower case. This is not just a PowerShell property.
man command that is similar to
Linux man. Invoke
man (with no arguments), and man * (second word is just
the asterisk). This will give an overview what PowerShell has. helpls .* ?[A-G]*
gcm to see a list (gcm is an alias
for Get-Command). alias, cat, cd, cp, diff, h, history, kill, ls, man,
more, mkdir, mv, , ...
popd, pushd, ps, pwd, rmdir, rm,
tee
However, the flags/options that you are used to in Linux may not be the same. E.g., ls works, but ls -l will generate a complaint. Several of the listed items are "aliases" in PS.
A sequence of characters ending with a carriage-return (the Enter key) that you type is divided into tokens (words), just like in English. Let us call them w0, w1, ... It is a distraction at this point to describe (all) the rules that govern the splitting of a line into words. In the examples, you will see one or two delimiters other than space. Let us just assume that the tokens we have do not contain spaces.
(i) A trailing backtick character allows long commands to be split into multiple lines. (ii) Comments begin with the number-sign/hash (#) character and end at the end of that line.
Variable names are case insensitive, but for CEG233, think as if they are. They must have a dollar sign in front. Some variables are predefined.
echo $HOME $PROFILE $PSHOME $env:UserName
$HOME gives the path name of your home directory. $PROFILE is where you store your PowerShell customizations, analogous to .bashrc
Variables can be introduced and assigned values as follows.
$a="hi " $b=0123456789+1 $c="0123456789+1" $d="$a there" echo $a $b $c $d write-host $a $b $c $d
The echo shown in the above can be dropped, but in CEG233 we keep it; a list of just variable names on a line will print their values.
PowerShell has several variables whose values are saved and restored via the Windows registry. These are known as environment variables. Environment variables have $ENV: prefixed; we say that environment variables are stored in a separate namespace ENV:
$env:path
The $env:path is an environment variable of special
importance to us. Its value is a list of path names of directories
separated with semicolons. Unless the first word w0 of a command line
is a full path name, PowerShell searches for a program named w0 in
each of these directories in left-to-right order.
Just like ordinary variables, an environment variable can be changed by assignment. E.g., if we had installed cygwin in a
partition named H:, we can update PATH as follows.
$ENV:PATH="H:\cygwin\bin;$ENV:PATH"
To make this change permanent, you must change it via Computer->Properties->Advanced Environment Variables -> System Variables -> Path.
$v=ls
versus $v="ls".$v='$v;$v'notepad myLabJournal.txt works but wordpad
myLabJournal.txt does not, even though "it is
there". Discover the cause.$a=0, 1, 2, 3 $b=$a, 4, 5, 6, 7, 8 # elements of array a and then 4 to 8 $b[4], $a[3] $exclusions = '*.com', '*.exe', '*.o', '*.obj', '*.class', '*.sys', ` '*.dll', '*.dat', '*.log', '*.ini' $exclusions[3] $i=3 $exclusions[$a[$i]]
Try the following (one line at a time).
echo $profile gcm gcm * help ls
The acronym REPL stands for Read, Execute, Print, Loop of an interpreter. The line that you type is read, divided into tokens, and based on w0 and the path-search results, a program (or cmdlet, or an alias, ...) is invoked.
echo hello > hello.txt hello.txtWhat did the above do? Now, try this:
./hello.txt
Exercise: Our book uses a prompt string that includes the number of the command you are about to type. How did he do that? [Hint: echo $profile]
A frequent use of PowerShell consists of just one line of text
given interactively. Sophisticated use involves multiple lines
collected into a file of text; such files are called script or batch
files (and have a .ps1 extension).
A typical script file starts out with command lines (such as assignment, if, for, etc.) and calls to functions defined within this file as well as calls of other script files. Good programs and scripts all have comments. They will remind you what your program is actually doing months or years down the road.
You can certainly try control structures and loops interactively. But they are better learnt with script files (see below).
Windows, by default, disables running .ps1 scripts for
security reasons. You can enable executing of scripts as
follows. Execute PowerShell in administrator mode (right-click
the PowerShell shortcut to find the option). Run this
cmdlet:
set-executionpolicy remotesignedNow locally stored script files are enabled, but scripts arriving from remote sites must be signed. For more details, invoke
get-help
about_signing
# a beginner example named myScript.ps1
echo 'echo a few numbers'
for ($i=0; ($i -lt 10); $i=$i+3) {
echo $i
}
function fewNumbers($start, $end, $step) {
echo fewNumbers
for ($i=$start; ($i -lt $end+10); $i=$i+$step) {
echo $i
}
}
fewNumbers 200 280 4
Type a line beginning with dot alone as w0, and the name of the script file as w1.
. myScript.ps1
There are many different uses of if code-blocks. We can compare strings, check if a file exists, check the exit code of the last program, etc. The overall structure is as follows.
if (condition) {
code-block1
} else {
code-block2
}
The condition is evaluated as a Boolean expression. If true, code-block1 is executed, code-block2 is skipped. If false, code-block1 is skipped, code-block2 is executed. In simple situations, the braces can be omitted.
The following generates the Fibonacci numbers less than 100. It also shows a use of multiple assignments where LHS is a list of variable, and RHS is a same length list of values. In ($c -lt 100), minus-lt stands for less-than.
$c = $p = 1;
while ($c -lt 100) {
$c;
$c,$p = ($c+$p),$c
}
There are two other variations, do .. while (B) and do .. until (B), that are skipped in CEG 233.
Here are a couple of little examples. The for loop is similar to what C++ and Java have. To save vertical space, the first loop is written in one line. In general, trying to save vertical space is not a good idea.
for ($i=0; $i -lt 5; $i++) { $i }
foreach ($f in dir *.*) {
$sz = $f.length
$ex = $f.extension
$fn = $f.name # unused var
echo "File $f has $sz bytes. Its extension is $ex."
}
In the above the command dir *.* supplies the list for the "in" operator. This command can be replaced by any other that produces a list of items.
Function definitions look like this:
function name ( $param1, $param2, ... ) {
statement-list
}
Recall the fewNumbers 200 280 4 example. A function is invoked in a way similar to Bash. Name of the function as w0, and its arguments as w1, w2, ...
echo $HOME `$HOME hi,` there! hi`,` there!
ls | select basename
echo junk > 'fileName-with-difficultToDealWithChars.pdf_(dated_2009-10-32).pdf' write-host > 'fileName-with-difficult To Deal With; Chars.pdf.adobe.pdf.exe'
cat inputFnm.txt | psScript.ps1This feeds the content of file named inputFnm.txt to psScript.ps1. By now, you know that cat is an alias for get-content
PS> ps p* | kill
PS> ps | ? { $_.WS -gt 1000MB } | killPS> ls | measure length -s
PS> (ps notepad).WaitForExit()
PS> 'string'.Insert(1, 'ABC')
PS> $rssUrl = 'http://blogs.msdn.com/powershell/rss.aspx'
PS> $blog = [xml](new-object System.Net.WebClient).DownloadString($rssUrl)
PS> $blog.rss.channel.item | select title -first 8
$x=new-object xml;$x.load('http://blogs.msdn.com/powershell/rss.aspx');$x.rss.channel.item|select title -f 8
PS> $arguments = '-h', '15', 'www.google.com' PS> tracert $arguments
& "ls"
measure-command { ls }
$nm = Read-Host "Enter your name" Write-Host "Hello" $nm
function prompt {
$host.ui.rawui.WindowTitle = "Files: " + `
(get-childitem).count + " Process: " + (get-process).count
Write-Host ("PS " + $(get-location) +">") `
-nonewline -foregroundcolor Magenta
return " "
}
function Get-Weather ($city, $country) {
$URI = "http://www.webservicex.net/globalweather.asmx?wsdl"
$Proxy = New-WebServiceProxy $URI WebServiceProxy
$Proxy.GetWeather($city,$country)
}
Get-Weather "Dayton" "United States"
Get-Weather "Bermuda" "Bermuda"
The following are PowerShell methods that were described in the context of MP3 files sorter. Study the differences in syntax very carefully.
function createOneDummyMP3File($fileName, $album, $artist, $year)
{
echo '' > $fileName
id3tool $fileName -a $album -r $artist -y $year
}
PowerShell functions list their parameters with $names.
function createTestMP3Files($dirName) {
mkdir -force $dirName
pushd $dirName
foreach ($i in 0..9) {
foreach ($j in 0..9) {
createOneDummyMP3File song$i$j.mp3 Album$i Artist$j 200$i
}
}
popd
}
Exercise: Discover what the following do:
id3tool fnm.mp3 | findstr -s Album: | % { $_ -replace '.*:[ \t]*' , '' }
$albumNm=id3tool fnm.mp3 | findstr -s Album: | %{$_ -replace '.*: *\t*',''}See http://www.cs.wright.edu/~pmateti/Courses/233/Labs/Scripting/ScriptingLab1.htm and http://www.cs.wright.edu/ ~pmateti/ Courses/233/ Labs/ Scripting/ScriptingLab2.html
Sarah Gothard