0
votes

I'm trying to connect to our McAfee ESM using a PowerShell API call.

The API calls for parameters to be submitted to it in JSON form. I've tried to use the PowerShell ConvertTo-Json commandlet with a hash and i've also tried to use just straight json text.

$headers = @{
    'Content-Type' = 'application/json'
    'Accept' = 'application/json'
    }    


$body_json = {"datasource": {
        "parentId": "123456789000",
        "name": "(name)",
        "id": "(value)",
        "typeId": 0,
        "childEnabled": false,
        "childCount": 0,
        "childType": 0,
        "ipAddress": "(ipAddress)",
        "zoneId": 0,
        "url": "(url)",
        "enabled": false,
        "idmId": 123456789000,
        "parameters": [{
            "key": "(key)",
            "value": "(value)"
        }]
    }}

$body_json_converted = @{
      datasource = @(
        @{
           parentId = 123456789000
           name = "name"
           id = "value"
           typeId = 0
           childEnabled = $false
           childCount = 0
           childType = 0
           ipAddress = "ipAddress"
           zoneId = 0
           url = "url"
           enabled = $false
           idmId = 123456789000
           parameters = @( @{
                key = "key"
                value = "value"
           })
    })
} | ConvertTo-Json -Depth 4


Invoke-RestMethod $url -Body $body_json_converted -Method Post -Headers $headers

Invoke-WebRequest $url -Body $body_json -Method Post -Headers $headers

I expect to get a result back saying that it has sucessfully created the data source or to tell me that i'm missing a parameter of some sort. What i'm actually getting is

Invoke-RestMethod : Cannot deserialize instance of [ERROR] 'com.mcafee.siem.api.data.datasource.EsmDataSourceDetail' out of START_ARRAY [ERROR] token

This appears to be almost an identical issue to this user:

Powershell Invoke-Webrequest w/ JSON Body - Can not deserialize...? but the user doesn't explain how he/she fixed it.

Edit: The McAfee ESM has an API help page for the particular API call to add a data source. All of the other API calls are documented the same. Here is the majority of the content from it:

Description Add a data source.

Parameters datasource Type: EsmDataSourceDetail Description: datasource to add Return Value ("return" JSON root element IS returned) Type: EsmDataSourceId Description: datasource id of the datasource that was just added Example REST Call (with JSON if applicable) https://siem/rs/esm/dsAddDataSource

Example JSON Content:

{"datasource": {
    "parentId": {"id": 123456789000},
    "name": "(name)",
    "id": {"id": "(id)"},
    "typeId": {"id": 0},
    "childEnabled": false,
    "childCount": 0,
    "childType": 0,
    "ipAddress": "(ipAddress)",
    "zoneId": 0,
    "url": "(url)",
    "enabled": false,
    "idmId": 123456789000,
    "parameters": [{
        "key": "(key)",
        "value": "(value)"
    }]
}}
1
How are you sure the format of your JSON is correct? Do you have reference documentation you can share regarding the format for the body of the posted content?Jason Shave
What happens if you add -ContentType 'application/json' to the Invoke-RestMethodTheo
I added the documentation for the API call to the original post Jason. At the top of the script i have the $headers variable which includes the ContentType of 'application/json'.shawnzzzy

1 Answers

0
votes

Looks like your $body_json_converted is wrong based on your JSON example.

You've specified datasource as an array with a table in it. In the other two examples its just a table. parentId also looks like it should be a table.

[ordered] just makes it easier to compare.

So, I would try:

$body_json_converted = @{
      datasource = [ordered]@{
           parentId = @{
               id = 123456789000
           }
           name = "name"
           id = "value"
           typeId = 0
           childEnabled = $false
           childCount = 0
           childType = 0
           ipAddress = "ipAddress"
           zoneId = 0
           url = "url"
           enabled = $false
           idmId = 123456789000
           parameters = @( @{
                key = "key"
                value = "value"
           })
    }
} | ConvertTo-Json -Depth 4

Output from above:

PS > $body_json_converted
{
  "datasource": {
    "parentId": {
      "id": 123456789000
    },
    "name": "name",
    "id": "value",
    "typeId": 0,
    "childEnabled": false,
    "childCount": 0,
    "childType": 0,
    "ipAddress": "ipAddress",
    "zoneId": 0,
    "url": "url",
    "enabled": false,
    "idmId": 123456789000,
    "parameters": [
      {
        "key": "key",
        "value": "value"
      }
    ]
  }
}

If you'd prefer you can also just add the JSON directly instead of converting:

$jsonObject = 
@"
{"datasource": {
    "parentId": {"id": 123456789000},
    "name": "(name)",
    "id": {"id": "(id)"},
    "typeId": {"id": 0},
    "childEnabled": false,
    "childCount": 0,
    "childType": 0,
    "ipAddress": "(ipAddress)",
    "zoneId": 0,
    "url": "(url)",
    "enabled": false,
    "idmId": 123456789000,
    "parameters": [{
        "key": "(key)",
        "value": "(value)"
    }]
}}
"@