Parsing System.Object in PowerShell - powershell

I have a Powershell command that returns an object from an Invoke-RestMethod that is doing an HTTP Get. If I echo the return it looks like this:
policies
--------
{#{id=12345; name=xxxx; ... }
I want to parse out the value of id. What approach would I take to accomplish this?

As stated in #Will comment -> Use Get-Member to get the object type, like:
$returnVal = Invoke-RestMethod ...
$returnVal | Get-Member
This should return the type of the returned object (including methods and properties you're able to call on the object).
It seems that policies might be a dictionary, but I'm not sure. If it is a dictionary you can try:
$returnVal = Invoke-RestMethod ...
$dict = $returnVal | select -ExpandProperty policies
$id = $dict.Get_Item("id")
If it is simple JSON you can deserialize it via:
$returnVal = Invoke-RestMethod ...
$derserializedJsonObject = $returnVal | select policies | ConvertTo-Json
Hope that helps

Related

Getting string from what appears to be a hash-map in PowerShell

In PowerShell, I do this command:
$w = iwr -usedefaultcredentials -uri http://acme.corp/anvils.aspx -method 'POST' -Body '{"ctl00_MainEntityNumber:"Wiley"}'
That returns an object, part of which is an object called InputFiles, one of which is an object called __VIEWSTATE. I want to get the string value of __VIEWSTATE. So I do this:
$f = $w.inputfields | where id -eq __VIEWSTATE | select-object value | select-string value
which gives me a MatchInfo object. If I just print out the object, I get
#{value=/wEPDwUJODU5MDM5MTc0DxYEHhBQYWdlRW50aXR5TnVtYmVyZh4Yb0luc3VyYW5jZVNlYXJjaENyaXRlcmlhMv0BAAEAAAD/////AQAAAAAAAAAMAgAAAFFJRE9JLlJlZ3VsYXRlZEV ....}
which looks to me like a Hashmap or something. But when I try $f.value or $f['value'] I get nothing, or if I $f[0], I get the whole thing (including the #{value=.. part) So the question is, how do I get just the string after the #{value=\ ? Do I have to parse it out manually?
If you're just wanting the value itself then change it to
$f = $w.inputfields | where id -eq __VIEWSTATE | Select-Object -ExpandProperty value

Get value from json variable using windows powershell 5.1

I've got a JSON like this
[
{
"Param1":true,
"Param2":0,
"Param3":"OK"
...
...
}
]
How can I get Param2 value, using powershell 5.1?
For now, I tried to get property names, but only get length
$jsondeconverted = $jsonOrig | ConvertFrom-Json
$jsonOrig .PsObject.Properties |
Select-Object -ExpandProperty Name |
ForEach-Object {
Write-Host "Key : " $_
Write-Host "Value : " $thisJSON."$_"
}
EDIT
This is how I get my json
$jsonvar = '['+$jsonvar+']'
$convertedJson = $jsonvar | ConvertTo-Json -Depth 10
$deconvertedJson = $convertedJson | ConvertFrom-Json
$deconvertedJson contains only length parameter and nothing more.
You need to look into the object ($jsondeconverted) rather than the string ($jsonOrig)
Based on your json Structure, you would access param2 in the following way $jsondeconverted[0].Param2
Verifiable complete example
$jsonorig = '[{"Param1":true,"Param2":0,"Param3":"OK"}]'
$jsondeconverted = $jsonorig | ConvertFrom-Json
$jsondeconverted[0].param2

How to Display the Last Half of a String in the Results Returned by windows "findstr" command?

I have a windows 2012 instance on AWS in which I am trying to return the instance ID from the CLI. I can successfully return that info into a variable with this command:
$instanceId = Invoke-WebRequest -Uri http://169.254.169.254/latest/meta-data/instance-id
I can then echo the contents of that variable and filter out the pertinent line:
PS C:\Users\Administrator> echo $instanceId | findstr /b /c:"Content "
Content : i-4bee88888bd72g2a
The problem I have is that I wish to return only the string after the colon, so the output would look like:
i-4bee88888bd72g2a
What switch can I add to findstr to filter out that string? What is the Microsoft equivalent to sed?
PowerShell outputs objects, not text. When you run this command:
Invoke-WebRequest -Uri http://169.254.169.254/latest/meta-data/instance-id
it outputs a string representation of an object with a Content property. To select only the value of that property, you can use Select-Object -ExpandProperty as follows:
Invoke-WebRequest -Uri http://169.254.169.254/latest/meta-data/instance-id | Select-Object -ExpandProperty Content
This tells PowerShell: "There's an output object, and I want only the value of its Content property."
You can assign this to your variable:
$instanceId = Invoke-WebRequest -Uri http://169.254.169.254/latest/meta-data/instance-id | Select-Object -ExpandProperty Content
You can also probably write it this way:
$instanceId = (Invoke-WebRequest -Uri http://169.254.169.254/latest/meta-data/instance-id).Content
(That is, the ( ) enclose an expression, and you are getting the Content property of the expression's output object.)
I found a better solution that returns the exact results; it uses 'replace', the MS version of 'sed':
$instanceId = Invoke-WebRequest -Uri http://169.254.169.254/latest/meta-data/instance-id
$contentString = $instanceId | findstr /b /c:"Content "
$desiredresult = $contentString -replace "(Content :)\s([a-z]+)",'$2'
$desiredresult
Which returns the exact results:
i-4bee88888bd72g2a
I may have been barking up the wrong tree with the command findstr. I found that I can display the exact string withe command select-string:
$instanceId | select-string -Pattern "i-"
Which returns the results:
i-4bee88888bd72g2a
(But it included blank lines before and after the results, which I may have to discard, TBD.)

PowerShell TFS REST-API object loop advise

I have a piece of code that i managed to get working, but i feel that it can be written a lot easier. Im new with PowerShell and am trying to understand it better. I have a double foreach below to get the key and value out of the PSCustomObject that comes out of the TFS REST-API call.
For some reason im doing 2 loops, but i dont understand why this is required.
A sample of the contents of $nameCap.userCapabilities is
Name1 Name2
----- -----
Value1 Value2
So basically i want to loop over the "name/value pairs" and get their values.
What can i do better ?
$uri = "$tfsUri/_apis/distributedtask/pools/$global:agentPoolId/agents?api-version=3.0-preview&includeCapabilities=true"
$result = (Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json" -UseDefaultCredentials).value | select name, userCapabilities, systemCapabilities
#Loop over all agents and their capablities
foreach ($nameCap in $result)
{
$capabilityNamesList = New-Object System.Collections.ArrayList
#Loop over all userCapabilities and store their names
#($nameCap.userCapabilities) | %{
$current_Cap = $_
$req_cap_exists = $false
Get-Member -MemberType Properties -InputObject $current_Cap | %{
$temp_NAME = $_.Name
$temp_Value = Select-Object -InputObject $current_Cap -ExpandProperty $_.Name
[void]$capabilityNamesList.Add($temp_NAME)
}
}
}
I mean if you just need the Name and value, like userCapabilities, then just select for it.
so:
$result | select Name,userCapabilites
And if it doesn't give you a table automatically, then | ft -force

Print only property names of PowerShell object

I'm trying to print out only the property names of a Powershell object.
In a script I do an Invoke-RestMethod and Write-Host ($response.result | Format-List | Out-String) gives me a nice list of the $response.result object.
Get-Member -InputObject $response.result also does not display what I want.
$response.result looks something like this: #{id=1; skip=true}.
How do I just get a list/table thats shows id, skip etc.
Many thanks!
All PowerShell objects have a hidden property PSObject that allows accessing information about the object, e.g. its properties:
$response.result.PSObject.Properties | Select-Object -Expand Name
If it's not a hashtable, you can use Get-Member to find the properties like this:
$response.result | Get-Member -MemberType Properties | Select-Object Name
If the result is just a simple 1-level hashtable, you could do something like:
(#{id=1; skip=$true}).GetEnumerator() | %{ $_.Key }
id
skip