ForEach vs Select-Object -ExpandProperty

Quite often I see scripts which use a ForEach loop to expand an array in an array and display that as a list. There is nothing wrong with that, however, another method is using 'Select-Object' with the 'ExpandProperty' option.

To illustrate, here is an example: 'I want to have a list with cluster and their datastores, but every datastore should be on a new line.'

Here is some code which fetches the data:

$ClusterComputeResources = get-view -viewtype "ClusterComputeResource" -Property Name,Datastore 

So that results in an array in $ClusterComputeResources: 

ForEach method 

​With the ForEach method you would create something like this to expand that list:

$DatastoresList = @()
ForEach ($ClusterComputeResource in $ClusterComputeResources) {
    ForEach ($Datastore in $ClusterComputeResource.Datastore) {
        $Result = [PSCustomObject]@{
            Name = $Cluster.Name
            Datastore = $Datastore
        }
        $DatastoresList += $Result
    }
} 

So that results in a list just the way I would have like to have it: 

Select-Object method 

 So we can also use the 'Select-Object' with the -ExpandProperty option, check out this one-liner:

$DatastoresList =  $ClusterComputeResources | Select-Object Name -ExpandProperty Datastore 

That also results in a list just the way I would like to have it: 

Results 

So the results are quite the same - however, there are some differences: the 'Select-Object' model is more 'Object' driven, note the 'Type' and 'Value' in the top, which is also visible when comparing both members:

# Results for the 'ForEach' method

$DatastoresList_ForEach | 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()
Datastore   NoteProperty ManagedObjectReference Datastore=Datastore-datastore-1093
Name        NoteProperty string Name=############



# Results for the 'Select-Object' method
$DatastoresList_SelectObject | Get-Member


   TypeName: VMware.Vim.ManagedObjectReference

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Name        NoteProperty string Name=############
Type        Property     string Type {get;set;}
Value       Property     string Value {get;set;} 

But there is another major advantage: the speed difference is huge!!!

ForEach: 2555 Milliseconds
Select-Object: 36 Milliseconds

That's 70 times faster!!!

Tricking the VM BIOS RTC to set a time
 

Comments

No comments made yet. Be the first to submit a comment
Guest
Friday, 20 September 2019