I have a basic PSCustomObject that I want to add multiple ScriptMethods to. When I invoke any ScriptMethod it is called a number of times equal to the number of ScriptMethods I added. Here’s a slimmed example:
function GetCustomObject {
param(
[Parameter(Mandatory=$true)] [String]$data
)
$CustomObject = [PSCustomObject]@{
member = $data
}
$CustomObject | Add-Member -MemberType ScriptMethod -PassThru -Name PrintMember -Value {
Write-Host "Data is:" $this.member
$this.member += ", again?"
}
$CustomObject | Add-Member -MemberType ScriptMethod -PassThru -Name SomeOtherFunction -Value {
Write-Host "SomeOtherFunction"
}
#Delete this ScriptMethod to reduce the number of prints by 1
$CustomObject | Add-Member -MemberType ScriptMethod -PassThru -Name YetAnotherFunction -Value {
Write-Host "YetAnotherFunction"
}
}
$LocalCustomObject = GetCustomObject "Hello World"
$LocalCustomObject.PrintMember()
$LocalCustomObject.SomeOtherFunction()
$LocalCustomObject.YetAnotherFunction()
This code returns the following:
Data is: Hello World
Data is: Hello World, again?
Data is: Hello World, again?, again?
SomeOtherFunction
SomeOtherFunction
SomeOtherFunction
YetAnotherFunction
YetAnotherFunction
YetAnotherFunction
I think it has something to do with how I’m adding the ScriptMethods to the PSCustomObject, but I have not yet figured it out. If you have a better way of adding ScriptMethods I’m all ears.
>Solution :
The issue is that you’re using -PassThru so your function is returning 3 objects instead of 1, and calling the methods over each member of the resulting array is possible due to member-access enumeration. Simply remove -PassThru from your code and output the object in the end:
function GetCustomObject {
param(
[Parameter(Mandatory = $true)] [String]$data
)
$CustomObject = [PSCustomObject]@{
member = $data
}
$CustomObject | Add-Member -MemberType ScriptMethod -Name PrintMember -Value {
Write-Host 'Data is:' $this.member
$this.member += ', again?'
}
$CustomObject | Add-Member -MemberType ScriptMethod -Name SomeOtherFunction -Value {
Write-Host 'SomeOtherFunction'
}
#Delete this ScriptMethod to reduce the number of prints by 1
$CustomObject | Add-Member -MemberType ScriptMethod -Name YetAnotherFunction -Value {
Write-Host 'YetAnotherFunction'
}
$CustomObject
}
$LocalCustomObject = GetCustomObject 'Hello World'
$LocalCustomObject.PrintMember()
$LocalCustomObject.SomeOtherFunction()
$LocalCustomObject.YetAnotherFunction()
You could also use -PassThru but only on the last Add-Member call:
function GetCustomObject {
param(
[Parameter(Mandatory = $true)] [String]$data
)
$CustomObject = [PSCustomObject]@{
member = $data
}
$CustomObject | Add-Member -MemberType ScriptMethod -Name PrintMember -Value {
Write-Host 'Data is:' $this.member
$this.member += ', again?'
}
$CustomObject | Add-Member -MemberType ScriptMethod -Name SomeOtherFunction -Value {
Write-Host 'SomeOtherFunction'
}
#Delete this ScriptMethod to reduce the number of prints by 1
$CustomObject | Add-Member -MemberType ScriptMethod -Name YetAnotherFunction -Value {
Write-Host 'YetAnotherFunction'
} -PassThru
}
$LocalCustomObject = GetCustomObject 'Hello World'
$LocalCustomObject.PrintMember()
$LocalCustomObject.SomeOtherFunction()
$LocalCustomObject.YetAnotherFunction()