2

I'm trying to convert JSON into hashtable in 5.1 version of Powershell. But the output is coming as an object again for FieldMapping key. Can we get the key value pairs for FieldMapping key?

We have ConvertFrom-Json -AsHashtable in 7.1 version. Ideally trying to get the same o/p in 5.1 as well. What can I try next?

My json:

$json = @'
[
  {
    "EntityType": "IP",
    "FieldMapping": [
      {
        "ColumnName":  "FileHashCustomEntity",
        "Identifier":  "Address"
      }
    ]
  }
]
'@

My code:

$entities = $json | ConvertFrom-Json 
$ht2 = @{}
$hash = $entities.psobject.properties | Foreach { $ht2[$_.Name] = $_.Value }
Write-Host $ht2

My output:

Key   : EntityType
Value : IP
Name  : EntityType
    
Key   : FieldMapping
Value : {@{ColumnName=FileHashCustomEntity; Identifier=Address}}
Name  : FieldMapping

Expected output:

Key   : EntityType
Value : IP
Name  : EntityType

Key   : FieldMapping
Value : {FileHashCustomEntity}
Name  : FieldMapping
3
  • Try : Foreach { $ht2[$_.Name] = $_.Value | Format-Table} Commented Jan 20, 2023 at 10:07
  • Hi jdweng.. tried using the above suggested code. But got o/p in this format: Key : EntityType Value : Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Name : EntityType Key : FieldMapping Value : {Microsoft.PowerShell.Commands.Internal.Format.FormatStartData, Microsoft.PowerShell.Commands.Internal.Format.GroupStartData, Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData, Microsoft.PowerShell.Commands.Internal.Format.GroupEndData…} Name : FieldMapping Commented Jan 20, 2023 at 10:22
  • 1
    You need to do this recursively and treat arrays specifically. If this works for you, we can close as duplicate: stackoverflow.com/a/34383413/7571258 Commented Jan 20, 2023 at 10:22

3 Answers 3

1

Right now you're ending up with a top-level hashtable containing custom objects as entries - what you need to do is convert every object in the resulting object hierarchy recursively.

Here's a simple function that does that:

function Convert-PSCToHashTable
{
  param(
    $InputObject, 
    [int]$Depth = 5
  )

  if($Depth -gt 0){
    if($InputObject -is [System.Collections.IList]){
      return @($InputObject |ForEach-Object {Convert-PSCToHashTable $_ -Depth ($Depth - 1)})
    }

    if($InputObject.psobject.BaseObject -is [System.Management.Automation.PSCustomObject]){
      $ht = @{}
      foreach($prop in $InputObject.psobject.Properties){
        $ht[$prop.Name] = Convert-PSCToHashTable $prop.Value -Depth ($Depth - 1)
      }
      return $ht
    }
  }

  return $InputObject
}

Now you can do:

$object = ConvertFrom-Json $json
$hashtable = Convert-PSCToHashTable $object

$hashtable['FieldMapping']['ColumnName'] # "FileHashCustomEntity"
Sign up to request clarification or add additional context in comments.

3 Comments

tried to use the above function to convert json to hashtable. I'm trying to send this hashtable to the following command. New-AzSentinelAlertRule -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName -QueryFrequency 1:00:00 -QueryPeriod 1:00:00 -DisplayName "TesS-2" -Kind Scheduled -Query "SecurityAlert | where TimeGenerated == '99'" -Severity Low -TriggerOperator GreaterThan -TriggerThreshold 10 -EntityMapping $hashtable
Facing this error : Invalid data model. [: Invalid length of '0' for 'EntityMappings'. 'EntityMappings' length should be between '1' and '5']
How can I send this hashtable to EntityMapping parameter ? Can you please help me out ?
0

You can use what's already built-in in .NET Framework, the JavaScriptSerializer Class already handles deserialization into Dictionary<string, object>, there is no need to re-invent the wheel.

$json = @'
[
  {
    "EntityType": "IP",
    "FieldMapping": [
      {
        "ColumnName":  "FileHashCustomEntity",
        "Identifier":  "Address"
      }
    ]
  }
]
'@

Add-Type -AssemblyName System.Web

$serializer = [System.Web.Script.Serialization.JavaScriptSerializer]::new()
$result = $serializer.DeserializeObject($json)
$result

# Key          Value
# ---          -----
# EntityType   IP
# FieldMapping {System.Collections.Generic.Dictionary`2[System.String,System.Object]}

$result.GetType()    # object[]
$result[0].GetType() # Dictionary<string, object>
$result[0]['FieldMapping']

# Key        Value
# ---        -----
# ColumnName FileHashCustomEntity
# Identifier Address

$result[0]['FieldMapping'][0]['ColumnName']

# FileHashCustomEntity

Comments

-1

This works. Included debug statements so you can see how the data is organized

$json = @" 
[
 
                              {
 
                                  "EntityType": "IP",
 
                                  "FieldMapping":  [
 
                                                       {
 
                                                           "ColumnName":  "FileHashCustomEntity",
                                                            "Identifier":  "Address"
                                                           
 
                                                       }
 
                                                   ]
 
                              }
 
                          ]
"@
$entities = $json | ConvertFrom-Json 
$entities
$ht2 = [System.Collections.ArrayList]::new()
$newRow = New-Object -TypeName psobject
$newRow | Add-Member -NotePropertyName EntityType -NotePropertyValue $entities.EntityType
foreach($property in $entities.FieldMapping)
{
$property | Format-Table
   $newRow | Add-Member -NotePropertyName ColumnName -NotePropertyValue $property.ColumnName  
   $newRow | Add-Member -NotePropertyName Identifier -NotePropertyValue $property.Identifier
 
}
$ht2.Add($newRow)  | Out-Null

$ht2 | Format-Table

1 Comment

This outputs an ArrayList of PsCustomObjects. Not a Hashtable at all as the OP wants

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.