0

I have script which accepts two parameters, a string arg1 and a hashtable arg2:

Script.ps1

Param(
        [string]$arg1,
        [hashtable]$arg2,
    )
Write-Host "@$(ConvertTo-Json $arg2)"

How can I pass a dictionary from powershell into this script, by calling it such that it runs in a separate process.

Call.ps1

$d = @{a="bla"} 
$s = "@$((ConvertTo-Json $a -Compress) -replace ':','=')"
powershell -File Script.ps1 "-arg2 $s" # We need another process (no access to the variables in this script)

I don't know what I am doing wrong (see this question), but this does not work. Or is there another

Gabriel
  • 8,990
  • 6
  • 57
  • 101
  • 1
    Can you change the parameter type to `string`? Then it would be quite easy to convert to and from JSON without being "dirty". – zett42 Dec 20 '19 at 13:59

2 Answers2

0

By doing:

$s = "@$((ConvertTo-Json $a -Compress) -replace ':','=')"

You convert the value of hashtable to string. So you should use:

param(
[string]$arg1
[string]$arg2
)

Now you can convert $arg2 to JSON quite easily.

Wasif
  • 14,755
  • 3
  • 14
  • 34
0

Been fiddling with this and finally came up with this:

Script.ps1

Param(
    [string]$arg1,
    [string]$arg2
)

$scriptBlock = [scriptblock]::Create($arg2)
# check that $arg2 contains no other Powershell commands
# see: https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.scriptblock.checkrestrictedlanguage?view=pscore-6.2.0
$scriptBlock.CheckRestrictedLanguage([string[]]@(), [string[]]@(), $false)
# execute it to create the hashtable
$ht = ( & $scriptBlock )

Write-Host "$(ConvertTo-Json $ht)"

Call.ps1

$d = @{'a'="bla"} 

# convert to JSON, replace ':' by '=' and escape the quotes with a backslash
$s = '@{0}' -f ((ConvertTo-Json $d -Compress) -replace ':','=' -replace '"', '\"')

powershell -File Script.ps1 -arg2 $s
Theo
  • 57,719
  • 8
  • 24
  • 41