From 8bf342632d6ada0042e1c6e3118955ebd8369d0a Mon Sep 17 00:00:00 2001 From: Bobby Reed Date: Fri, 26 Apr 2019 14:09:26 -0400 Subject: [PATCH] Fixes #4160 - Add example for scriptblock expresion. Expanded hashtable calcuated property syntax (#4227) * Fixes #4160 - Add example for scriptblock expresion. Expanded hashtable calcuated property syntax * Fixing Spacing * Editorial review --- .../Select-Object.md | 285 +++++++++++------ .../Select-Object.md | 286 +++++++++++------ .../Select-Object.md | 289 +++++++++++------ .../Select-Object.md | 293 ++++++++++++------ .../Select-Object.md | 293 ++++++++++++------ 5 files changed, 945 insertions(+), 501 deletions(-) diff --git a/reference/3.0/Microsoft.PowerShell.Utility/Select-Object.md b/reference/3.0/Microsoft.PowerShell.Utility/Select-Object.md index ce05e59e6ef6..6505d6bc7ddf 100644 --- a/reference/3.0/Microsoft.PowerShell.Utility/Select-Object.md +++ b/reference/3.0/Microsoft.PowerShell.Utility/Select-Object.md @@ -10,7 +10,6 @@ title: Select-Object # Select-Object ## SYNOPSIS - Selects objects or object properties. ## SYNTAX @@ -33,28 +32,50 @@ Select-Object [-InputObject ] [-Unique] [-Wait] [-Index ] ## DESCRIPTION The `Select-Object` cmdlet selects specified properties of an object or set of objects. -It can also select unique objects, a specified number of objects, or objects in a specified position in an array. +It can also select unique objects, a specified number of objects, or objects in a specified position +in an array. + +To select objects from a collection, use the **First**, **Last**, **Unique**, **Skip**, and +**Index** parameters. To select object properties, use the **Property** parameter. +When you select properties, `Select-Object` returns new objects that have only the specified +properties. -To select objects from a collection, use the **First**, **Last**, **Unique**, **Skip**, and **Index** parameters. -To select object properties, use the **Property** parameter. -When you select properties, `Select-Object` returns new objects that have only the specified properties. +Beginning in Windows PowerShell 3.0, `Select-Object` includes an optimization feature that prevents +commands from creating and processing objects that are not used. -Beginning in Windows PowerShell 3.0, `Select-Object` includes an optimization feature that prevents commands from creating and processing objects that are not used. -When you include a `Select-Object` command with the **First** or **Index** parameters in a command pipeline, Windows PowerShell stops the command that generates the objects as soon as the selected number of objects is generated, even when the command that generates the objects appears before the `Select-Object` command in the pipeline. +When you include a `Select-Object` command with the **First** or **Index** parameters in a command +pipeline, PowerShell stops the command that generates the objects as soon as the selected number of +objects is generated, even when the command that generates the objects appears before the +`Select-Object` command in the pipeline. To turn off this optimizing behavior, use the **Wait** parameter. ## EXAMPLES ### Example 1: Select objects by property +This command creates objects that have the **Name**, **ID**, and working set (**WS**) properties of +process objects. + ```powershell Get-Process | Select-Object -Property ProcessName, Id, WS ``` -This command creates objects that have the Name, ID, and working set (WS) properties of process objects. - ### Example 2: Select objects by property and format the results +This command gets information about the modules used by the processes on the computer. +It uses `Get-Process` cmdlet to get the process on the computer. + +It uses the `Select-Object` cmdlet to output an array of `[System.Diagnostics.ProcessModule]` +instances as contained in the **Modules** property of each `System.Diagnostics.Process` instance +output by `Get-Process`. + +The command uses the **Property** parameter of the `Select-Object` cmdlet to select the process +names. This add a `ProcessName` `NoteProperty` to every `[System.Diagnostics.ProcessModule]` +instance and populates it with the value of current processes **ProcessName** property. + +The command uses the `Format-List` cmdlet to display the name and modules in of each process in a +list. + ```powershell Get-Process Explorer | Select-Object -Property ProcessName -ExpandProperty Modules | Format-List ``` @@ -67,25 +88,26 @@ BaseAddress : 140697278152704 ModuleMemorySize : 3919872 EntryPointAddress : 140697278841168 FileVersionInfo : File: C:\WINDOWS\explorer.exe -InternalName: explorer -OriginalFilename: EXPLORER.EXE.MUI -FileVersion: 10.0.17134.1 (WinBuild.160101.0800) -FileDescription: Windows Explorer -Product: Microsoft Windows Operating System -ProductVersion: 10.0.17134.1 + InternalName: explorer + OriginalFilename: EXPLORER.EXE.MUI + FileVersion: 10.0.17134.1 (WinBuild.160101.0800) + FileDescription: Windows Explorer + Product: Microsoft Windows Operating System + ProductVersion: 10.0.17134.1 ... ``` -This command gets information about the modules used by the processes on the computer. -It uses `Get-Process` cmdlet to get the process on the computer. - -It uses the `Select-Object` cmdlet to output an array of `[System.Diagnostics.ProcessModule]` instances as contained in the `Modules` property of each `System.Diagnostics.Process` instance output by `Get-Process`. - -The command uses the **Property** parameter of the `Select-Object` cmdlet to select the process names. This add a `ProcessName` `NoteProperty` to every `[System.Diagnostics.ProcessModule]` instance and populates it with the value of current processes `ProcessName` property. +### Example 3: Select processes using the most memory -The command uses the `Format-List` parameter to display the name and modules in of each process in a list. +This command gets the five processes that are using the most memory. +The `Get-Process` cmdlet gets the processes on the computer. +The `Sort-Object` cmdlet sorts the processes according to memory (working set) usage, and the +`Select-Object` cmdlet selects only the last five members of the resulting array of objects. -### Example 3: Select processes using the most memory +The **Wait** parameter is not required in commands that include the `Sort-Object` cmdlet because +`Sort-Object` processes all objects and then returns a collection. +The `Select-Object` optimization is available only for commands that return objects individually as +they are processed. ```powershell Get-Process | Sort-Object -Property WS | Select-Object -Last 5 @@ -101,36 +123,10 @@ Handles NPM(K) PM(K) WS(K) VS(M) CPU(s) Id ProcessName 1612 44 66080 92780 380 900.59 6132 INFOPATH ``` -This command gets the five processes that are using the most memory. -The `Get-Process` cmdlet gets the processes on the computer. -The `Sort-Object` cmdlet sorts the processes according to memory (working set) usage, and the `Select-Object` cmdlet selects only the last five members of the resulting array of objects. +### Example 4: Select unique characters from an array -The **Wait** parameter is not required in commands that include the `Sort-Object` cmdlet because `Sort-Object` processes all objects and then returns a collection. -The `Select-Object` optimization is available only for commands that return objects individually as they are processed. - -### Example 4: Select the name and start day of processes - -```powershell -Get-Process | Select-Object -Property ProcessName,@{Name="Start Day"; Expression = {$_.StartTime.DayOfWeek}} -``` - -```output -ProcessName StartDay ----- -------- -alg Wednesday -ati2evxx Wednesday -ati2evxx Thursday -... -``` - -This command gets the name and start day of the processes running on a computer. - -The command uses the `Get-Process` cmdlet to get the processes on the computer. -It passes the processes to the `Select-Object` cmdlet, which creates objects that have only the *ProcessName* parameter and a calculated property named Start Day. -The Start Day property is added by using a hash table with Name and Expression keys. -The value of the Expression key is a script blocks that gets the **StartTime** property of each process and the **DayofWeek** property of the StartTime. - -### Example 5: Select unique characters from an array +This command uses the **Unique** parameter of `Select-Object` to get unique characters from an array +of characters. ```powershell "a","b","c","a","a","a" | Select-Object -Unique @@ -142,52 +138,66 @@ b c ``` -This command uses the Unique parameter of `Select-Object` to get unique characters from an array of characters. +### Example 5: Select newest and oldest events in the event log -### Example 6: Select newest and oldest events in the event log +These commands gets the first (newest) and last (oldest) events in the Windows PowerShell event log. + +The command uses the `Get-EventLog` cmdlet to get all events in the Windows PowerShell log. +It saves them in the `$a` variable. + +The second command uses a pipeline operator (|) to send the events in `$a` to the `Select-Object` +cmdlet. +The `Select-Object` command uses the **Index** parameter to select events from the array of events +in the `$a` variable. The index of the first event is 0. +The index of the last event is the number of items in `$a` minus 1. ```powershell $a = Get-EventLog -LogName "Windows PowerShell" $a | Select-Object -Index 0, ($A.count - 1) ``` -These commands gets the first (newest) and last (oldest) events in the Windows PowerShell event log. +### Example 6: Select all but the first object -The command uses the `Get-EventLog` cmdlet to get all events in the Windows PowerShell log. -It saves them in the `$a` variable. - -The second command uses a pipeline operator (|) to send the events in `$a` to the `Select-Object` cmdlet. -The `Select-Object` command uses the **Index** parameter to select events from the array of events in the `$a` variable. -The index of the first event is 0. -The index of the last event is the number of items in `$a` minus 1. +This command creates a new PSSession on each of the computers listed in the Servers.txt files, +except for the first one. -### Example 7: Select all but the first object +This command uses the `Select-Object` cmdlet to select all but the first computer in a list of +computer names. +The resulting list of computers is set as the value of the **ComputerName** parameter of the +`New-PSSession` cmdlet. ```powershell New-PSSession -ComputerName (Get-Content Servers.txt | Select-Object -Skip 1) ``` -This command creates a new PSSession on each of the computers listed in the Servers.txt files, except for the first one. +### Example 7: Rename files and select several to review -This command uses the `Select-Object` cmdlet to select all but the first computer in a list of computer names. -The resulting list of computers is set as the value of the **ComputerName** parameter of the `New-PSSession` cmdlet. +This command adds a "-ro" suffix to the base names of text files that have the read-only attribute +and then displays the first five files so the user can see a sample of the effect. -### Example 8: Rename files and select several to review +The command uses the **ReadOnly** dynamic parameter of the `Get-ChildItem` for FileSystem cmdlet to +get read-only files. +It uses a pipeline operator (|) to send the files to the `Rename-Item` cmdlet, which renames the +file. +It uses the **Passthru** parameter of `Rename-Item` to send the renamed files to the `Select-Object` +cmdlet, which selects the first 5 for display. + +The **Wait** parameter of `Select-Object` prevents PowerShell from stopping the `Get-ChildItem` +cmdlet after it gets the first five read-only text files. +Without this parameter, only the first five read-only files would be renamed. ```powershell Get-ChildItem *.txt -ReadOnly | Rename-Item -NewName {$_.BaseName + "-ro.txt"} -PassThru | Select-Object -First 5 -Wait ``` -This command adds a "-ro" suffix to the base names of text files that have the read-only attribute and then displays the first five files so the user can see a sample of the effect. - -The command uses the **ReadOnly** dynamic parameter of the `Get-ChildItem` for FileSystem cmdlet to get read-only files. -It uses a pipeline operator (|) to send the files to the `Rename-Item` cmdlet, which renames the file. -It uses the **Passthru** parameter of `Rename-Item` to send the renamed files to the `Select-Object` cmdlet, which selects the first 5 for display. +### Example 8: Demonstrate the intricacies of the -ExpandProperty parameter -The **Wait** parameter of `Select-Object` prevents Windows PowerShell from stopping the `Get-ChildItem` cmdlet after it gets the first five read-only text files. -Without this parameter, only the first five read-only files would be renamed. +This example demonstrates the intricacies of the **ExpandProperty** parameter. -### Example 9: Demonstrate the intricacies of the -ExpandProperty parameter +Note that the output generated was an array of `[System.Int32]` instances. The instances conform to +standard formatting rules of the **Output View**. +This is true for any *Expanded* properties. If the outputted objects have a specific standard +format, the expanded property might not be visible. ```powershell # Create a custom object to use for the Select-Object example. @@ -239,10 +249,68 @@ ToUInt64 Method uint64 IConvertible.ToUInt64(System.IFormatProvider pro Name NoteProperty string Name=CustomObject ``` -This example demonstrates the intricacies of the `ExpandProperty` parameter. +### Example 9: Create custom properties on objects + +The following example demonstrates using `Select-Object` to add a custom property to any object. +When you specify a property name that does not exist, `Select-Object` creates that property as a +**NoteProperty** on each object passed. -Note that the output generated was an array of `[System.Int32]` instances. The instances conform to standard formatting rules of the **Output View**. -This is true for any *Expanded* properties. If the outputted objects have a specific standard format, the expanded property might not be visible. +```powershell +$customObject = 1 | Select-Object -Property MyCustomProperty +$customObject.MyCustomProperty = "New Custom Property" +$customObject +``` + +```Output +MyCustomProperty +---------------- +New Custom Property +``` + +### Example 10: Create calculated properties for each InputObject + +This example demonstrates using `Select-Object` to add calculated properties to your input. +Passing a **ScriptBlock** to the **Property** parameter causes `Select-Object` to evaluate the +expression on each object passed and add the results to the output. Within the **ScriptBlock**, you +can use the `$_` variable to reference the current object in the pipeline. + +By default, `Select-Object` will use the **ScriptBlock** string as the name of the property. +Using a **Hashtable**, you can label the output of your **ScriptBlock** as a custom property +added to each object. You can add multiple calculated properties to each object passed to +`Select-Object`. + +```powershell +# Create a calculated property called $_.StartTime.DayOfWeek +Get-Process | Select-Object -Property ProcessName,{$_.StartTime.DayOfWeek} +``` + +```output +ProcessName $_.StartTime.DayOfWeek +---- ---------------------- +alg Wednesday +ati2evxx Wednesday +ati2evxx Thursday +... +``` + +```powershell +# Add a custom property to calculate the size in KiloBytes of each FileInfo object you pass in. +# Use the pipeline variable to divide each file's length by 1 KiloBytes +$size = @{label="Size(KB)";expression={$_.length/1KB}} +# Create an additional calculated property with the number of Days since the file was last accessed. +# You can also shorten the key names to be 'l', and 'e', or use Name instead of Label. +$days = @{l="Days";e={((Get-Date) - $_.LastAccessTime).Days}} +# You can also shorten the name of your label key to 'l' and your expression key to 'e'. +Get-ChildItem $PSHOME -File | Select-Object Name, $size, $days +``` + +```Output +Name Size(KB) Days +---- -------- ---- +Certificate.format.ps1xml 12.5244140625 223 +Diagnostics.Format.ps1xml 4.955078125 223 +DotNetTypes.format.ps1xml 134.9833984375 223 +``` ## PARAMETERS @@ -266,21 +334,27 @@ Accept wildcard characters: True ### -ExpandProperty -Specifies a property to select, and indicates that an attempt should be made to expand that property. +Specifies a property to select, and indicates that an attempt should be made to expand that +property. Wildcards are permitted in the property name. - If the specified property is an array, each value of the array is included in the output. -- If the specified property is an object, the objects properties are expanded for every `InputObject` +- If the specified property is an object, the objects properties are expanded for every + **InputObject** In either case, the **Type** of objects output will match the **Type** of the expanded property. -If the `Property` parameter is specified, `Select-Object` will attempt to add each selected property as a `NoteProperty` to every outputted object. +If the **Property** parameter is specified, `Select-Object` will attempt to add each selected +property as a **NoteProperty** to every outputted object. > [!WARNING] -> If you receive the error: Select : Property cannot be processed because property `` already exists, consider the following. +> If you receive the error: Select : Property cannot be processed because property `` +> already exists, consider the following. > Note that when using `-ExpandProperty`, `Select-Object` can not replace an existing property. > This means: +> > - If the expanded object has a property of the same name, an error will occur. -> - If the *Selected* object has a property of the same name as an *Expanded* objects property, an error will occur. +> - If the *Selected* object has a property of the same name as an *Expanded* objects property, an +> error will occur. ```yaml Type: String @@ -315,7 +389,8 @@ Accept wildcard characters: False Selects objects from an array based on their index values. Enter the indexes in a comma-separated list. -Indexes in an array begin with 0, where 0 represents the first value and (n-1) represents the last value. +Indexes in an array begin with 0, where 0 represents the first value and (n-1) represents the last +value. ```yaml Type: Int32[] @@ -334,8 +409,9 @@ Accept wildcard characters: False Specifies objects to send to the cmdlet through the pipeline. This parameter enables you to pipe objects to `Select-Object`. -When you use the InputObject parameter with `Select-Object`, instead of piping command results to `Select-Object`, the InputObject value-even if the value is a collection that is the result of a command, such as -InputObject (Get-Process)-is treated as a single object. -Because InputObject cannot return individual properties from an array or collection of objects, it is recommended that if you use `Select-Object` to filter a collection of objects for those objects that have specific values in defined properties, you use `Select-Object` in the pipeline, as shown in the examples in this topic. +When you pass objects to the **InputObject** parameter, instead of using the pipeline, + `Select-Object` treats the **InputObject** as a single object, even if the value is a +collection. It is recommended that you use the pipeline when passing collections to `Select-Object`. ```yaml Type: PSObject @@ -367,15 +443,15 @@ Accept wildcard characters: False ### -Property -Specifies the properties to select. These properties are added as `NoteProperty` members to the output objects. -Wildcards are permitted. +Specifies the properties to select. These properties are added as **NoteProperty** members to the +output objects. Wildcards are permitted. -The value of the Property parameter can be a new calculated property. +The value of the **Property** parameter can be a new calculated property. To create a calculated, property, use a hash table. Valid keys are: -- Name (or Label) \ -- Expression \ or \