Parsing var list of dictionaries in json to Powershell - the term convert-fromjson is not recognized.....

I’m not too sure if this is an issue with how I’m parsing to the PS script… or the PS script accepting the arg in json hence posting here sorry…
I have a var that consists of a list of dictionaries. In my play I have a task that runs a Powershell script and the var is parsed in json as an argument.

Below are relevant snippets…

dns_test:

  • { zone: ‘test.com’, name: ‘test1’, target: ‘1.2.3.4’, type: ‘ARecord’, state: ‘present’ }

  • { zone: ‘test.com’, name: ‘test2’, target: ‘5.6.7.8’, type: ‘ARecord’, state: ‘present’ }

  • name: Configure DNS
    script: files/dns.ps1 {{ dns_test | quote | to_json }}

I’ve tested that I can output dns_test in json format without issues (also tried with filter to_nice_json).
I’ve also tested the Powershell script - this was importing the json file and then using PS cmdlet convert-fromjson - script works without issues when importing the json file (please note I only want to parse the var in json format).

I’ve become stuck when parsing the var in json format to the PS script as an arg - the script expects the arg.

I get the below error when running the play…

“stderr”: “convert-fromjson : The term ‘convert-fromjson’ is not recognized as the name \r\nof a cmdlet, function, script file, or operable program. Check the spelling of \r\nthe name, or if a path was included, verify that the path is correct and try \r\nagain.\r\nAt C:\Users\ansible\AppData\Local\Temp\ansible-tmp-1550181100.61-21894512685493\r\n9\dns.ps1:27 char:9\r\n+ $json | convert-fromjson\r\n+ ~~~~~~~~~~~~~~~~\r\n + CategoryInfo : ObjectNotFound: (convert-fromjson:String) , Co \r\n mmandNotFoundException\r\n + FullyQualifiedErrorId : CommandNotFoundException\r\n \r\n\r\n”,

63
“stderr_lines”: [

64
"convert-fromjson : The term ‘convert-fromjson’ is not recognized as the name ",

65
"of a cmdlet, function, script file, or operable program. Check the spe…

The line in the PS script for the arg is…

$json = $args[0] | convert-fromjson

I’ve also tried parsing the var without using the filter of “quote”…

script: files/dns.ps1 {{ dns_test | to_json }}

When leaving out the “quote” filter I get a different error…

{
“stderr_lines”: [
“At line:1 char:99”,
“+ … \ansible-tmp-1550180925.73-263417387907116\dns.ps1 [{"state": "presen …”,
“+ ~”,
“Unexpected token ‘:’ in expression or statement.”,
“”,
“At line:1 char:214”,
“+ … , "zone": "test.com”, "target": "1.2.3.4"}, {"state": "presen …",
“+ ~”,
“Unexpected token ‘:’ in expression or statement.”,

The server the PS script is running on is Windows 2012 R2 - PS version 5.1
I’m running Ansible 2.7.1

Thanks for reading and any assistance offered.

The cmdlet is ConvertFrom-Json not Convert-FromJson, https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertfrom-json?view=powershell-6.

Thanks

Jordan

Argh! I’d been staring at the code way too long! I had correct syntax commented out. Thanks Jordan… getting a bit further now.

Now troubleshooting this…

“stderr_lines”: [

64
“ConvertFrom-Json : Invalid JSON primitive: .”,

65
“At C:\Users\ansible\AppData\Local\Temp\ansible-tmp-1550198625.18-19959264060901”,

66
“5\dns.ps1:27 char:9”,

67
“+ $json | ConvertFrom-Json”,

68
“+ ~~~~~~~~~~~~~~~~”,

69
" + C…

The trouble with this approach is that the quotes in the JSON string will be confusing the Windows argument parser and $args[0] won’t be the whole JSON string causing the cmdlet to fail. What you are better off doing is to base64 encode the json string then read that back in your script, or create a module and pass the data as module options. To go the base64 way you can do something like;

`

  • script: files/dns.ps1 {{ dns_test | to_json | b64encode }}

`

Then in your script you can do the following to read the JSON back;

`
$json_string = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($args[0]))

$json = ConvertFrom-Json -InputObject $json_string

`

Base64 is good for these problems as the characters don’t need to be escaped and can easily be seen as 1 argument in Windows.

Thanks

Jordan

Thank you so much for your assistance - this did the trick! Why won’t $args[0] be the whole JSON string? And how do you know when to encode?

I’ve hit some issues on the PS side now I’ll work through that’s not related to Ansible (script works fine when running through the loop in debug mode - all the DNS records are created), however if the script is run without stepping through the code (using PS ISE) only the first entry in $json is created (same result when running via Ansible). I put a sleep of 10 seconds in the loop and it created the second entry but no cigar for the 3rd onwards - haven’t encountered this before.

I know the json and script is fine though as I also tweaked the above for testing and parsed $json_string to a json file - I read this back into the script and debugged with it.