How do I pass variables through a Json body Powershell - json

I want to pass variables in for these values but I cant get them to go for example in user_id I want to pass the variable $userID
This is an example of the Body i'm using:
$body = '{
"data":
[
{
"user_id":$userID,
"type":"manual",
"date":"2021-01-30",
"duration":"150",
"jobcode_id":"15281216",
"notes":"This is a test of a manual time entry",
"customfields": {
"54138" : "IT Services",
"54136" : "Yes"
}
}
]
}'

I would use a double-quoted Here-String for that:
$userID = 'Alex'
$body = #"
{
"data": [{
"user_id": "$userID",
"type": "manual",
"date": "2021-01-30",
"duration": "150",
"jobcode_id": "15281216",
"notes": "This is a test of a manual time entry",
"customfields": {
"54138": "IT Services",
"54136": "Yes"
}
}]
}
"#
$body now contains:
{
"data": [{
"user_id": "Alex",
"type": "manual",
"date": "2021-01-30",
"duration": "150",
"jobcode_id": "15281216",
"notes": "This is a test of a manual time entry",
"customfields": {
"54138": "IT Services",
"54136": "Yes"
}
}]
}

The reason why $userID is not substituted for it's value in your example is because you are using a single quote (') character. PowerShell only substitutes when you use a double quote (") character.
This would give you the challenge that your data already contains double quotes. There Here string from Theo's answers works just fine but as a personal preference I would use a PowerShell hashtable to construct an object and convert it to Json using Convert-To-Json.
Example:
$userID = 'John'
$body = #{
"data" = ,#{
"user_id" = $userID;
"type" = "manual";
"date" = "2021-01-30";
"duration" = "150";
"jobcode_id" = "15281216";
"notes" = "This is a test of a manual time entry";
"customfield" = #{
"54138" = "IT Services";
"54136" = "Yes";
}
}
}
$body | ConvertTo-Json -Depth 3
Output:
{
"data": [
{
"notes": "This is a test of a manual time entry",
"customfield": {
"54138": "IT Services",
"54136": "Yes"
},
"duration": "150",
"type": "manual",
"date": "2021-01-30",
"jobcode_id": "15281216",
"user_id": "John"
}
]
}
EDIT: As robdy mentioned in the comments, the Depth parameter should be used (I've added it). A good explanation can be found here.

Related

How to remove brackets from JSON?

I have a groovy script that I want to return userDefinedErrorText. The issue I am having is that when parse my JSON I am having my failedForm variable equal [Failed] instead of "Failed".
If I remove the first pair of [] from my JSON input, I get the correct "Failed".
Is there a way to remove [] from the input JSON?
My Groovy
def json = new JsonSlurper().parseText( aInputJson )
failedForm = json?.userDefinedErrorText
if( failedForm == "Failed" ) {
resultMessage = "false"
}
JSON
[
{
"step": "abcd",
"message": {
"ServiceRequest: abc": {
"App Stack Form Exception": {
"Expecting Form": "P",
"Resulting Form": "P"
},
"JAS Response": {
"fs_P": {
"title": "I",
"data": {},
"errors": [
{
"CODE": "799L",
"TITLE": "Error: Invalid Long Address Number",
"ERRORCONTROL": "15",
"DESC": "CAUSE . . . . The long address number entered is not found in the Address Book\\u000a Master file (F0101).\\u000aRESOLUTION. . Enter a valid long address number.",
"MOBILE": "The long address number entered is not found in the Address Book\\u000a Master file (F0101)."
}
],
"warnings": []
},
"stackId": 12,
"stateId": 5,
"rid": "8f4",
"currentApp": "P",
"timeStamp": "2022-04-22:11.25.03",
"sysErrors": []
}
}
},
"timeStamp": "2022-04-22T11:25:03.235-0400",
"userDefinedErrorText": "Failed"
}
]
The issue I am having is that when parse my JSON I am having my
failedForm variable equal [Failed] instead of "Failed".
The following should work:
String jsonString = '''
[
{
"step": "abcd",
"message": {
"ServiceRequest: abc": {
"App Stack Form Exception": {
"Expecting Form": "P",
"Resulting Form": "P"
},
"JAS Response": {
"fs_P": {
"title": "I",
"data": {},
"errors": [
{
"CODE": "799L",
"TITLE": "Error: Invalid Long Address Number",
"ERRORCONTROL": "15",
"DESC": "CAUSE . . . . The long address number entered is not found in the Address Book\\\\u000a Master file (F0101).\\\\u000aRESOLUTION. . Enter a valid long address number.",
"MOBILE": "The long address number entered is not found in the Address Book\\\\u000a Master file (F0101)."
}
],
"warnings": []
},
"stackId": 12,
"stateId": 5,
"rid": "8f4",
"currentApp": "P",
"timeStamp": "2022-04-22:11.25.03",
"sysErrors": []
}
}
},
"timeStamp": "2022-04-22T11:25:03.235-0400",
"userDefinedErrorText": "Failed"
}
]'''
def json = new JsonSlurper().parseText(jsonString)
String value = json[0].userDefinedErrorText
assert value == 'Failed'

JQ Not Taking In Variable Data

I am unsuccessfully trying to add variable data to a json within a ci script. I am attempting to use the --arg VariableName VariableData notation.
For example purposes, I am only passing $date which has already been set earlier in the script. In the outputted JSON, the literal string $date is outputted instead of the variable.
jq --arg date "$date" '.sections[0].builds += [{"title": "Version MyVersion", "timestamp": "$date", "iOS": "My_URL.plist" }]' builds.json > builds1.json
This results in:
{
"title": "MY Title",
"columnCount": 1,
"notes_OFF": "First_Test",
"sections": [
{
"title": "My Title",
"builds": [
{
"title": "Version MyVersion",
"timestamp": "$date",
"iOS": "My_URL.plist"
}
]
}
]
}
Original JSON:
{
"title": "MY Title",
"columnCount": 1,
"notes_OFF": "First_Test",
"sections": [
{
"title": "My Title",
"builds": [
]
}
]
}
What am I doing wrong here?
Replace "$date" with $date in your filter.

Determine depth of object &/or JSON values using PowerShell Loop

I am using an api to gather a list of comments for particular tickets, the tickets have nested comments which are returned from the api like so:
{
"comments": [
{
"text": "test 1",
"comments": [
{
"text": "test 2",
"comments": [
{
"text": "test 3",
"comments":[]
}
]
}
]
}
]
}
The number of child comments can be n for any parent comment. I'm ultimately trying to get the text value for each "comments" tag until the "comments" tag is null.
I thought about making a parent object then trying to append the property search until it returns null.
$n = 1
$exists = $true
while ($exists){
$string = ".comments"
$search = $string * $n
$search = $search.Substring(1)
$m = $i.$search
$commentVal = $m.comments
$textValue = $m.text
$textValue
if ($textValue -ne ''){
$comments += $textValue
}
if ($commentVal){
$exists = $true
}else{
$exists = $false
}
$n++
}
This does work but only for one iteration. i.e. if $search = "comments.comments" $i.$search does not work, but $search = "comments"; $i.$search does work.
Here's a solution for you that converts the response to an object and recurses on the comments property:
$rawJson = #'
{
"comments": [
{
"text": "test 1",
"comments": [
{
"text": "test 2",
"comments": [
{
"text": "test 3",
"comments":[]
}
]
}
]
}
]
}
'#
$jsonObj = $rawJson | ConvertFrom-Json
$comment = $jsonObj.Comments
$allComments = while ($null -ne $comment) {
$comment.text
$comment = $comment.Comments
}
Edit
(a bit of explanation might be helpful)
if $search = "comments.comments" $i.$search does not work, but $search = "comments"; $i.$search does work.
This is expected, if not intuitive. $i.comments tells PowerShell to index on the comments property, and $i.comments.comments tells it to do twice.
Problem is when using a variable like in the case $search = "comments.comments", $search is not expanded; PowerShell will look for the literal property comments.comments.
Try your code on this json:
{
"comments": [
{
"text": "test 1",
"comments": [
{
"text": "test 2",
"comments": [
{
"text": "test 3",
"comments":[]
}
]
}
]
}
],
"comments.comments": [
{
"text": "test 2.0",
"comments": [
{
"text": "i'm not empty"
}
]
}
],
"comments.comments.comments": [
{
"text": "test 3.0",
"comments": [
{
"text": "i'm not empty"
}
]
}
]
}

Use Powershell variable in JSON

I am trying to pass a parameter through a function in powershell but it is not working
Code
function test($test1, $test2)
{
$details = #"
{ "updateDetails": [
{
"customer": "John",
"rank": $test1
},
{
"school": "western",
"address": $test2
}
]
}
"#
return $details
}
test 0 florida
Current issue
{ "updateDetails": [
{
"customer": "John",
"rank":
},
{
"school": "western",
"address": florida
}
]
}
I tried running test but the value 0 is not filled in the details json, florida is filled in correctly. How can I replace the two values. Also how can florida be in string
0 fills in for me, but florida doesn't have quotes, which is invalid JSON.
To make life a little easier, instead building a here-string, consider building an object and converting it to JSON with the built-in cmdlet ConvertTo-Json.
In this example I'll show you how to do it using a hashtable
function test($test1, $test2)
{
$details = #{
"updateDetails"=
#(
#{
"customer" = "John"
"rank" = $test1
},
#{
"school" = "western"
"address" = $test2
}
)
}
return $details | ConvertTo-Json
}
test 0 florida
output
{
"updateDetails": [
{
"customer": "John",
"rank": 0
},
{
"school": "western",
"address": "florida"
}
]
}
Your code is perfectly fine. I ran your example and it worked as expected. Maybe you missed updating the function. Close the shell and then try again.
To include "florida" as string you could simply add quotes around the variable "$test2", or even safer: Use ConvertTo-Json to output a properly quoted and escaped JSON string:
function test {
param ([int]$rank, [string]$address)
return #"
{ "updateDetails": [
{
"customer": "John",
"rank": $rank
},
{
"school": "western",
"address": $(ConvertTo-Json $address)
}
]
}
"#
}
test 0 florida

ARM Template DSC: configuration does not 'see' protectedSettings.configurationArguments

I need to protect a DSC configuration parameter ([pscredential]RegistrationKey), so I have put it under "settings.protectedSettings.configurationData" thus:
"protectedSettings": {
"configurationArguments": {
"RegistrationKey": {
"UserName": "PLACEHOLDER_DONOTUSE",
"Password": "[parameters('dscAutomationRegistrationKey')]"
}
},
"configurationUrlSasToken": "[parameters('artifactsLocationSasToken')]"
}
I get the error:
"VM has reported a failure when processing extension 'Microsoft.Powershell.DSC'. Error message: \"The DSC Extension failed to execute: Mandatory
parameter RegistrationKey is missing.
If I move RegistrationKey out of "settings.protectedSettings.configurationArguments", into "settings.configurationArguments", it works, therefore, I assume there is nothing wrong with the syntax, so I believe it is to do with PsDscAllowPlainTextPassword = $true that wasn't included in the DSC configuration.
(I tried to include the configuration block in the PS1 file, but this threw an error, suggesting this can't be done)
I have now written a configurationdata .psd1 file, containing the following:
$ConfigData = #{
AllNodes = #(
#{
NodeName = "*"
PsDscAllowPlainTextPassword = $true
}
)
}
and referenced it in settings.configurationdata.url.
This now results in the same error as before: VM has reported a failure...
The ARM template is called from PowerShell:
$oAutomationAccount = Get-AzureRmAutomationAccount -ResourceGroupName $AAresourceGroupName -Name $AutomationAccountName
$RegistrationInfo = $oAutomationAccount | Get-AzureRmAutomationRegistrationInfo
$DscRegKeyString = $RegistrationInfo.PrimaryKey
$ssDscAutomationRegistrationKey = (ConvertTo-SecureString -string $DscRegKeyString -AsPlainText -Force)
#Automation Account EndPoint Uri
$DscRegistrationUrl = $RegistrationInfo.Endpoint
$params = #{
artifactsLocationSasToken = $TemplateSas
vmName = "XYZ"
dscAutomationRegistrationKey = $ssDscAutomationRegistrationKey
dscAutomationRegistrationUrl = $DscRegistrationUrl
dscNodeConfigurationName = "CreateAFolder.localhost"
dscTimeStamp = (Get-Date -f "MM/dd/yyyy H:mm:ss tt") #"MM/dd/yyyy H:mm:ss tt"
dscResourceUrl = $DscResourceUrl
dscConfigurationUrl = $DscConfigurationUrl
dscResourceScript = $DscResourceScriptName
dscResourceFunction = "ConfigureLCMforAAPull"
#sequenceId = $sequenceId
}
New-AzureRmResourceGroupDeployment #params `
-Name "$TemplateInstance-$branch" `
-ResourceGroupName $DeploymentResourceGroup.ResourceGroupName `
-Mode Incremental `
-DeploymentDebugLogLevel All `
-TemplateUri $TemplateUri `
-Verbose
Where I believe the parameters are being passed as the correct types.
What am I doing wrong?
Reference template: https://github.com/Azure/azure-quickstart-templates/blob/master/dsc-extension-azure-automation-pullserver/azuredeploy.json
Updated to use a newer DSC schema:https://blogs.msdn.microsoft.com/powershell/2016/02/26/arm-dsc-extension-settings/
this is the template I've been using for node onboarding:
{
"name": "xxx",
"type": "Microsoft.Compute/virtualMachines/extensions",
"location": "[parameters('location')]",
"apiVersion": "2015-06-15",
"dependsOn": [
"xxx"
],
"properties": {
"publisher": "Microsoft.Powershell",
"type": "DSC",
"typeHandlerVersion": "2.22",
"autoUpgradeMinorVersion": false,
"protectedSettings": {
"Items": {
"registrationKeyPrivate": "[parameters('registrationData')]"
}
},
"settings": {
"ModulesUrl": "https://github.com/Azure/azure-quickstart-templates/raw/master/dsc-extension-azure-automation-pullserver/UpdateLCMforAAPull.zip",
"SasToken": "",
"ConfigurationFunction": "UpdateLCMforAAPull.ps1\\ConfigureLCMforAAPull",
"Properties": [
{
"Name": "RegistrationKey",
"Value": {
"UserName": "PLACEHOLDER_DONOTUSE",
"Password": "PrivateSettingsRef:registrationKeyPrivate"
},
"TypeName": "System.Management.Automation.PSCredential"
},
{
"Name": "RegistrationUrl",
"Value": "xxx",
"TypeName": "System.String"
},
{
"Name": "NodeConfigurationName",
"Value": "xxx",
"TypeName": "System.String"
},
{
"Name": "ConfigurationMode",
"Value": "ApplyAndMonitor",
"TypeName": "System.String"
},
{
"Name": "ConfigurationModeFrequencyMins",
"Value": 15,
"TypeName": "System.Int32"
},
{
"Name": "RefreshFrequencyMins",
"Value": 30,
"TypeName": "System.Int32"
},
{
"Name": "RebootNodeIfNeeded",
"Value": true,
"TypeName": "System.Boolean"
},
{
"Name": "ActionAfterReboot",
"Value": "ContinueConfiguration",
"TypeName": "System.String"
},
{
"Name": "AllowModuleOverwrite",
"Value": true,
"TypeName": "System.Boolean"
},
{
"Name": "Timestamp",
"Value": "MM/dd/yyyy H:mm:ss tt",
"TypeName": "System.String"
}
]
}
}
}
I know its using an old format, but that works so, meh.