Programming4us
         
 
 
Windows

Windows 7 : Scripting Windows with PowerShell - Scripting Objects

5/4/2011 6:24:34 PM
Scripting with PowerShell is really about scripting objects, so the most fundamental skills you need to master PowerShell scripting are those that enable you to work with and use objects.

In programming, an object is an element that exposes an interface to the programmer, who can then use that interface to work with the object in two ways:

  • Make changes to the object’s properties, which are the elements that describe or configure the object.

  • Make the object perform a task by activating one of the object’s methods, which are the elements that enable the object to perform actions.

In PowerShell, an object’s properties and methods are part of the collection known as the object’s members. Other items in an object’s member collection includes events (occurrences that trigger object actions) and property aliases (alternate names for certain properties).

Returning Object Members

When you need to work with an object in PowerShell, you usually begin by listing all the members associated with that object, which tells you which properties you can read or change, and which methods you can invoke. To return an object’s members, you use the Get-Member cmdlet:

object | get-member

Note

PowerShell’s pipe operator (|) works just like it does in a Command Prompt session. That is, it combines both input and output redirection, so that the output of one cmdlet is captured and sent as input to another cmdlet.

Replace object with the object you want to interrogate. For example, the following command returns the members associated with the current location (folder) in the PowerShell session:
get-location | get-member

Here’s the output you see:

Name         MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Drive Property System.Management.Automation.PSDriveInfo Drive {get;}
Path Property System.String Path {get;}
Provider Property System.Management.Automation.ProviderInfo Provider {get;}
ProviderPath Property System.String ProviderPath {get;}


Some member collections are quite large and may displays dozens of properties, methods, and other member types. If you’re only interested in a particular type of member, you can restrict the output of Get-Member by adding the -MemberType switch:

object | get-member -membertype type1, type2, ...

Here, replace type1, type2, and so on with one or more of the following member type keywords: AliasProperty, CodeProperty, Property, NoteProperty, ScriptProperty, Properties, PropertySet, Method, CodeMethod, ScriptMethod, Methods, ParameterizedProperty, MemberSet, Event, or All.

For example, if you only want to see the properties and methods associated with the Get-Process object (which returns a handle to a running process), enter the following command:

get-process | get-member -membertype property, method

Selecting Object Members

When you work with an object, PowerShell usually defines a default subset of the object’s members. For example, if you want to see a list of the running processes on your system, you use the Get-Process cmdlet, which sends to the console output similar to the following:

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
50 3 960 4120 47 0.02 3308 conhost
52 3 1844 5216 48 4.60 3860 conhost
475 5 1264 2808 33 344 csrss
310 10 1784 6208 69 412 csrss
105 7 36520 31568 109 49.31 2324 dwm
1139 38 51544 75488 316 95.78 2348 explorer
0 0 0 24 0 0 Idle
741 14 3028 8032 33 468 lsass
187 5 1696 3996 26 476 lsm
64 3 1016 2824 40 1552 lxdwcoms
434 10 85840 88124 219 7.24 2300 powershell
279 15 76000 66380 287 1.56 684 powershell_ise
154 7 14628 13572 124 2304 PresentationFontCache
764 26 39980 22148 123 2684 SearchIndexer
206 7 4096 5692 38 452 services
29 1 264 648 4 256 smss
461 21 15936 34336 221 17.61 2464 SnagIt32
407 12 7920 11464 79 1368 spoolsv
143 4 1820 6672 28 2192 sppsvc
351 7 3020 5928 39 588 svchost
272 9 3304 5928 30 708 svchost
579 14 14832 14336 82 764 svchost
1254 17 34740 37652 129 864 svchost
1331 28 17232 27928 128 908 svchost
662 20 8116 14136 67 1056 svchost
601 18 11352 13080 88 1232 svchost
315 24 11024 10896 52 1404 svchost
91 9 2748 4244 30 1496 svchost
126 9 4804 4472 33 1680 svchost
401 17 6240 11872 73 2920 svchost
261 7 2864 8268 54 3228 svchost
350 17 45248 11416 122 3936 svchost
709 0 52 4092 6 4 System
195 10 7416 7572 66 0.30 1216 taskhost
108 6 1892 7544 91 2.81 2520 taskmgr
53 3 920 3720 55 0.06 2576 TscHelp
77 5 924 2752 30 404 wininit
113 4 1708 3976 36 636 winlogon
441 16 10372 12764 128 2832 wmpnetwk
331 6 1716 4188 33 352 WUDFHost


These columns represent (from left to right) the number of open handles, the amount of nonpaged memory, the amount of paged memory, the size of the working set, the amount of virtual memory, the amount of CPU time, the process ID, and the process name. This is all useful information, but it might not be what you want to see. For example, you might not need to see the number of file handles each process is using, or you may be interested in not only the current working set for each process, but also the peak working set (the most memory the process has used in the current session).

In other words, there may be default properties that you don’t want to see, and other properties (such as PeakWorkingSet) that you do want to see. You can customize the members you work with by using the Select-Object cmdlet:

object | select-object member1[, member2, ...]

Here, object is the object you’re working with, and member1, member2, and so on are the members you want to use. Here’s an example:

get-process | select-object processname, workingset, peakworkingset

Tip

If you only want to see the first few results, add the -First n switch, where n is the number of results you want to see. For example, the following command returns the first five results:

get-process | select-object processname, workingset, peakworkingset -first 5

Similarly, if you only want to see the last few results, add the -Last n switch, where n is the number of results you want to see. For example, the following command returns the last 10 results:
get-process | select-object processname, workingset, peakworkingset -last 10



A Brief Aside About Formatting Output

If you run the command show at the end of the previous section, the console displays the name, working set, and peak working set for each running process. However, the two memory values are displayed in bytes, rather than an easier-to-read value such as kilobytes (as you get when you run Get-Process by itself). To fix this, you need to define a statement that defines how you want the output to look. In this case, the statement you want takes the following general form:

@{Label="Label"; Expression={expression}}

Here, Label is the text you want to appear at the top of the output column, and expression is an expression that defines how you want the values in that column to appears. For example, to convert a memory value in bytes to kilobytes, you need to divide it by 1,024:

[int]($_.workingset/1024)

We add [int] because we only want an integer result displayed. The symbols $_ are a PowerShell shorthand that refers to whatever object is currently being piped, so $_.workingset refers to the WorkingSet property of the current object. If we want the column name to be, say, WS (KB), the full statement looks like this:

@{Label="WS (KB)";Expression={[int]($_.workingset/1024)}}

We can do the same for the PeakWorkingSet property:

@{Label="Peak WS (KB)";Expression={[int]($_.peakworkingset/1024)}}

We then pipe everything through the Format-Table cmdlet using its -auto switch, which makes each column only wide enough to hold the widest item in the column:

get-process | select-object name, @{Label="WS (KB)";Expression=
{[int] ($_.workingset/1024)}}, @{Label="Peak WS (KB)";Expression={[int] ($_.peakworkingset/1024)}} | format-table -auto


Here’s the resulting output:

Name                  WS (KB) Peak WS (KB)
---- ------- ------------
conhost 4120 4148
conhost 5464 7724
csrss 2812 2844
csrss 6208 11428
dwm 31568 44884
explorer 75492 95140
Idle 24 0
lsass 8044 8292
lsm 4036 4316
lxdwcoms 2824 6256
powershell 89676 91252
powershell_ise 66380 68040
PresentationFontCache 13572 13600
SearchIndexer 22172 26588
services 5688 11280
smss 648 780
SnagIt32 34336 45548
spoolsv 11464 13620
sppsvc 6728 6748
svchost 5964 6552
svchost 5964 5988
svchost 14348 15448
svchost 37068 47276
svchost 27900 30128
svchost 14004 14420
svchost 13080 13228
svchost 10920 26924
svchost 4216 6196
svchost 4472 7576
svchost 11876 12252
svchost 8296 9608
svchost 16056 66828
System 4092 8032
taskhost 7584 8016
taskhost 10404 10424
taskmgr 7584 7592
TscHelp 3720 3720
wininit 2752 3172
winlogon 3976 6276
wmpnetwk 12760 24908
WUDFHost 4188 5128


Filtering Object Instances

By default, PowerShell returns all the instances of an object. If you want to work with only some subset of the object, you can use the Where-Object cmdlet to filter the instances and return just the ones you want. Here’s the general syntax:

object | where-object { expression }

Here, expression is a logical expression that defines the filter, and this expression usually takes the following general form:

property operator value

In this statement, property is the name of the object property you want to use as the filter, value is the text or numeric value you want to use as the comparison, and operator is one of the following PowerShell conditional operators:

-eqEquals
-neNot equal
-gtGreater than
-ltLess than
-geGreater than or equal to
-leLess than or equal to
-likeMatch with wildcards
-notlikeNo match with wildcards
-matchMatch with regular expression
-notmatchNo match with regular expression

For example, suppose you want to work with processes via Get-Process, but you’re only interested in the PowerShell process. In that case, you’d filter the Get-Process output as follows:

get-process | where-object { $_.processname -eq "powershell" }

Here’s the result:

Handles NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
474 10 87924 90356 219 7.94 2300 powershell

Here’s another example that returns just those processes where the working set is greater than 20MB:

get-process | where-object { $_.workingset -gt 20*1024*1024 }

Here’s the result:

Handles NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
105 8 36532 31576 112 51.34 2324 dwm
1208 41 56712 76460 325 97.13 2348 explorer
439 10 88440 90900 219 8.19 2300 powershell
265 15 75240 65624 287 1.58 684 powershell_ise
775 26 40412 23260 131 2684 SearchIndexer
459 21 15892 34012 220 17.61 2464 SnagIt32
1254 17 34764 37412 129 864 svchost
1321 28 17196 27888 128 908 svchost

You’ll probably find that the two wildcard operators are particularly useful. You use the standard wildcard characters: ? for a single characters, and * for any number of characters. For example, to work with any process that contains the string “powershell”, you’d use the following command:

get-process | where-object { $_.processname -like "*powershell*" }

Here’s the output:

Handles NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
478 10 88700 91168 219 8.25 2300 powershell
265 15 75240 65624 287 1.58 684 powershell_ise

Sorting Object Instances

When you work with the instances of an object in PowerShell, those instances are sorted on the object’s default property. For example, the instances returned by Get-Process are sorted on the ProcessName property. If you’d prefer to use the instances in some other order, you can use the Sort-Object cmdlet, which uses the following (partial) syntax:

object | sort-object -Property property [-Descending]

Here, property is the name of the property you want to use for the sort. For example, the following command sorts the output of the Get-Process cmdlet on the WorkingSet property values:

get-process | sort-object -property workingset

Here’s the result:

Handles NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
0 0 0 24 0 0 Idle
29 1 264 648 4 256 smss
77 5 924 2752 30 404 wininit
478 5 1264 2808 33 344 csrss
64 3 1016 2824 40 1552 lxdwcoms
53 3 920 3720 55 0.06 2576 TscHelp
113 4 1708 3976 36 636 winlogon
189 5 1740 4008 26 476 lsm
710 0 52 4092 6 4 System
50 3 960 4120 47 0.02 3308 conhost
331 6 1716 4188 33 352 WUDFHost
91 9 2748 4240 30 1496 svchost
126 9 4804 4476 33 1680 svchost
52 3 1864 5468 48 6.52 3860 conhost
208 7 4096 5692 38 452 services
353 7 3020 5928 39 588 svchost
274 9 3308 5944 30 708 svchost
311 10 1784 6192 70 412 csrss
143 4 1820 6672 28 2192 sppsvc
195 10 7416 7572 66 0.31 1216 taskhost
106 6 1964 7772 92 2.81 2520 taskmgr
741 14 3028 8032 33 468 lsass
261 7 2864 8268 54 3228 svchost
315 24 11024 10896 52 1404 svchost
407 12 7920 11464 79 1368 spoolsv
399 17 6240 11868 73 2920 svchost
439 16 10372 12764 128 2832 wmpnetwk
601 18 11352 13080 88 1232 svchost
154 7 14628 13572 124 2304 PresentationFontCache
647 20 8088 13996 66 1056 svchost
594 15 14912 14352 82 764 svchost
349 17 45248 15992 122 3936 svchost
763 26 39996 22212 123 2684 SearchIndexer
1329 28 17208 27932 128 908 svchost
105 8 36532 31576 112 52.24 2324 dwm
459 21 15892 34012 220 17.61 2464 SnagIt32
1254 17 33848 36808 129 864 svchost
265 15 75240 65624 287 1.58 684 powershell_ise
1208 41 56712 76460 325 97.13 2348 explorer
424 10 90108 92584 219 9.05 2300 powershell


Here’s a command that sorts Get-Process on the WorkingSet property in descending order and displays the top 10 results:

get-process | sort-object -property ws -descending | select-object -first 10


Here’s the output:

Handles NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
443 10 91072 93552 219 9.06 2300 powershell
1208 41 56720 76468 325 97.13 2348 explorer
265 15 75240 65624 287 1.58 684 powershell_ise
1254 17 33920 36872 129 864 svchost
459 21 15892 34012 220 17.61 2464 SnagIt32
105 8 36540 31584 112 52.43 2324 dwm
1324 28 17204 27916 128 908 svchost
773 26 40416 23332 131 2684 SearchIndexer
579 14 14856 14316 82 764 svchost
640 20 8056 13968 66 1056 svchost

Assigning an Object to a Variable

In PowerShell, if you want to work with an object’s properties or methods, you must first use cmdlets to define your object, as described in the past few sections, and then assign the result to a variable. Here’s the general syntax:

$variable = object

For example, you saw earlier that the following command returns the PowerShell process:

get-process | where-object { $_.processname -eq "powershell" }

To access the properties and methods for this process, you need to assign the result to a variable, like so:

$ps = get-process | where-object { $_.processname -eq "powershell" }

In PowerShell, you always start a variable name with a dollar sign ($).

Working with Object Properties

Every programmable object has a defining set of characteristics. These characteristics are the object’s properties, and they control the appearance and position of the object. When you refer to a property, you use the following syntax:

Object.Property

ObjectA variable containing the object instance
PropertyThe name of the property you want to work with

For example, suppose you want to reference the current working set value for the PowerShell process. In that case, you’d use cmdlets to filter Get-Process to just that instance, assign it to a variable, and then use that variable to access the WorkingSet property:

$ps = get-process | where-object { $_.processname -eq "powershell" }
$wset = $ps.workingset

Returning the Value of a Property

Sometimes you need to know the current setting of a property before changing the property or performing some other action. You can find out the current value of a property by using the following syntax:

$variable = Object.Property

Here, $variable is a variable name. For example, if you have a process stored in a variable, you can use that variable to return the value of the WorkingSet property. Here’s a sequence of commands that does this:

$ps = get-process | where-object { $_.processname -eq "powershell" }
$wset = $ps.workingset
write-host "The PowerShell working set is $wset bytes."
The PowerShell working set is 96444416 bytes.

Setting the Value of a Property

When you pipe an object into Get-Members, the resulting output includes a Definition column, and for Property members the definition includes braces ({}) at the end, and within those braces you see get if you can read the value of the property, and set if you can change the value of the property.

To set a property to a certain value, you use the following syntax:

Object.Property = value

Here, value is an expression that specifies the value to which you want to set the property. As such, it can be any of the scripting language’s recognized data types, which usually include the following:

  • A numeric value

  • A string value, enclosed in double quotation marks (such as "My Script Application")

  • A logical value ($True or $False)

For example, each running process has a MaxWorkingSet property that determines the maximum amount of memory the process can use. Here’s a sequence of commands that sets the MaxWorkingSet property for a process to 20MB:

$ps = get-process | where-object { $_.processname -eq "myapp" }
$ps.maxworkingset = 20*1024*1024

Working with Object Methods

An object’s properties describe what the object is, whereas its methods describe what the object does. For example, the WScript object has a Quit method that enables you to stop the execution of a script.

How you refer to a method depends on whether the method requires any arguments. If it doesn’t, the syntax is similar to that of properties:

Object.Method()

ObjectThe name of the object
MethodThe name of the method you want to run

For example, each process has a Kill() method that shuts down the process. Here’s an example that runs this method:

$ps = get-process | where-object { $_.processname -eq "myapp" }
$ps.kill()

Working with Object Collections

A collection is a set of similar objects. For example, when you run Get-Process by itself, the return value is a collection of process objects. Collections are objects, too, so they have their own properties and methods, and you can use these properties and methods to manipulate one or more objects in the collection.

To assign a collection to a variable, you use the following general syntax:

$variable = @(collection)

For example, the following command stores the collection of Get-Process instances in a variable:

$p = @(get-process)

The members of a collection are elements. You can refer to individual elements by using an index. For example, the following statement returns the name of the first process (collection indexes always begin at 0):

$p[0].name

Each collection has a Length property that tells you how many items are in the collection, which means that the expression Length-1 always refers to the last element in the collection:

$p[$_.length-1].workingset

If you don’t specify an element, PowerShell assumes that you want to work with the entire collection.

You often have to loop through the individual elements in a collection and perform some action on each element using one or more commands inside the loop. You use a foreach loop to do this:

foreach ($element in $collection) {
[statements]
}

$elementA variable used to hold the name of each element in the collection
$collectionA variable that stores the collection
statementsThe statements to execute for each element in the collection

The multiline structure of a foreach loop makes it better suited to a PowerShell script, but it’s possible to run short loops at the console by putting everything on one line:

foreach ($element in $collection) {statement1; statement2;...}

Here’s an example:

foreach ($pitem in $p) { write-host $pitem.name; write-host $pitem.id }

Note

You use the Write-Host cmdlet to write text to the console.

Other -----------------
- Windows 7 : Scripting Windows with PowerShell - Running PowerShell Cmdlets
- Windows 7 : Scripting Windows with PowerShell - Getting Started with PowerShell
- Scripting Windows 7 with WSH : Programming the Windows Management Instrumentation Service
- Scripting Windows 7 with WSH : Scripting Internet Explorer
- Scripting Windows 7 with WSH : Programming the WshNetwork Object
- Scripting Windows 7 with WSH : Programming the WshShell Object (part 2)
- Scripting Windows 7 with WSH : Programming the WshShell Object (part 1)
- Scripting Windows 7 with WSH : Programming the WScript Object
- Scripting Windows 7 with WSH : Programming Objects
- Scripting Windows 7 with WSH : Scripts and Script Execution
- Adding Macs to Your Windows 7 Network : Letting Windows Computers See Your Mac Shares
- Adding Macs to Your Windows 7 Network : Using a Mac to Make a Remote Desktop Connection to Windows 7
- Adding Macs to Your Windows 7 Network : Connecting to a Windows Shared Folder
- Adding Macs to Your Windows 7 Network : Connecting to the Windows Network
- Windows 7 : Controlling and Customizing Your Website (part 5) - Viewing the Server Logs
- Windows 7 : Controlling and Customizing Your Website (part 4) - Disabling Anonymous Access
- Windows 7 : Controlling and Customizing Your Website (part 3) - Working Without a Default Document
- Windows 7 : Controlling and Customizing Your Website (part 2) - Setting the Website’s Default Document
- Windows 7 : Controlling and Customizing Your Website (part 1)
- Windows 7 : Adding Folders and Files to the Default Website (part 3) - Adding a Folder to the Default Website
 
 
Most View
- SQL Server 2008 : Transparent Data Encryption
- Microsoft Office 2010 : Using and Customizing the Ribbon
- SQL Server 2008 : Developing Custom Managed Database Objects (part 7) - Using Transactions & Using the Related System Catalogs
- Parallel Programming with Microsoft .Net : Dynamic Task Parallelism - Variations
- Windows Server 2008 : Configure Group Policy Application Settings
- Exchange Mailbox Services Architecture
- Windows 7 : Setting Security Permissions on Files and Folders (part 1) -
- Microsoft Exchange Server 2003: Configuring Recipient Objects (part 6) - Configuring Mailbox Permissions
- Windows 7 : Setting Account Policies (part 2)
- Windows Server 2008 : Controlling Access to Web Services (part 5) - Managing URL Authorization Rules
Top 10
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 3) - Configuring Recipient Filtering
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 2)
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 1)
- Implementing Edge Services for an Exchange Server 2007 Environment : Installing and Configuring the Edge Transport Server Components
- What's New in SharePoint 2013 (part 7) - BCS
- What's New in SharePoint 2013 (part 6) - SEARCH
- What's New in SharePoint 2013 (part 6) - WEB CONTENT MANAGEMENT
- What's New in SharePoint 2013 (part 5) - ENTERPRISE CONTENT MANAGEMENT
- What's New in SharePoint 2013 (part 4) - WORKFLOWS
- What's New in SharePoint 2013 (part 3) - REMOTE EVENTS