Byron Jones
Byron Jones

Reputation: 315

Add a ScriptMethod Helper to query PSCustomObject

I am trying to add some simple helper methods to an existing PSCustomObject. My goal is to replace something like this:

$Persons.Where{$_.FirstName -like "*Test*"}

With this:

$Persons.GetFirstName("Test")

I am having a lot of trouble figuring out a working ScriptMethod to use with add-member.
Here is my example code, along with all of the variations I have tried so far:

$Persons = [PSCustomObject]@()

$Person1 = [PSCustomObject]@{
    FirstName = 'John';
    LastName = 'Doe';
    Age = 27
    }
$Person2 = [PSCustomObject]@{
    FirstName = 'Test';
    LastName = 'Dummy';
    Age = 27
    }

$Persons += $Person1 
$Persons += $Person2 

$Persons
#FirstName LastName Age
#--------- -------- ---
#John      Doe       27
#Test      Dummy     27

#Get using a regular where method to confirm
$Persons.Where{$_.FirstName -like "*Test*"}
#FirstName LastName Age
#--------- -------- ---
#Test      Dummy     27

#Add the Helper Method GetFirstName
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where{$_.FirstName -like "$Args[0]"}}

#Check if the Test record is returned
$Persons.GetFullName("Test")

#Use this to remove the method for the next try
$Persons.PSObject.properties.remove('GetFirstName')

#Other Permutations I have tried
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where($this.FirstName -like "$($Args[0])")}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where({FirstName -like $Args[0]})}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where({FirstName -like $args(0)})}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where({FirstName -like "$Args[0]"})}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where({FirstName -like "$($Args[0])"})}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where({$this.FirstName -like $Args[0]})}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where({$this.FirstName -like "*$($Args[0])*"})}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where({$this.FirstName -eq $Args[0]})}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where({$_.FirstName -like $Args[0]})}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where({$_.FirstName -like "$($Args[0])"})}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where("FirstName -like ""$($Args[0])""")}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.where("$($_.FirstName) -like ""$($Args[0])""")}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.GetEnumerator().where{FirstName -like $Args[0]}}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.GetEnumerator().where{$this.FirstName -like $Args[0]}}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this.GetEnumerator().where{$_.FirstName -like $Args[0]}}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this | ?{$_.FirstName -like $Args[0]}}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this | ?({$_.FirstName -like $Args[0]})}
add-member -inputobject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {$this | ?({$_.FirstName -like "$($Args[0])"})}


Upvotes: 1

Views: 39

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174690

There's one $Args per scope, so $Args inside .Where{ <in here> } does not actually contain the input arguments to the script method - declare a named parameter instead and it'll work:

Add-Member -InputObject $Persons -MemberType ScriptMethod -Name GetFirstName -Value {
  param([string]$fnArg)
  
  $this.Where{$_.FirstName -like $fnArg}
} -Force

Upvotes: 4

Related Questions