psmp
psmp

Reputation: 41

How to create a custom method and items for a custom object in powershell?

I am trying to create a custom object with custom method and key value pair inside that method in powershell.

$mymethod= @{
MemberName = "mymethod"
MemberType = 'ScriptMethod'
Value = {'Test'}
Force = $true
}
Update-TypeData -TypeName 'Dummy' @mymethod
$test = [PsCustomObject][Ordered]@{PsTypeName = 'Dummy'}

So this creates and object like $test.mymethod() with the value "Test"

What I am trying is to create like below:

    $test.mymethod('key1')='value1'
    $test.mymethod('key2')='value2'

Any help?

Upvotes: 4

Views: 2816

Answers (2)

mklement0
mklement0

Reputation: 440501

To answer the question generically (even though the specific use case may warrant a simpler solution, as demonstrated in TheIncorrigible1's answer):

Note: In the code below I'm assuming that by $test.mymethod('key1')='value1' you actually meant to say that you want $test.mymethod('key1') to return 'value1', given that using a method call as the LHS of an assignment doesn't make sense.


lit mentions a PSv5+ alternative: defining a [class]:

# Define the class.
class Dummy { 
 [string] mymethod([string] $key) { return @{ key1='value1'; key2='value2' }[$key] }
}

# Instantiate it
$test = [Dummy]::new()

# Call the method
$test.mymethod('key2') # -> 'value2'

If you do want to use PowerShell's ETS (extended type system), as in your question (which is your only option in PSv4-, short of embedded C# code via Add-Type):

Perhaps the only hurdle was not knowing how to define a parameter for the method (use a param() block) and possibly how to access the instance on which the method is invoked (use $this); both techniques are demonstrated below:

# Define a type named 'Dummy' and attach a script method named 'mymethod'
$mymethod = @{
  MemberName = 'mymethod'
  MemberType = 'ScriptMethod'
  # Note the use of param() to define the method parameter and
  # the use of $this to access the instance at hand.
  Value      = { param([string] $key) $this.Dict[$key] }
  Force      = $true
}
Update-TypeData -TypeName 'Dummy' @mymethod

# Create a custom object and give it an ETS type name of 'Dummy', which
# makes the mymethod() method available.
$test = [PsCustomObject] @{ PsTypeName = 'Dummy'; Dict = @{ key1='value1'; key2='value2' } } 

$test.mymethod('key2')  # -> 'value2'

Upvotes: 3

Maximilian Burszley
Maximilian Burszley

Reputation: 19694

To expand on @Ansgar Wiechers's comment, it sounds like you're trying to recreate a dictionary, of which .NET has plenty:

$test = [pscustomobject]@{
    bar = [ordered]@{
    }
}

In action:

$test.bar.Add('key1', 'value1')
$test.bar.Add('key2', 'value2')

Output:

> $test
>> bar
>> ---
>> {key1, key2}

> $test.bar
>> Name    Value
>> ----    -----
>> key1    value1
>> key2    value2

Upvotes: 1

Related Questions