简体   繁体   中英

Powershell Pipeline - return a new Object, that was created within pipline

I keep running into the same problem again, and i have my default way of handling it, but it keeps bugging me.
Isn't there any better way?

So basicly i have a pipline running, do stuff within the pipline, and want to return a Key/Value Pair from within the pipline.
I want the whole pipline to return a object of type psobject (or pscustomobject).

Here is the way i do it everytime. I create a hashtable at the beginning of the pipline and add key/Value Pairs from within the pipline to this hashtable using the.Add() method.
Afterwards i create a psobject by passing the hashtbale to New-Object`s -Property Parameter.
This gives me the desired result.

Get-Process | Sort -Unique Name | ForEach-Object -Begin { $ht = @{} } -Process {
    
    # DO STUFF
    $key = $_.Name
    $val = $_.Id

    # Add Entry to Hashtable
    $ht.Add($key,$val)
}

# Create PSObject from Hashtable
$myAwesomeNewObject = New-Object psobject -Property $ht

# Done - returns System.Management.Automation.PSCustomObject
$myAwesomeNewObject.GetType().FullName

But this seems a bit cluncky, isn't there a more elegant way of doing it?

Something like this:

[PSObject]$myAwesomeNewObject = Get-Process | Sort -Unique Name | ForEach-Object -Process {
    
    # DO STUFF
    $key = $_.Name
    $val = $_.Id

    # return Key/Val Pair
    @{$key=$val}
}

# Failed - returns System.Object[]
$myAwesomeNewObject.GetType().FullName

This unfortunally dosn't work, since the pipe returns an array of hashtables, but i hope you know now what iam trying to achieve.

Thanks

Not sure if this is more elegant but just another way of doing it, this uses an anonymous function so $ht will no longer be available after execution, and casts to [pscustomobject] instead of using New-Object :

[pscustomobject] (Get-Process | Sort -Unique Name | & {
    begin { $ht = @{ } }
    process {
        # DO STUFF
        $key = $_.Name
        $val = $_.Id

        # Add Entry to Hashtable
        $ht.Add($key, $val)
    }
    end { $ht }
})

You can also use the -End parameter to convert the final hash table to a pscustomobject as part of the pipeline, without needing to set the whole thing to a variable

$ht[$key]=$val is also a nice shorthand for $ht.Add($key,$val) :

Get-Process | 
  Sort -Unique Name | 
    Foreach -Begin { $ht = @{} } -Process { 
      $ht[$_.Name] = $_.Id 
    } -End {[pscustomobject]$ht} |  
      ## continue pipeline with pscustomobject

Thanks to @Santiago Squarzon and @Cpt.Whale answers, i were able to combine them to create a solution that pleases me:

$myAwesomeNewObject = `
Get-Process | Sort -Unique Name | & {
    begin { $ht = @{} }
    process {
        # DO STUFF
        $key = $_.Name
        $val = $_.Id

        # Add Entry to Hashtable
        $ht[$key]=$val
    }
    end {[pscustomobject]$ht}  
}

# Success - System.Management.Automation.PSCustomObject
$myAwesomeNewObject.Gettype().FullName

# And helper Hashtable is NULL thanks to the
# anonym function
$null -eq $ht

Thanks alot Guys

Alternatively you may create a hashtable using Group-Object -AsHashTable :

# Store the PIDs of all processes into a PSCustomObject, keyed by the process name
$processes = [PSCustomObject] (Get-Process -PV proc | 
                               Select-Object -Expand Id | 
                               Group-Object { $proc.Name } -AsHashtable)

# List all PIDs of given process
$processes.chrome

Notes:

  • Common parameter -PV (alias of -PipelineVariable ) makes sure that we can still access the full process object from within the calculated property of the Group-Object command, despite that we have a Select-Object command in between.
  • The values of the properties are arrays , which store the process IDs of all instances of each process. E. g.$processes.chrome outputs a list of PIDs of all instances of the chrome process.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM