1

You have all been a great help - let me start by saying that.

I get the below output from a function I run - the data is stored in a variable called $response, obtained from an Invoke-RestMethod call.

@{ResourceType=UserStory; Id=202847; Name=Professional Lines: 2,800,000 Policy Aggregate Limit update}    

How do i go about parsing these values into new variables so the end result is

TP Id:202847 Professional Lines: 2,800,000 Policy Aggregate Limit update
mklement0
  • 382,024
  • 64
  • 607
  • 775
Shane
  • 43
  • 6
  • 2
    This question is lacking context it seems. How did `$reponse` get created? It looks like a hashtable. therefore it should be in a very usable state now e.g. `$response.ResourceType` You just want 3 variables at the end of the day? What are you going to do with them? So you want to have a flat string for output? Is there an equals sign that got dropped in the copy? – Matt Nov 01 '18 at 18:31
  • why do you need to extract the values from their very usable hashtable? you can address them via `$Response['Resource Type']` to get the `UserStory` value. simply address them by the Key to get the Value. ///// if you need to _display_ them on one line, then use the string format operator to build the string you want. – Lee_Dailey Nov 01 '18 at 18:34
  • It _looks_ like a hashtable, but it isn't one; it's actually the stringified version of a _custom object_ (e.g., `"$([pscustomobject] @{ one = 1; two = 2 })"`) – mklement0 Nov 01 '18 at 19:02

1 Answers1

3

What you're showing is the stringified form of a custom object, which uses a hashtable-like textual representation.

That custom object's definition looks something like this:

# Construct a custom object with .ResourceType, .Id, and .Name properties.
$response = [pscustomobject] @{
  ResourceType = 'UserStory'
  Id = 202847
  Name = 'Professional Lines: 2,800,000 Policy Aggregate Limit update'
}

If you include this variable in an expandable string (interpolating string), you'll get the representation in your question[1] - note that you'll get the same representation if you pass the object to the Write-Host cmdlet[2], as well as even with default output formatting if [pscustomobject] instances are nested in property values:

# Note the enclosing "..."
PS> "$response"

@{ResourceType=UserStory; Id=202847; Name=Professional Lines: 2,800,000 Policy Aggregate Limit update}

# Custom object nested in a property value:
PS> [pscustomobject] @{ foo = [pscustomobject] @{ bar = 'baz' } }

foo
---
@{bar=baz}
 

Note that without the enclosing "...", you'd get a nicer, tabular representation, courtesy of PowerShell's output-formatting system.

PS> $response  # direct output of the object

ResourceType     Id Name
------------     -- ----
UserStory    202847 Professional Lines: 2,800,000 Policy Aggregate Limit update

Assuming $response is actually still a custom object, and not a string representation of it, you can simply access the custom object's properties to build your string, again using an expandable string:

PS> "TP Id:$($response.Id) $($response.Name)"
TP Id:202847 Professional Lines: 2,800,000 Policy Aggregate Limit update

Note the need to use $(...) around the property references - see this answer for a summary of PowerShell's string-expansion rules.


An alternative approach is to use the -f operator, which uses formatting strings like the .NET String.Format() method:

PS> 'TP ID:{0} {1}' -f $response.Id, $response.Name
TP ID:202847 Professional Lines: 2,800,000 Policy Aggregate Limit update

[1] You can also obtain this representation by calling .psobject.ToString() on a custom object; curiously, just .ToString() doesn't work, as of PowerShell Core 6.1.0; this surprising discrepancy is discussed in this GitHub issue.

[2] Do note that Write-Host's purpose is to provide for-display-only (to-host) output, which bypasses PowerShell's success output stream, and thereby the ability to capture or redirect its output - see this answer for more information.

mklement0
  • 382,024
  • 64
  • 607
  • 775