Phatmandrake
Phatmandrake

Reputation: 359

How-to access additional object properties in Pipeline after looping through one collection of objects properties

Suppose I am processing a list of user objects in a function.

Function DoThings {
   Process { $_.memberof).where{ $_ -match "Team_" }.foreach{ Remove-ADGroupMember $_ $_.samaccountname}
                  }#did things

The issue is that since the foreach loop is being used on the output of where, I've scoped myself down to not being able access the rest of the objects properties.

I want to loop through a subset of the objects properties, but I also need to be able to access other information from the user's properties to pass through to the cmdlet (such as the username).

So far the only thing I've been able to figure out doing is assigning $_.samaccountname to a temporary variable then calling that later, but that is inelegant.

Is there a cleaner way of doing this?

Upvotes: 0

Views: 206

Answers (2)

Phatmandrake
Phatmandrake

Reputation: 359

Using the where() and foreach() methods you can specify a parameter.

Function DoThings {

    Param ($user)

    Process {

    $_.memberof.Where{
    $_ -match "Team_" }.foreach{
    Remove-ADGroupMember $_ $user.samaccountname}

            }

}#did things

By specify your input as a parameter, you can access the initial object with the parameter name.

DoThings $Userlist

Alternatively, to maintain pipeline accessibility you can turn the function into an Advanced Function to allow the parameter to accept pipeline input explicitly.

Function DoThings {

    [cmdletbinding()]
    param([Parameter(ValueFromPipeline = $true)]$user)

    Process {

    $_.memberof.where{ 
    $_ -match "Team_" }.foreach{ 
    Remove-ADGroupMember $_ $user.samaccountname}

            }

}#did things

Will then work as

$Userlist DoThings 

A basic function will accept pipeline input, but only accessible through the automatic variable $_. In my testing using automatic variable $input has access to the initial object properties, but can seemingly only be used once per function.

Rather than assigning a value to a temporary variable it's much more elegant to use the features of the Advanced Function.

The same technique can be used with the ForEach-Object and Where-Object cmdlets without creating a new variable.

Upvotes: 0

Nas
Nas

Reputation: 1263

This could be considered more elegant:

Function DoThings {
    Process {
        ($_.memberof) | 
            Where-Object { $_ -match "Team_" } -PipelineVariable pipevar | 
                ForEach-Object { Remove-ADGroupMember $_ $pipevar.samaccountname}
}#did things

more about PipelineVariable

Upvotes: 1

Related Questions