PowerShell/docs/learning-powershell/working-with-powershell-objects.md
2016-08-02 08:39:24 -05:00

4.3 KiB

Working with PowerShell Objects

When cmdlets are executed in PowerShell, the output is an Object, as opposed to only returning text. This provides the ability to store information as properties. As a result, handling large amounts of data and getting only specific properties is a trivial task.

As a simple example, the following function retrieves information about storage Devices on a Linux or MacOS operating system platform. This is accomplished by parsing the output of an existing command, parted -l in administrative context, and creating an object from the raw text by using the New-Object cmdlet.

Function Get-DiskInfo {
    $disks = sudo parted -l | Select-String "Disk /dev/sd*" -Context 1,0
    $diskinfo = @()
    foreach ($disk in $disks) {
        $diskline1 = $disk.ToString().Split("`n")[0].ToString().Replace('  Model: ','')
        $diskline2 = $disk.ToString().Split("`n")[1].ToString().Replace('> Disk ','')
        $i = New-Object psobject -Property @{'Friendly Name' = $diskline1; Device=$diskline2.Split(': ')[0]; 'Total Size'=$diskline2.Split(':')[1]}
        $diskinfo += $i
    }
    $diskinfo
}

Execute the function and store the results as a variable. Now retrieve the value of the variable. The results are formatted as a table with the default view.

Note: in this example, the disks are virtual disks in a Microsoft Azure virtual machine.

PS /home/psuser> $d = Get-DiskInfo
[sudo] password for psuser:
PS /home/psuser> $d

Friendly Name            Total Size Device
-------------            ---------- ------
Msft Virtual Disk (scsi)  31.5GB    /dev/sda
Msft Virtual Disk (scsi)  145GB     /dev/sdb

Passing the variable down the pipeline to Get-Member reveals available methods and properties. This is because the value of $d is not just text output. The value is actually an array of .Net objects with methods and properties. The properties include Device, Friendly Name, and Total Size.

PS /home/psuser> $d | Get-Member


   TypeName: System.Management.Automation.PSCustomObject

Name          MemberType   Definition
----          ----------   ----------
Equals        Method       bool Equals(System.Object obj)
GetHashCode   Method       int GetHashCode()
GetType       Method       type GetType()
ToString      Method       string ToString()
Device        NoteProperty string Device=/dev/sda
Friendly Name NoteProperty string Friendly Name=Msft Virtual Disk (scsi)
Total Size    NoteProperty string Total Size= 31.5GB

To confirm, we can call the GetType() method interactively from the console.

PS /home/psuser> $d.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

To index in to the array and return only specific objects, use the square brackets.

PS /home/psuser> $d[0]

Friendly Name            Total Size Device
-------------            ---------- ------
Msft Virtual Disk (scsi)  31.5GB    /dev/sda

PS /home/psuser> $d[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object

To return a specific property, the property name can be called interactively from the console.

PS /home/psuser> $d.Device
/dev/sda
/dev/sdb

To output a view of the information other than default, such as a view with only specific properties selected, pass the value to the Select-Object cmdlet.

PS /home/psuser> $d | Select-Object Device, 'Total Size'

Device   Total Size
------   ----------
/dev/sda  31.5GB
/dev/sdb  145GB

Finally, the example below demonstrates use of the ForEach-Object cmdlet to iterate through the array and manipulate the value of a specific property of each object. In this case the Total Size property, which was given in Gigabytes, is changed to Megabytes. Alternatively, index in to a position in the array as shown below in the third example.

PS /home/psuser> $d | ForEach-Object 'Total Size'
 31.5GB
 145GB

PS /home/psuser> $d | ForEach-Object {$_.'Total Size' / 1MB}
32256
148480

PS /home/psuser> $d[1].'Total Size' / 1MB
148480