0

When creating and working with PSCustomObjects which result in a NoteProperty member with a 'Definition' (as shown below), is there any easy, programmatic way to select the values from the definition fields without resorting to splitting the strings?

For example below, is there a 'good' way to extract the value 'silver' from the field of name 'token' that does not requre traditional string manipulations? I've been messing around with select and -ExpandProperty but getting no-where fast and would appreciate a nudge in the right direction.

TypeName: System.Management.Automation.PSCustomObject
Name   MemberType   Definition          
----   ----------   ----------          
bsw    NoteProperty decimal bsw=3.14    
name   NoteProperty string name=chris
token  NoteProperty string token=silver 
volume NoteProperty decimal volume=17.22

Thanks.

Update: Following guidance from Thomas I came up with this function to extract Noteproperty members from a PSObject and return a Hashtable with the names of the fields and the values:

function convertObjectToHash($psObj) {
    $hashBack = @{}

    try {
        $psObjFieldNames = $psObj | get-member -type NoteProperty | select "Name"
        $psObjFieldNames | foreach-object { 
            $hashBack.Add($_.Name,$psObj.$($_.Name)) }
        }catch{ "Error: $_" }

    return $hashBack
}

Thanks!

Indrid
  • 962
  • 4
  • 25
  • 39

2 Answers2

3

You can access the members of a custom object like in any other object:

$myCustomObject.token

Reproduction:

$myCustomObject = New-Object -TypeName psobject
$myCustomObject | Add-Member -MemberType NoteProperty -Name bsw -Value 3.14
$myCustomObject | Add-Member -MemberType NoteProperty -Name name -Value "chris"
$myCustomObject | Add-Member -MemberType NoteProperty -Name token -Value "silver"
$myCustomObject | Add-Member -MemberType NoteProperty -Name volume -Value 17.22

$myCustomObject | Get-Member -MemberType NoteProperty
$myCustomObject.token

Output:

   TypeName: System.Management.Automation.PSCustomObject

Name   MemberType   Definition                
----   ----------   ----------                
bsw    NoteProperty System.Double bsw=3.14    
name   NoteProperty string name=chris         
token  NoteProperty string token=silver       
volume NoteProperty System.Double volume=17.22

silver
stackprotector
  • 10,498
  • 4
  • 35
  • 64
  • Thanks Thomas. The method is probably my best chance of getting where I need to be. I''m actually getting the fields from a Json document. By default the object I get following the convertfrom-json has discrete fields I can access for name , but not the values. Your method will require a bit more preparation but I'm certain it will work. Many thanks! – Indrid May 10 '20 at 13:43
  • @Indrid How did you get the output in your question then? It doesn't look so complicated as you describe. – stackprotector May 10 '20 at 13:48
  • Thanks Thomas I started by getting content from a local json file which contains an array of items. I have no way of knowing what field names are going to be in each item apart from around three which are constant. I then did a convertfrom-json and because I could see no way to interact with the field names which had been found (just the values), I did the pipe to get-member -membertype "noteproperty". Doing that gave me access to the field names through ".Name". I also need the value, which I could see in the .Definition - but could not work out how to get just the value without string ops. – Indrid May 10 '20 at 16:05
  • Building on your example and input and for posterity I made this function to convert PSObject Noteproperty items into a HashTable. I will put the function into the main question body. I need all this in order to splat params at an add-pnpField cmdlet.... – Indrid May 10 '20 at 16:07
1

Since in your objects you store a string value, I see no other way to extract just the value silver then to use a string method to get only the part after the equals sign.

($obj.token -split '=', 2)[-1]  --> silver

Why not create the custom objects with an extra property called value and add the value you seek in there, taken from the Definition property? like

$obj = [PsCustomObject]@{'token' = 'string token=silver'; 'value' = 'silver'}
Theo
  • 57,719
  • 8
  • 24
  • 41