Convert JSON data from http body request to string in PowerShell - json

I'm building a Function App in Azure using PowerShell HTTP Trigger.
The JSON body content looks something like this:
Input
{
"name": "azure 0103",
"time": 1400,
"stages": {
"MultiStageReviewSettings": [
{
"StageName": "Stage1",
"Reviewers": [
"ayewrewtela#t7rfdspfdsc.onfdsmicrosoft.com"
]
}
]
}
}
param($Request, $TriggerMetadata)
$label = $Request.Body.Name
$time = $Request.Body.Time
$stages = $Request.Body.Time
I need to covert the stages object to a single line string and it has to be like this:
Output
$stringData = '{ "MultiStageReviewSettings": [ { "StageName": "Stage1", "Reviewers": [ "ayewrewtela#t7rfdspfdsc.onfdsmicrosoft.com" ] } ] }'

As mentioned by Santiago the way to do it is :
$stages = $Request.Body.stages | ConvertTo-Json -Compress -Depth 99

Related

Iterate through a text file and add entries to the JSON using powershell

I have a text file with below data which is Dynamically generated, so the contents of the repo.txt keep changing
repo.txt -> Content as below
repo1
repo2
repo_3
And a JSON file
template.json -> Content as below
{
"name": "new-report-test-1",
"resources": {
"repositories": [
{
"name": "repoa"
},
{
"name": "repo_b"
}
]
},
"filters": {
"severities": [
"High"
]
}
}
now i want to read the repo list from the repo.txt file and update the template.json to below
{
"name": "new-report-test-1",
"resources": {
"repositories": [
{
"name": "repoa"
},
{
"name": "repo_b"
},
{
"name": "repo1"
},
{
"name": "repo2"
},
{
"name": "repo_3"
}
]
},
"filters": {
"severities": [
"High",
"Medium",
"Critical"
]
}
}
I have this bash script that does the job thiugh I'm unsure how to translate it to PoweShell. Any inputs would be highly appreciated
cat ./tmpgen_reponames.txt | while read repoEntry do echo " Repository: $repoEntry" cat <<< $(jq --arg REPOID "$repoEntry" '[ .[] , {"name":$REPOID} ]' tmpgen_repoarray.json) > tmpgen_repoarray.json done
You can accomplish this in PowerShell using ConvertFrom-Json to convert your Json into objects then following an object-oriented approach adding new custom objects to the .resources.repositories property and adding the new values Medium and Critical to the .filters.severities property of your Json, lastly, converting it back to a Json string with ConvertTo-Json:
$json = Get-Content path\to\template.json -Raw | ConvertFrom-Json
$json.resources.repositories = #(
$json.resources.repositories
(Get-Content path\to\repo.txt).Trim() | ForEach-Object {
[pscustomobject]#{ Name = $_ }
}
)
$json.filters.severities = #(
$json.filters.severities
'Medium'
'Critical'
)
$json | ConvertTo-Json -Depth 99 | Set-Content path\to\newJson.Json

(PowerShell) How to remove double quotes from the JSON output?

Here's an excerpt from my PowerShell script, that writes JSON data to a file:
$jsonData = #"
{
"FunctionName" :
{
"description": "",
"parameters": [],
"signature" : ""
}
}
"#
$jsonParameterData = #"
{
`t`t`t`t`t`t`t`t`t`t"description": "",
`t`t`t`t`t`t`t`t`t`t"name": ""
`t`t`t`t`t`t`t`t`t }
"#
$jsonData = $jsonData | ConvertFrom-Json
In the code above I have defined the JSON template that I will use to write to the file. I'm using jsonData to describe the function FunctionName with the keys of description, parameters, and signature.
On the other hand, I'm using jsonParameterData to describe each argument of the function FunctionName with the keys of description and name.
My PowerShell script pulls the data from other files, and writes this JSON information to a .json file.
For example, if the signature of the function I want to extract data from is Function FunctionName(Parameter1, Parameter2), in the .json file I would expect to see this:
"FunctionName": {
"description": "This function does this and that",
"parameters": [
{
"description": "This is the first parameter",
"name": "Parameter1"
},
{
"description": "This is the second parameter",
"name": "Parameter2"
}
],
"signature": "Function FunctionName(Parameter1, Parameter2)"
}
Somewhere in the code, I store the number of function arguments in the variable NumberOfArguments; the arguments of the function in ArrayOfArguments, and the argument descriptions in ArrayOfArgumentDescriptions.
The PowerShell code below is used to add jsonParameterData to jsonData:
for($i=0; $i -lt $NumberOfArguments; $i++){
$SelectedArgument = $ArrayOfArguments[$i]
$SelectedDescription = $ArrayOfArgumentDescriptions[$i]
$jsonData.AplusWait.parameters += $jsonParameterData
}
Then, I write jsonData to the file like this:
$jsonData = $jsonData | ConvertTo-Json | ForEach-Object { [System.Text.RegularExpressions.Regex]::Unescape($_) }
$jsonData.Substring(1, $jsonData.length - 2) | Add-Content -Path $OutputFile
Write-Output "`nFinished writing JSON data to file.`n"
However, the resulting output slightly does not match the intended output. The output looks like this:
"FunctionName": {
"description": "This function does this and that",
"parameters": [
"{
"description": "This is the first parameter",
"name": "Parameter1"
}",
"{
"description": "This is the second parameter",
"name": "Parameter2"
}"
],
"signature": "Function FunctionName(Parameter1, Parameter2)"
}
If you look closely, the output displays the parameters array as an array of strings (note the double quotes), when it should actually be an array of JSON objects.
How can I transform this:
"{
"description": "This is the first parameter",
"name": "Parameter1"
}"
into this:
{
"description": "This is the first parameter",
"name": "Parameter1"
}
?
Having the following JSONs:
$jsonData = #"
{
"foo": {
"des": "foo-des",
"par": [],
"sig": "foo-sig"
}
}
"#
$jsonParamData = #"
{
"des": "param-des",
"name": "param-name"
}
"#
$jsonObj = $jsonData | ConvertFrom-Json
$jsonParamObj = $jsonParamData | ConvertFrom-Json
# add param
$jsonObj.foo.par += $jsonParamObj
# Pay attention to the -Depth parameter otherwise the final json will be truncated
$jsonResult = $jsonObj | ConvertTo-Json -Depth 5
Write-Host $jsonResult
Should print:
{
"foo": {
"des": "foo-des",
"par": [
{
"des": "param-des",
"name": "param-name"
}
],
"sig": "foo-sig"
}
}
When converting objects back to json you should pay attention to the -Depth parameter since it will truncate your result.

How to add keys to values and convert to json in PowerShell?

I have a string like this:
$string = "PackageName1,1,C:\Path
PackageName2,12,C:\Path2
PackageName3,3,C:\Path3"
(is a file with multilines, when I get the content I have the string above)
I want to convert this string to Json:
[
{
Pacakge: "PackageName1",
Branch: = "1",
LocalPath = "C:\Path"
}
{
Pacakge: "PackageName2",
Branch: = "2",
LocalPath = "C:\Path2"
}
]
I can get the values with this code:
$spiltted = $string.Split(' ')
ForEach ($s in $splitted)
{
$values = $s.Split(',')
}
How can I add the Json keys to each value and convert it to Json object?
Thank you.
As your String looks like a csv without headers:
$string | ConvertFrom-Csv -Header Package,Branch,LocalPath|ConvertTo-Json
Sample output
[
{
"Package": "PackageName1",
"Branch": "1",
"LocalPath": "C:\\Path"
},
{
"Package": "PackageName2",
"Branch": "12",
"LocalPath": "C:\\Path2"
},
{
"Package": "PackageName3",
"Branch": "3",
"LocalPath": "C:\\Path3"
}
]

Cannot convert PSCustomObjects within array back to JSON correctly

I'm trying to ingest a JSON file into Powershell, append a block of JSON to an existing node (Components), then convert the PSCustomObject back to JSON and save the file. The JSON I'm playing with looks something like Figure 1.
As you see in my code, I run ConvertTo-Json to cast the data into a PSCustomObject, and I then append a new object to the Components node. If I view the object, $configFile in this case it all looks fine, but when I convert back to JSON the items in the Components node, are treated as strings and not evaluated into JSON (see last snippet). I imagine this is because ConvertTo-JSON treats arrays literally, but not 100% sure.
If someone can advise how to ensure the PSCustomObjects in the Components node get casted back to JSON properly I would be grateful, thank you.
Figure 1 - the original JSON:
{
"EngineConfiguration": {
"PollInterval": "00:00:15",
"Components": [
{
"Id": "ApplicationEventLog",
"FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
"Parameters": {
"LogName": "Application",
"Levels": "1"
}
},
{
"Id": "SystemEventLog",
"FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
"Parameters": {
"LogName": "System",
"Levels": "7"
}
}
],
"Flows": {
"Flows":
[
"(ApplicationEventLog,SystemEventLog),CloudWatchLogs"
]
}
}
}
Figure 2 - my code:
#Requires -Version 3.0
$configFile = "C:\Program Files\Amazon\EC2ConfigService\Settings\AWS.EC2.Windows.CloudWatch.json"
$configToPSObject = ConvertFrom-Json "$(Get-Content $configFile)"
$configToPSObject.EngineConfiguration.Components += New-Object -Type PSObject -Property ([ordered]#{
"Id" = "IISRequestQueueSize"
"FullName" = "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch"
"Parameters" = [PSCustomObject]#{
"CategoryName" = "HTTP Service Request Queues"
"CounterName" = "CurrentQueueSize"
"InstanceName" = "_Total"
"MetricName" = "IISRequestQueueSize"
"Unit" = ""
"DimensionName" = ""
"DimensionValue" = ""
}
})
$configJson = ConvertTo-Json -Depth 5 $configToPSObject
Set-Content -Path $configFile -Value $configJson
Figure 3 - the JSON output:
{
"EngineConfiguration": {
"PollInterval": "00:00:15",
"Components": [
"#{Id=ApplicationEventLog; FullName=AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch; Parameters=}",
"#{Id=SystemEventLog; FullName=AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch; Parameters=}",
"#{Id=IISRequestQueueSize; FullName=AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch; Parameters=}"
],
"Flows": {
"Flows":
"(ApplicationEventLog,SystemEventLog),CloudWatchLogs"
}
}
}
If I increase the depth to say, 8 or beyond, the JSON comes out as follows:
{
"EngineConfiguration": {
"PollInterval": "00:00:15",
"Components": [
"#{Id=ApplicationEventLog; FullName=AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch; Parameters=}",
"#{Id=SystemEventLog; FullName=AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch; Parameters=}",
"Id": "IISRequestQueueSize",
"FullName": "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
"Parameters": {
"CategoryName": "HTTP Service Request Queues",
"CounterName": "CurrentQueueSize",
"InstanceName": "_Total",
"MetricName": "IISRequestQueueSize",
"Unit": "",
"DimensionName": "",
"DimensionValue": ""
}
}
],
"Flows": {
"Flows": "(ApplicationEventLog,SystemEventLog),CloudWatchLogs"
}
}
}
The ConvertTo-Json cmdlet also has a Depth parameter, beyond which an object is treated with toString() instead of going deeper with recursion. So just setting that parameter to whatever max depth of objects you have should result in a correctly formed JSON.
$configJson = ConvertTo-Json $configToPSObject -Depth 8
# your JSON has depth of 5, get some extra
You have to supply the depth for the ConvertTo-Json commandlet.
Otherwise it only does the first level and leaves the subnodes as is and converts them to a string apparently.
$configJson = ConvertTo-Json $obj -Depth 3

Storing a part of a json query result in a variable in powershell

I have the following output from a json query and I am looking for a way to search though it and pull the value for the tvdbid(the number 72663) and store it in a variable.
In the example below you can see there are actually 2 results so I would like it to store the both in array.
I am running powershell 3 on my pc so any v3 specific stuff should be ok.
Out put
{
"data": {
"langid": 7,
"results": [
{
"first_aired": "2010-11-15",
"name": "Accused",
"tvdbid": 72663
},
{
"first_aired": "2010-01-17",
"name": "Enzai: Falsely Accused",
"tvdbid": 135881
}
]
},
"message": "",
"result": "success"
}
Using PS V3:
$json = #'
{
"data": {
"langid": 7,
"results": [
{
"first_aired": "2010-11-15",
"name": "Accused",
"tvdbid": 72663
},
{
"first_aired": "2010-01-17",
"name": "Enzai: Falsely Accused",
"tvdbid": 135881
}
]
},
"message": "",
"result": "success"
}
'#
$psobj = ConvertFrom-Json $json
$psobj.data.results.tvdbid
72663
135881
Most of the time I use now the CmdLet given by #mjolinor, but I still use the following old fashion XML serialization in two cases :
1- When I must use PowerShell V2
2- Even in PowerShell V3 when the json returned by a web service is very big the PowerShell V3 is sending an exception.
Add-Type -AssemblyName System.ServiceModel.Web, System.Runtime.Serialization
$utf8 = [System.Text.Encoding]::UTF8
function Write-String
{
PARAM([Parameter()]$stream,
[Parameter(ValueFromPipeline=$true)]$string)
PROCESS
{
$bytes = $utf8.GetBytes($string)
$stream.Write( $bytes, 0, $bytes.Length )
}
}
function Convert-JsonToXml
{
PARAM([Parameter(ValueFromPipeline=$true)][string[]]$json)
BEGIN
{
$mStream = New-Object System.IO.MemoryStream
}
PROCESS
{
$json | Write-String -stream $mStream
}
END
{
$mStream.Position = 0
try
{
$jsonReader = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonReader($mStream,[System.Xml.XmlDictionaryReaderQuotas]::Max)
$xml = New-Object Xml.XmlDocument
$xml.Load($jsonReader)
$xml
}
finally
{
$jsonReader.Close()
$mStream.Dispose()
}
}
}
function Convert-XmlToJson
{
PARAM([Parameter(ValueFromPipeline=$true)][Xml]$xml)
PROCESS
{
$mStream = New-Object System.IO.MemoryStream
$jsonWriter = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonWriter($mStream)
try
{
$xml.Save($jsonWriter)
$bytes = $mStream.ToArray()
[System.Text.Encoding]::UTF8.GetString($bytes,0,$bytes.Length)
}
finally
{
$jsonWriter.Close()
$mStream.Dispose()
}
}
}
In your case this will give the following :
$json = #'
{
"data": {
"langid": 7,
"results": [{
"first_aired": "2010-11-15",
"name": "Accused",
"tvdbid": 72663
},
{
"first_aired": "2010-01-17",
"name": "Enzai: Falsely Accused",
"tvdbid": 135881
}]
},
"message": "",
"result": "success"
}
'#
$xmlOut = Convert-JsonToXml -json $json
($xmlOut.root.data.results).ChildNodes[0].tvdbid.InnerText
($xmlOut.root.data.results).ChildNodes[1].tvdbid.InnerText