By Lee Holmes
Book Price: $12.99 USD
£7.99 GBP
PDF Price: $10.99
Cover | Table of Contents
PS> prompt indicates that PowerShell is ready for input, as shown in .
PS C:\Documents and Settings\Lee> function Prompt { "PS >" }
PS >pushd .
PS >cd \
PS >dir
Directory: Microsoft.PowerShell.Core\FileSystem::C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 11/2/2006 4:36 AM $WINDOWS.~BT
d---- 5/8/2007 8:37 PM Blurpark
d---- 11/29/2006 2:47 PM Boot
d---- 11/28/2006 2:10 PM DECCHECK
d---- 10/7/2006 4:30 PM Documents and Settings
d---- 5/21/2007 6:02 PM F&SC-demo
d---- 4/2/2007 7:21 PM Inetpub
d---- 5/20/2007 4:59 PM Program Files
d---- 5/21/2007 7:26 PM temp
d---- 5/21/2007 8:55 PM Windows
-a--- 1/7/2006 10:37 PM 0 autoexec.bat
-ar-s 11/29/2006 1:39 PM 8192 BOOTSECT.BAK
-a--- 1/7/2006 10:37 PM 0 config.sys
-a--- 5/1/2007 8:43 PM 33057 RUU.log
-a--- 4/2/2007 7:46 PM 2487 secedit.INTEG.RAW
PS >popd
PS >pwd
Path
----
C:\Documents and Settings\LeeGet-Process, Get-Content, and Stop-Process.PS >Get-Process -Name lsass
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
668 13 6228 1660 46 932 lsass
ProcessName parameter to get a specific process by name.Get, Set, Start, and Stop actions still apply. For a list of these common verbs, see .Tab key to auto-complete cmdlet names and parameter names:PS >Get-Pr<Tab> -N<Tab> lsass
gps alias that represents the Get-Process cmdlet (along with parameter shortening), you can instead type:PS >gps -n lsass
Get-Process cmdlet takes a process name as its first positional parameter. This parameter even supports wildcards:PS >gps l*s
PS >"Hello World" Hello World
Length property, which tells you how many characters are in the string. To access a property, you place a dot between the object and its property name:PS >"Hello World".Length 11
Get-Process cmdlet generates a System.Diagnostics.Process object, which you can store in a variable. In PowerShell, variable names start with a $ character. If you have an instance of Notepad running, the following command stores a reference to it:$process = Get-Process notepad
Process object from the .NET Framework, you can call methods on that object to perform actions on it. This command calls the Kill() method, which stops a process. To access a method, you place a dot between the object and its method name:$process.Kill()
Stop-Process cmdlet, but this example demonstrates an important point about your ability to interact with these rich objects.MB (for megabyte) and GB (for gigabyte) as some of the standard administrative constants. For example, how many disks will it take to back up a 40 GB hard drive to CD-ROM?PS >40GB / 650MB 63.0153846153846
PS >[DateTime]::IsLeapYear(2008) True
"06/21/2008" (the start of summer) to a date, and then subtracts the current date from that. It stores the result in the $result variable, and then accesses the TotalDays property.PS >$result = [DateTime] "06/21/2008" - [DateTime]::Now PS >$result.TotalDays 283.0549285662616
Path1 directory and moves them to the Path2 directory:Get-Item Path1\* | Move-Item -Destination Path2
Where-Object cmdlet, which runs a comparison against each incoming item. In this case, the comparison is $_.Handles -ge 500, which checks whether the Handles property of the current object (represented by the $_ variable) is greater than or equal to 500. For each object in which this comparison holds true, you pass the results to the Sort-Object cmdlet, asking it to sort items by their Handles property. Finally, you pass the objects to the Format-Table cmdlet to generate a table that contains the Handles, Name, and Description of the process.PS >Get-Process |
>> Where-Object { $_.Handles -ge 500 } |
>> Sort-Object Handles |
>> Format-Table Handles,Name,Description -Auto
>>
Handles Name Description
------- ---- -----------
588 winlogon
592 svchost
667 lsass
725 csrss
742 System
964 WINWORD Microsoft Office Word
1112 OUTLOOK Microsoft Office Outlook
2063 svchostPS >gps [b-t]*[c-r] | Stop-Process
b through t and end with the letters c through r. How can you be sure? Let PowerShell tell you. For commands that modify data, PowerShell supports -WhatIf and -Confirm parameters that let you see what a command would do:PS >gps [b-t]*[c-r] | Stop-Process -whatif What if: Performing operation "Stop-Process" on Target "ctfmon (812)". What if: Performing operation "Stop-Process" on Target "Ditto (1916)". What if: Performing operation "Stop-Process" on Target "dsamain (316)". What if: Performing operation "Stop-Process" on Target "ehrecvr (1832)". What if: Performing operation "Stop-Process" on Target "ehSched (1852)". What if: Performing operation "Stop-Process" on Target "EXCEL (2092)". What if: Performing operation "Stop-Process" on Target "explorer (1900)". (...)
-WhatIf parameter with the Stop-Process pipelined command lets you preview which processes on your system will be stopped before you actually carry out the operation.Not only did it stop everything, but on Vista, it forced a shutdown with only one minute warning!It was very funny though…. At least I had enough time to save everything first!
Get-Command cmdlet. For example, by entering the following, you can find out which PowerShell commands (and Windows applications) contain the word process.PS >Get-Command *process* CommandType Name Definition ----------- ---- ---------- Cmdlet Get-Process Get-Process [[-Name] <Str... Application qprocess.exe c:\windows\system32\qproc... Cmdlet Stop-Process Stop-Process [-Id] <Int32...
Get-Process does, use the Get-Help cmdlet, like this:PS >Get-Help Get-Process
Get-Member cmdlet to retrieve information about the properties and methods that an object, such as a .NET System.String, supports. Piping a string to the Get-Member command displays its type name and its members:PS >"Hello World" | Get-Member
TypeName: System.String
Name MemberType Definition
---- ---------- ----------
(...)
PadLeft Method System.String PadLeft(Int32 tota...
PadRight Method System.String PadRight(Int32 tot...
Remove Method System.String Remove(Int32 start...
Replace Method System.String Replace(Char oldCh...
Split Method System.String[] Split(Params Cha...
StartsWith Method System.Boolean StartsWith(String...
Substring Method System.String Substring(Int32 st...
ToChar- System.Char[] ToCharArray(), Sys...
ArrayMethod
ToLower Method System.String ToLower(), System....
ToLower- Method System.String ToLowerInvariant()
Invariant
ToString Method System.String ToString(), System...
ToUpper Method System.String ToUpper(), System....
ToUpper- Method System.String ToUpperInvariant()
Invariant
Trim Method System.String Trim(Params Char[]...
TrimEnd Method System.String TrimEnd(Params Cha...
TrimStart Method System.String TrimStart(Params C...
Chars Parameter- System.Char Chars(Int32 index) {...
izedProperty
Length Property System.Int32 Length {get;}foreach statement) work directly on the command line.PS >$handleCount = 0
PS >foreach($process in Get-Process) { $handleCount +=
$process.Handles }
PS >$handleCount
19403Measure-Object) to measure statistics about collections, this short example shows how PowerShell lets you apply techniques that normally require a separate scripting or programming language.PS >$webClient = New-Object System.Net.WebClient
PS >$content = $webClient.DownloadString("http://blogs.msdn.com/
PowerShell/rss.aspx")
PS >$content.Substring(0,1000)
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/
utility/FeedStylesheets/rss.xsl" media="screen"?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel>
<title>Windo
(...)Get-History cmdlet to retrieve the history of your session. For each of those items, you get its CommandLine property (the thing you typed) and send the output to a new script file.PS >Get-History | Foreach-Object { $_.CommandLine } >
c:\temp\script.ps1
PS >notepad c:\temp\script.ps1
(save the content you want to keep)
PS >c:\temp\script.ps1help about_signing'.PS >$xmlContent = [xml] $content
PS >$xmlContent
xml xml-stylesheet rss
--- -------------- ---
rss
PS >$xmlContent.rss
version : 2.0
dc : http://purl.org/dc/elements/1.1/
slash : http://purl.org/rss/1.0/modules/slash/
wfw : http://wellformedweb.org/CommentAPI/
channel : channel
PS >$xmlContent.rss.channel.item | select Title
title
---
CMD.exe compatibility
Time Stamping Log Files
Microsoft Compute Cluster now has a PowerShell Provider and
Cmdlets
The Virtuous Cycle: .NET Developers using PowerShell
(...)PS >Get-WmiObject Win32_Bios SMBIOSBIOSVersion : ASUS A7N8X Deluxe ACPI BIOS Rev 1009 Manufacturer : Phoenix Technologies, LTD Name : Phoenix - AwardBIOS v6.00PG SerialNumber : xxxxxxxxxxx Version : Nvidia - 42302e31
PS >[ADSI] "WinNT://./Administrator" | Format-List *
UserFlags : {66113}
MaxStorage : {-1}
PasswordAge : {19550795}
PasswordExpired : {0}
LoginHours : {255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255
255 255 255 255 255}
FullName : {}
Description : {Built-in account for
administering the computer/
domain}
BadPasswordAttempts : {0}
LastLogin : {5/21/2007 3:00:00 AM}
HomeDirectory : {}
LoginScript : {}
Profile : {}
HomeDirDrive : {}
Parameters : {}
PrimaryGroupID : {513}
Name : {Administrator}
MinPasswordLength : {0}
MaxPasswordAge : {3710851}
MinPasswordAge : {0}
PasswordHistoryLength : {0}
AutoUnlockInterval : {1800}
LockoutObservationInterval : {1800}
MaxBadPasswordsAllowed : {0}
RasPermissions : {1}
objectSid : {1 5 0 0 0 0 0 5 21 0 0 0 121 227
252 83 122 130 50 34 67 23 10 50
244 1 0 0}if, foreach, and throw) while commands do not. You will often want to control the way that Windows PowerShell interprets your statements, so lists the available options.Statement | Example | Explanation |
|---|---|---|
Precedence control:() |
PS >5 * (1 + 2) 15 PS >(dir).Count 2276 | Forces the evaluation of a command or expression, similar to how parentheses force the order of evaluation in a math expression. |
Expression subparse: $() |
PS >"The answer is
(2+2)"
The answer is (2+2)
PS >"The answer is
$(2+2)"
The answer is 4
PS >$value = 10
PS >$result = $(
>> if($value -gt 0)
{ $true }
else { $false }
>> )
>>
PS >$result
True
| Forces the evaluation of a command or expression, similar to how parentheses force the order of evaluation in a mathematical expression. However, a subparse is as powerful as a subprogram, and is required only when it contains logic or flow control statements. This statement is also used to expand dynamic information inside a string. |
List evaluation:@() |
PS >"Hello".Length
5
PS >@("Hello").Length
1
PS >(Get-ChildItem).
Count
12
PS >(Get-ChildItem
*.txt).Count
PS >@(Get-ChildItem
*.txt).Count
1
| Forces an expression to be evaluated as a list. If it is already a list, it will remain a list. If it is not, PowerShell temporarily treats it as one. |
# This is a regular comment
# Start of the here string
$null = @"
function MyTest
{
"This should not be considered a function"
}
$myVariable = 10;
"@
# End of the here string
# This is regular script againif, foreach, and throw) while commands do not. You will often want to control the way that Windows PowerShell interprets your statements, so lists the available options.Statement | Example | Explanation |
|---|---|---|
Precedence control:() |
PS >5 * (1 + 2) 15 PS >(dir).Count 2276 | Forces the evaluation of a command or expression, similar to how parentheses force the order of evaluation in a math expression. |
Expression subparse: $() |
PS >"The answer is
(2+2)"
The answer is (2+2)
PS >"The answer is
$(2+2)"
The answer is 4
PS >$value = 10
PS >$result = $(
>> if($value -gt 0)
{ $true }
else { $false }
>> )
>>
PS >$result
True
| Forces the evaluation of a command or expression, similar to how parentheses force the order of evaluation in a mathematical expression. However, a subparse is as powerful as a subprogram, and is required only when it contains logic or flow control statements. This statement is also used to expand dynamic information inside a string. |
List evaluation:@() |
PS >"Hello".Length
5
PS >@("Hello").Length
1
PS >(Get-ChildItem).
Count
12
PS >(Get-ChildItem
*.txt).Count
PS >@(Get-ChildItem
*.txt).Count
1
| Forces an expression to be evaluated as a list. If it is already a list, it will remain a list. If it is not, PowerShell temporarily treats it as one. |
# This is a regular comment
# Start of the here string
$null = @"
function MyTest
{
"This should not be considered a function"
}
$myVariable = 10;
"@
# End of the here string
# This is regular script againSyntax | Meaning |
|---|---|
$simpleVariable = "Value" | A simple variable name. The variable name must consist of alphanumeric characters. Variable names are not case sensitive. |
${arbitrary!@#@#`{var`}iable} = "Value" | An arbitrary variable name. The variable name must be surrounded by curly braces, but may contain any characters. Curly braces in the variable name must be escaped with a backtick (`). |
${c:\filename.extension} | Variable "Get and Set Content" syntax. This is similar to the arbitrary variable name syntax. If the name corresponds to a valid PowerShell path, you can get and set the content of the item at that location by reading and writing to the variable. |
[datatype] $variable = "Value" | Strongly typed variable. Ensures that the variable may contain only data of the type you declare. PowerShell throws an error if it cannot coerce the data to this type when you assign it. |
$SCOPE:variable | Gets or sets the variable at that specific scope. Valid scope names are global (to make a variable available to the entire shell), script (to make a variable available only to the current script), local (to make a variable available only to the current scope and subscopes), and private (to make a variable available only to the current scope). The default scope is the current scope: global when defined interactively in the shell, script when defined outside any functions or script blocks in a script, and local elsewhere. |
New-Item Variable:\variable–Value value | Creates a new variable using the Variable Provider. |
Get-Item Variable:\variableGet-Variable variable | Gets the variable using the Variable Provider or Get-Variable cmdlet. This lets you access extra information about the variable, such as its options and description. |
New-Variable variable-Option option-Value value | Creates a variable using the New-Variable cmdlet. This lets you provide extra information about the variable, such as its options and description. |
$true and $false. When it evaluates variables as part of a Boolean expression (for example, an if statement), though, PowerShell maps them to a suitable Boolean representation, as listed in .Result | Boolean representation |
|---|---|
$true | True |
$false | False |
$null | False |
Nonzero number | True |
Zero | False |
Nonempty string | True |
Empty string | False |
Nonempty array | True |
Empty array | False |
Hashtable (either empty or not) | True |
$myString = 'hello 't $ENV:SystemRoot'
$myString gets the actual value of hello 't $ENV:SystemRoot.$myString = "hello 't $ENV:SystemRoot"
$myString gets a value similar to hello C:\WINDOWS.PS >"Hello ""There""!" Hello "There"! PS >'Hello ''There''!' Hello 'There'!
$prompt = "$(Get-Location) >"
$prompt gets a value similar to c:\temp >.$output = "Current script name is:
$($myInvocation.MyCommand.Path)"$output gets a value similar to Current script name is c:\Test-Script.ps1.$myHereString = @" This text may span multiple lines, and may contain "quotes". "@
Sequence | Meaning |
|---|---|
`0 | The null character. Often used as a record separator. |
`a | The alarm character. Generates a beep when displayed on the console. |
`b | The backspace character. The previous character remains in the string but is overwritten when displayed on the console. |
`f | A form feed. Creates a page break when printed on most printers. |
`n | A newline. |
`r | A carriage return. Newlines in PowerShell are indicated entirely by the `n character, so this is rarely required. |
`t | A tab. |
`v | A vertical tab. |
''(Two single quotes) |
$myInt = 10
$myInt gets the value of 10, as a (32-bit) integer.$myDouble = 3.14
$myDouble gets the value of 3.14, as a (53-bit, 9 bits of precision) double.$myLong = 2147483648L
$myLong gets the value of 2147483648, as a long integer.$myDecimal = 0.999D
$myDecimal gets the value of 0.999.$myPi = 3141592653e-9
$myPi gets the value of 3.141592653.gb, mb, and kb to represent gigabytes, megabytes, and kilobytes, respectively:PS >$downloadTime = (1gb + 250mb) / 120kb PS >$downloadTime 10871.4666666667
0x:$myErrorCode = 0xFE4A
$myErrorCode gets the integer value 65098.$myBinary = [Convert]::ToInt32("101101010101", 2)$myBinary gets the integer value of 2901.$myOctal = [Convert]::ToInt32("1234567", 8)$myOctal gets the integer value of 342391.$myHexString = [Convert]::ToString(65098, 16)
$myHexString gets the string value of fe4a.$myBinaryString = [Convert]::ToString(12345, 2)
$myBinaryString gets the string value of 11000000111001.$myArray = @()
$mySimpleArray = 1,"Two",3.14
$myList = ,"Hello"
$myList = @("Hello")int[] represents an array of integers:[int[]] $myArray = 1,2,3.14
3.14 to the integer value of 3.PS >$myArray[2] 3
$multiDimensional = @(
(1,2,3,4),
(5,6,7,8)
)$multiDimensional[0][1] returns 2, coming from row 0, column 1.$multiDimensional[1][3] returns 8, coming from row 1, column 3.System.Int32:$multidimensional = New-Object "Int32[,]" 2,4 $multidimensional[0,1] = 2 $multidimensional[1,3] = 8
$myArray = 1,2,3,4,5,6 as an example:$myArray[0]
1, the first element in the array.$myArray[2]
3, the third element in the array.$myArray[-1]
6, the last element in the array.$myArray[-2]
5, the second-to-last element in the array.$myHashtable = @{}$myHashtable = @{ Key1 = "Value1";
"Key 2" = 1,2,3; 3.14 = "Pi" }$myHashtable["Key1"]
"Value1".$myHashtable."Key 2"
1,2,3.$myHashtable["New Item"] = 5
"New Item" to the hashtable.$myHashtable."New Item" = 5
"New Item" to the hashtable.[xml] type:$myXml = [xml] @"
<AddressBook>
<Person contactType="Personal">
<Name>Lee</Name>
<Phone type="home">555-1212</Phone>
<Phone type="work">555-1213</Phone>
</Person>
<Person contactType="Business">
<Name>Ariel</Name>
<Phone>555-1234</Phone>
</Person>
</AddressBook>
"@$myXml.AddressBook
Person property.$myXml.AddressBook.Person
Person nodes. Each Person node exposes contactType, Name, and Phone as properties.$myXml.AddressBook.Person[0]
Person node.$myXml.AddressBook.Person[0].ContactType
Personal as the contact type of the first Person node.XmlDocument and XmlElement classes. Unlike most PowerShell .NET wrappers, this wrapper does not expose the properties from the underlying class because they may conflict with the dynamic properties that PowerShell adds for node names.PsBase property. For example:$myXml.PsBase.InnerXml
Operator | Meaning |
|---|---|
+ | The addition operator:
$leftValue + $rightValue
When used with numbers, returns their sum.
When used with strings, returns a new string created by appending the second string to the first.
When used with arrays, returns a new array created by appending the second array to the first.
When used with hashtables, returns a new hashtable created by merging the two hashtables. Since hashtable keys must be unique, PowerShell returns an error if the second hashtable includes any keys already defined in the first hashtable.
When used with any other type, PowerShell uses that type's additio |