php -ews - empty ItemId - exchangewebservices

I am subscribing to EWS push notifications for calendar events and to log notifications.
I am using PHP-EWS: jamesiarmes/php-ews and Symfony 4.1
To subscribe, I'm using this code:
$eventTypes = new NonEmptyArrayOfNotificationEventTypesType();
$eventTypes->EventType[] = NotificationEventTypeType::CREATED_EVENT;
$eventTypes->EventType[] = NotificationEventTypeType::MODIFIED_EVENT;
$eventTypes->EventType[] = NotificationEventTypeType::DELETED_EVENT;
$eventTypes->EventType[] = NotificationEventTypeType::COPIED_EVENT;
$eventTypes->EventType[] = NotificationEventTypeType::MOVED_EVENT;
$folderIDs = new NonEmptyArrayOfBaseFolderIdsType();
$folderIDs->DistinguishedFolderId = new DistinguishedFolderIdType();
$folderIDs->DistinguishedFolderId->Id = DistinguishedFolderIdNameType::CALENDAR;
$pushSubscription = new PushSubscriptionRequestType();
$pushSubscription->FolderIds = $folderIDs;
$pushSubscription->EventTypes = $eventTypes;
$pushSubscription->StatusFrequency = $this->statusFrequency;
$pushSubscription->URL = $this->subscriptionUrl;
$subscribe_request = new SubscribeType();
$subscribe_request->PushSubscriptionRequest = $pushSubscription;
At te present time, when I book a meeting I receive this notification:
{
"SubscriptionId": "xxxxxxxx",
"PreviousWatermark": "xxxxxxxx",
"MoreEvents": "false",
"CreatedEvent": {
"Watermark": "xxxxx",
"TimeStamp": "2018-08-13T13:18:12Z",
"ItemId": "",
"ParentFolderId": ""
},
"ModifiedEvent": [
{
"Watermark": "xxxxxxx",
"TimeStamp": "2018-08-13T13:18:13Z",
"ItemId": "",
"ParentFolderId": ""
},
{
"Watermark": "xxxxxxx",
"TimeStamp": "2018-08-13T13:18:13Z",
"FolderId": "",
"ParentFolderId": ""
}
]
}
My problem is that I don't receive the ´ItemId´ or the ´ParentFolderId´. How can I receive these on the notification or how can I get the meeting that has been created?

Related

Reading the JSON hierarchy (Number of subnodes can be any number) file using Powershell

Reading the JSON hierarchy (Number of subnodes can be any number) file using Powershell.
I could do it for one level but need the same for N number of loops and nested loops
Need result in Tree view, if not possible then Tabular way with the title on top of the root table
Below is the script so far I have developed:
$Filepath = 'C:\Users\Learner\Test2.JSON'
$JsonContent=gc $Filepath | ConvertFrom-Json
$RootNodeCount=$JsonContent.psobject.Properties.name.Count
$RootNodeName=$JsonContent.psobject.Properties.name
foreach ($Name in $RootNodeName) {Echo $Name--> $JsonContent.$Name}
JSON File
{
"foundation": {
"network": {
"resource_group_name": "rg-network-e2",
"name": "nonprodvnet-e2"
},
"diagnostics": {
"resource_group_name": "rg-mgmt-cu",
"storage_account_name": "Sreacnt-e2"
},
"log_analytics": {
"resource_group_name": "rg-mgmt-cu",
"workspace_name": "la-sap-e2"
},
"recovery_vault": {
"resource_group_name": "rg-mgmt-cu",
"name": "rsv-sap-e2"
},
"windows_domain": {
"domain_name": "dmn.local",
"ou_path": "CN=Computers,DC=example,DC=com",
"domain_user": "svc_domainjoin#dmn.local",
"domain_password": "Pwd01"
}
},
"control_flags": {
"enable_boot_diagnostics": true,
"enable_oms": false,
"enable_backup": true,
"windows_domain_join": false
},
"deployment": {
"resource_group": {
"name": "rg-sap-501-e2",
"location": "eastus2"
},
"tags": {
"owner": "for SAP"
},
"os_account": {
"admin_username": "locadm"
},
"proximity_placement_groups": {
"ppg-501": {}
},
"availability_sets": {
"avset-cs-501": {
"ppg_name": "ppg-501"
},
"avset-app-501": {
"ppg_name": "ppg-501"
},
"avset-db-501": {
"ppg_name": "ppg-501"
}
},
"load_balancers": {
"ilb-sap-501": {
"dv2ascs": {
"ip_address": "192.0.18.20",
"probe_port": 62000,
"subnet": "app"
},
"dv2-ers": {
"ip_address": "192.0.18.21",
"probe_port": 62102,
"subnet": "app"
}
},
"ilb-db-501": {
"dv2-hana": {
"ip_address": "192.0.17.12",
"probe_port": 62503,
"subnet": "db"
}
}
},
"server_groups": {
"ascs": {
"os_type": "linux",
"sku": "Standard_E4s_v3",
"availability_set": "avset-cs-501",
"backup_policy": "sap",
"ppg_name": "ppg-501",
"lb_refs": [
"dv2-ascs",
"dv2-ers"
],
"os_disk_size": "30",
"enable_accelerated_networking": true,
"hosts": {
"vcs501-01": {
"nics": [
[
"192.0.18.18"
]
]
},
"vcs501-02": {
"nics": [
[
"192.0.18.19"
]
]
}
},
"subnet": "app",
"image_details": {
"resource_id": null,
"marketplace_reference": {
"publisher" : "SUSE",
"offer" : "sles-sap-15-sp1",
"sku" : "gen1",
"version": "latest"
}
},
"disks": [
{
"name": "usrsap",
"disk_size": "128",
"number_of_disks": 1
}
]
},
"apps": {
"type": "app_linux",
"os_type": "linux",
"sku": "Standard_E4s_v3",
"availability_set": "avset-app-501",
"backup_policy": "sap",
"ppg_name": "ppg-501",
"enable_accelerated_networking": true,
"os_disk_size": "30",
"hosts": {
"vas501-01": {
"nics": [
[
"192.0.18.16",
"192.0.18.26"
]
]
},
"vas501-02": {
"nics": [
[
"192.0.18.17",
"192.0.18.27"
]
]
}
},
"subnet": "app",
"image_details": {
"resource_id": null,
"marketplace_reference": {
"publisher" : "SUSE",
"offer" : "sles-15-sp1",
"sku" : "gen1",
"version": "latest"
}
},
"disks": [
{
"name": "usrsap",
"disk_size": "128",
"number_of_disks": 1
}
]
},
"hana": {
"os_type": "linux",
"sku": "Standard_E32s_v3",
"availability_set": "avset-db-501",
"backup_policy": "sap",
"ppg_name": "ppg-501",
"os_disk_size": "30",
"subnet": "db",
"lb_refs": [
"dv2-hana"
],
"hosts": {
"vhs501-01": {
"nics": [
[
"192.0.17.10"
]
]
},
"vhs501-02": {
"nics": [
[
"192.0.17.11"
]
]
}
},
"image_details": {
"resource_id": null,
"marketplace_reference": {
"publisher" : "SUSE",
"offer" : "sles-sap-15-sp1",
"sku" : "gen1",
"version": "latest"
}
},
"disks": [
{
"name": "usrsap",
"disk_size": "128",
"number_of_disks": 1
},
{
"name": "hanashared",
"disk_size": "128",
"number_of_disks": 1
},
{
"name": "hanadata",
"disk_size": "128",
"number_of_disks": 3
},
{
"name": "hanalog",
"disk_size": "128",
"number_of_disks": 2
},
{
"name": "hanabackup",
"disk_size": "512",
"number_of_disks": 1
}
]
}
}
}
}
You are not really reading a Json file but actually the hierarchy of a PowerShell object which might hold a lot of (.Net) object types but in this case it is limited by the original Json structure which only consists out of three major types:
Arrays, containing multiple child objects
PSCustomObjects (unless you use the ConvertFrom-Json -AsHashTable parameter), containing child objects assigned to a specific name.
Primitives (including strings), which is basically an object ("leaf") without children.
To best way to read through a hierarchic structure of an unknown depth is to use a recursive function, meaning a function that calls itself. To give you an example for your specific question:
Function Show-Object ($Object, $Depth = 0, $Name) {
$Indent = if ($Depth++) { " " * ($Depth - 2) }
if ($Object -is [Array]) {
If ($Name) { "$Indent$Name =" }
foreach ($Item in $Object) {
Show-Object $Item $Depth
}
}
elseif ($Object -is [PSCustomObject]) {
If ($Name) { "$Indent$Name =" }
foreach ($Name in $Object.PSObject.Properties.Name) {
Show-Object $Object.$Name $Depth $Name
}
}
else {
if ($Name) { "$Indent$Name = $Object" } else { "$Indent$Object" }
}
}
As you can see, where the structure might any child objects (in case of an [Array] or an [PSCustomObject]), the Show-Object function is calling itself with a child object as the new input object, and some additional parameters as to e.g. keep track of the current $Depth.
You can call the function simply like:
Show-Object $JsonContent
Or export it to a file like:
Show-Object $JsonContent | Out-File .\text1.txt
For your $JsonContent it will result in:
foundation =
network =
resource_group_name = rg-network-e2
name = nonprodvnet-e2
diagnostics =
resource_group_name = rg-mgmt-cu
storage_account_name = Sreacnt-e2
log_analytics =
resource_group_name = rg-mgmt-cu
workspace_name = la-sap-e2
recovery_vault =
resource_group_name = rg-mgmt-cu
name = rsv-sap-e2
windows_domain =
domain_name = dmn.local
ou_path = CN=Computers,DC=example,DC=com
domain_user = svc_domainjoin#dmn.local
domain_password = Pwd01
control_flags =
enable_boot_diagnostics = True
enable_oms = False
enable_backup = True
windows_domain_join = False
deployment =
resource_group =
name = rg-sap-501-e2
location = eastus2
tags =
owner = for SAP
os_account =
admin_username = locadm
proximity_placement_groups =
ppg-501 =
availability_sets =
avset-cs-501 =
ppg_name = ppg-501
avset-app-501 =
ppg_name = ppg-501
avset-db-501 =
ppg_name = ppg-501
load_balancers =
ilb-sap-501 =
dv2ascs =
ip_address = 192.0.18.20
probe_port = 62000
subnet = app
dv2-ers =
ip_address = 192.0.18.21
probe_port = 62102
subnet = app
ilb-db-501 =
dv2-hana =
ip_address = 192.0.17.12
probe_port = 62503
subnet = db
server_groups =
ascs =
os_type = linux
sku = Standard_E4s_v3
availability_set = avset-cs-501
backup_policy = sap
ppg_name = ppg-501
lb_refs =
dv2-ascs
dv2-ers
os_disk_size = 30
enable_accelerated_networking = True
hosts =
vcs501-01 =
nics =
192.0.18.18
vcs501-02 =
nics =
192.0.18.19
subnet = app
image_details =
resource_id =
marketplace_reference =
publisher = SUSE
offer = sles-sap-15-sp1
sku = gen1
version = latest
disks =
name = usrsap
disk_size = 128
number_of_disks = 1
apps =
type = app_linux
os_type = linux
sku = Standard_E4s_v3
availability_set = avset-app-501
backup_policy = sap
ppg_name = ppg-501
enable_accelerated_networking = True
os_disk_size = 30
hosts =
vas501-01 =
nics =
192.0.18.16
192.0.18.26
vas501-02 =
nics =
192.0.18.17
192.0.18.27
subnet = app
image_details =
resource_id =
marketplace_reference =
publisher = SUSE
offer = sles-15-sp1
sku = gen1
version = latest
disks =
name = usrsap
disk_size = 128
number_of_disks = 1
hana =
os_type = linux
sku = Standard_E32s_v3
availability_set = avset-db-501
backup_policy = sap
ppg_name = ppg-501
os_disk_size = 30
subnet = db
lb_refs =
dv2-hana
hosts =
vhs501-01 =
nics =
192.0.17.10
vhs501-02 =
nics =
192.0.17.11
image_details =
resource_id =
marketplace_reference =
publisher = SUSE
offer = sles-sap-15-sp1
sku = gen1
version = latest
disks =
name = usrsap
disk_size = 128
number_of_disks = 1
name = hanashared
disk_size = 128
number_of_disks = 1
name = hanadata
disk_size = 128
number_of_disks = 3
name = hanalog
disk_size = 128
number_of_disks = 2
name = hanabackup
disk_size = 512
number_of_disks = 1

Read JSON File: I want to read the content of external JSON file and use as input

JSON File:
I want to read the content of external JSON file
{
"article": {
"article_doi": "13.032020/11032020",
"sage_article_id": 1,
"peer_review_id":"PRV1",
"article_title": "WF2-only with CBP",
"journal_id": "HIJ",
"article_type": "Article",
"author_role": "Author",
"submission_date": "2020-03-13",
"article_acceptance_date": "2020-03-13",
"SMART_entry_date": "2020-03-12",
"first_article_export_date": "2020-03-13",
"subscription_published_date": "",
"oa_published_date":""
},
"authors": [
{
"email": "raman.kumar#aptaracorp.com",
"title": "",
"first_name": "Raman",
"last_name": "Kumar",
"country_code": "AUS",
"orcid": "",
"institution_ringgold_id": "4615",
"institution_ringgold_name": "Imperial College London",
"author_sequence_number": 1,
"corresponding_author": true
},
{
"email": "authorname2#aptaracorp.com",
"title": "",
"first_name": "Prateek",
"last_name": "Sharma",
"country_code": "AUS",
"orcid": "",
"institution_ringgold_id": "",
"institution_ringgold_name": "",
"author_sequence_number": 2,
"corresponding_author": false
}
],
"oa_requester": {
"email": "pavan.kumar#aptaracorp.com",
"title": "",
"first_name": "Pavan",
"last_name": "Kumar",
"organisation": "Requestor Organisation",
"oa_requested_date": "2018-10-17"
},
"societies": [
{
"society_name": "S1",
"society_membership_number":"SMN1"
},
{
"society_name": "S2",
"society_membership_number":"SMN2"
}
],
"article_process_info": {
}
}
File inFile = new File("TestData.json");
StringBuilder targetString = new StringBuilder();
FileReader fr = new FileReader(inFile);
// #SuppressWarnings("resource")
BufferedReader br = new BufferedReader(fr);
String s= null;
while ((s = br.readLine()) != null) {
targetString.append(s);
}
WebElement element = driver.findElement(By.id("request_json"));
body.sendKeys(targetString);
String sCurrentLine=null;
br = new BufferedReader(new FileReader(inFile));
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
}

Getting inventory contexts of Steam users

A stack overflow answer explains how to retrieve a user's public inventory
http://steamcommunity.com/profiles/<PROFILEID>/inventory/json/<APPID>/<CONTEXTID>
I read that context ID must be set as 2 to find items for most games, but this is not always the case. Is there any official API to find a user's inventory contexts? steamapis.com already has a paid API which performs this task:
{
"steamID": {
"universe": 1,
"type": 1,
"instance": 1,
"accountid": 78261062
},
"name": "PEPZ",
"onlineState": "online",
"stateMessage": "Online",
"privacyState": "public",
"visibilityState": "3",
"avatarHash": "5b702b331ddeb928225ad562a3e729aecd191b9a",
"vacBanned": false,
"tradeBanState": "None",
"isLimitedAccount": false,
"customURL": "pepzwee",
"memberSince": "2011-02-21T22:00:00.000Z",
"location": "Estonia",
"realName": "SteamApis.com Developer",
"summary": "",
"groups": [
{
"universe": 1,
"type": 7,
"instance": 0,
"accountid": 28077004
},
...
],
"primaryGroup": {
"universe": 1,
"type": 7,
"instance": 0,
"accountid": 28077004
},
"contexts": {
"440": {
"appid": 440,
"name": "Team Fortress 2",
"icon": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/440/e3f595a92552da3d664ad00277fad2107345f743.jpg",
"link": "http://steamcommunity.com/app/440",
"asset_count": 11,
"inventory_logo": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/440/e613d1d46de26ea755105b898cc8830d305353f3.png",
"trade_permissions": "FULL",
"load_failed": 0,
"rgContexts": {
"2": {
"asset_count": 11,
"id": "2",
"name": "Backpack"
}
}
},
...
}
}
Where "rgContexts" contains inventory context for each game.
I found out with some inspect element work, that there is a script tag available with the exact information you need. This is an example of my profile:
var g_rgWalletInfo = {"success":false};
var g_bInventoryIsInModalDialog = false;
var g_bIsInMarketplace = false;
UserYou.SetSteamId( '76561199033382814' );
var g_rgAppContextData = {"753":{"appid":753,"name":"Steam","icon":"https:\/\/cdn.cloudflare.steamstatic.com\/steamcommunity\/public\/images\/apps\/753\/135dc1ac1cd9763dfc8ad52f4e880d2ac058a36c.jpg","link":"https:\/\/steamcommunity.com\/app\/753","asset_count":303,"inventory_logo":"https:\/\/cdn.cloudflare.steamstatic.com\/steamcommunity\/public\/images\/apps\/753\/db8ca9e130b7b37685ab2229bf5a288aefc3f0fa.png","trade_permissions":"FULL","load_failed":0,"store_vetted":"1","rgContexts":{"6":{"asset_count":303,"id":"6","name":"Community"}}},"730":{"appid":730,"name":"Counter-Strike: Global Offensive","icon":"https:\/\/cdn.cloudflare.steamstatic.com\/steamcommunity\/public\/images\/apps\/730\/69f7ebe2735c366c65c0b33dae00e12dc40edbe4.jpg","link":"https:\/\/steamcommunity.com\/app\/730","asset_count":61,"inventory_logo":"https:\/\/cdn.cloudflare.steamstatic.com\/steamcommunity\/public\/images\/apps\/730\/3ab6e87a04994b900881f694284a75150e640536.png","trade_permissions":"FULL","load_failed":0,"store_vetted":"1","rgContexts":{"2":{"asset_count":61,"id":"2","name":"Backpack"}}}};
var g_strInventoryLoadURL = 'https://steamcommunity.com/id/stoplookingatmyid/inventory/json/';
$J( function() {
UserYou.LoadContexts( g_rgAppContextData );
} );
$J( function() {
var bHasPendingGifts = false;
InitInventoryPage( bHasPendingGifts, -1, false );
});
var g_bInClient = false;
var g_bInChinaRealm = false;
var g_bViewingOwnProfile = false;
var g_bMarketAllowed = false;
var g_strLanguage = 'english';
var g_strCountryCode = "US";
var g_strProfileURL = 'https://steamcommunity.com/id/stoplookingatmyid';
Some of this data is junk, but g_rgAppContextData is exactly what you need in JSON format, and it just needs to be parsed if your programming language of choice. In this example, 753 is the app id of Steam, with 6 being the context id, and 730 is CSGO'S app id, with 2 as the context id. with This data won't be present if the user has a private steam inventory.

Dynamically Parsing JSON with Groovy

I have a JSON document pulled back from a support system API. With my code, I want to pull out the pre-configured fields dynamically, presuming that the JSON may have more or fewer of the desired fields when my program calls the API.
I have some code that works, though it seems very convoluted and inefficient.
Here is a snippet of the pieces of JSON that I'm interested in:
{
"rows": [
{
"assignee_id": 1,
"created": "2017-01-25T14:13:19Z",
"custom_fields": [],
"fields": [],
"group_id": 2468,
"priority": "Low",
"requester_id": 2,
"status": "Open",
"subject": "Support request",
"ticket": {
"description": "Ticket descritpion",
"id": 1000,
"last_comment": {
"author_id": 2,
"body": "Arbitrary text",
"created_at": "2017-02-09T14:21:38Z",
"public": false
},
"priority": "low",
"status": "open",
"subject": "Support request",
"type": "incident",
"url": "Arbitrary URL"
},
"updated": "2017-02-09T14:21:38Z",
"updated_by_type": "Agent"
},
{
"assignee_id": 1,
"created": "2017-02-09T14:00:18Z",
"custom_fields": [],
"fields": [],
"group_id": 3579,
"priority": "Normal",
"requester_id": 15,
"status": "Open",
"subject": "Change request",
"ticket": {
"description": "I want to change this...",
"id": 1001,
"last_comment": {
"author_id": 20,
"body": "I want to change the CSS on my website",
"created_at": "2017-02-09T14:12:12Z",
"public": true
},
"priority": "normal",
"status": "open",
"subject": "Change request",
"type": "incident",
"url": "Arbitrary URL"
},
"updated": "2017-02-09T14:12:12Z",
"updated_by_type": "Agent"
}
]
}
I have an ArrayList called wantedFields that I build up from a config to define which information I want to pull out from the JSON:
["id","subject","requester_id","status","priority","updated","url"]
The complexity is that data is replicated in the API, and I only want to pull out data once, with a preference for the data in "rows" where applicable. My method for doing this is below. It feels like I'm repeating code but I can't really see how to make this work more efficiently. The JSON is held as "viewAsJson".
def ArrayList<Map<String,Object>> assignConfiguredFields(viewAsJson, wantedFields) {
//Pull out configured fields from JSON and store as Map to write as CSV later
ArrayList<Map<String,Object>> listOfDataToWrite = new ArrayList<Map<String,Object>>()
ArrayList<String> rowKeyList = new ArrayList<String>()
def validationRow = viewAsJson.rows.get(0)
//Compare one row object to config first
validationRow.each { k, v ->
if (wantedFields.contains(k)) {
wantedFields.remove(k)
rowKeyList.add(k)
}
}
ArrayList<String> ticketKeyList = new ArrayList<String>()
def validationTicket = viewAsJson.rows.ticket.get(0)
//Compare one ticket object to config first
validationTicket.each { k, v ->
if (wantedFields.contains(k)) {
wantedFields.remove(k)
ticketKeyList.add(k)
}
}
def rows = viewAsJson.rows
def tickets = viewAsJson.rows.ticket
//Pull matching ticket objects from JSON and store in Map
ArrayList<Map<String,Object>> tickList= new ArrayList<>()
ArrayList<Map<String,Object>> rowList= new ArrayList<>()
rows.each { row ->
Map<String,Object> rowMap = new HashMap<>()
row.each { k, v ->
if(rowKeyList.contains(k))
rowMap.put(k,v)
}
rowList.add(rowMap)
}
tickets.each { ticket ->
Map<String,Object> ticketMap = new HashMap<>()
ticket.each { k, v ->
if(ticketKeyList.contains(k))
ticketMap.put(k, v)
}
tickList.add(ticketMap)
}
for (int i = 0; i < rowList.size(); i++) {
HashMap<String,Object> dataMap = new HashMap<>()
dataMap.putAll(rowList.get(i))
dataMap.putAll(tickList.get(i))
listOfDataToWrite.add(dataMap)
}
println listOfDataToWrite
return listOfDataToWrite
}
I know there should be some validation for if the wantedFields ArrayList is still populated. I've iterated on this code so many times I just forgot to re-add that this time.
I don't know if you still need this code but why not try something like this.
Have a translation map and run each row through it.
Object tranverseMapForValue(Map source, String keysToTranverse, Integer location = 0){
List keysToTranverseList = keysToTranverse.split(/\./)
tranverseMapForValue(source, keysToTranverseList, location)
}
Object tranverseMapForValue(Map source, List keysToTranverse, Integer location = 0){
if(source.isEmpty() || keysToTranverse.isEmpty()){
return null
}
String key = keysToTranverse[location]
if(source[key] instanceof Map){
return tranverseMapForValue(source[key], keysToTranverse, location + 1)
}
else{
return source[key]
}
}
Map translation = [
"ticket.id": "id",
"ticket.subject": "subject",
"requester_id": "requester_id",
"ticket.status": "status",
"priority": "priority",
"updated": "updated",
"ticket.url": "url"
]
List rows = []
json.rows.each{ row ->
Map mapForRow = [:]
translation.each{ sourceKey, newKey ->
mapForRow << [(newKey): tranverseMapForValue(row, sourceKey)]
}
rows.add(mapForRow)
}

How to populate a list inside a collection in JSON format in Windows PowerShell

I'm working on a task, where-in I should invoke a REST Post request in Powershell environment.
Based on google research, I decided to use Invoke-RestMethod cmdlet.
For the POST request, the body should be in JSON format as below.
{
"appid": "sample string 1",
"appName": "sample string 2",
"appType": "sample string 3",
"hostName": "sample string 4",
"userName": "sample string 5",
"password": "sample string 6",
"status": "sample string 7",
"appUri": "sample string 8",
"resourceParams": [
{
"data1": "sample string 1",
"data2": "sample string 2",
"data3": "sample string 3"
},
{
"data1": "sample string 1",
"data2": "sample string 2",
"data3": "sample string 3"
}
],
"Params": [
{
"hostName": "sample string 1",
"ip": "sample string 2"
},
{
"hostName": "sample string 1",
"ip": "sample string 2"
},
{
"hostName": "sample string 1",
"ip": "sample string 2"
}
]
}
Now inorder to populate this json content, I used the code like below
$externalAPP = #{
appId = 1
appName = "test"
appType = 1
userName = "Administrator#test"
password = "xxxxxxxx"
status = "1"
resourceParams = #{
data1 = "test"
data2 = "test"
data3 = "test"
}
Params = {#{
hostName = "ex1"
ipAddress = "192.1.1.1"
}
#{
hostName = "ex2"
ipAddress = "192.1.1.2"
}
}
}
$json = $externalAPP | ConvertTo-Json
Write-Host $json
Above code works fine, if there is only one item in resourceParams & Params. If there is more than one, the format is something different as follows.
Sample Ouptut
"appName": "test",
"esxiParams": {
"Attributes": [
],
"File": "C:\\Users\\kspviswa\\Desktop\\Demo3\\test.ps1",
"IsFilter": false,
"IsConfiguration": false,
"Module": null,
"StartPosition": {
"Content": "{#{\r\n\t\thostName = \"ex1\"\r\n\t\tipAddress = \"192.
"\r\n\t}\r\n\t#{\r\n\t\thostName = \"ex2\"\r\n\t\tipAddress = \"192.1.1.2\"\r\n\t}\r\n\t}",
"Type": 19,
"Start": 292,
"Length": 117,
"StartLine": 14,
"StartColumn": 15,
"EndLine": 22,
"EndColumn": 3
},
"DebuggerHidden": false,
"Ast": {
"ParamBlock": null,
"BeginBlock": null,
"ProcessBlock": null,
"EndBlock": "#{\r\n\t\thostName = \"ex1\"\r\n\t\tipAddress = \"192.1.1.1\"\r\
\n\t#{\r\n\t\thostName = \"ex2\"\r\n\t\tipAddress = \"192.1.1.2\"\r\n\t}",
"DynamicParamBlock": null,
"ScriptRequirements": null,
"Extent": "{#{\r\n\t\thostName = \"ex1\"\r\n\t\tipAddress = \"192.1.1.1\"\r\n
n\t#{\r\n\t\thostName = \"ex2\"\r\n\t\tipAddress = \"192.1.1.2\"\r\n\t}\r\n\t}",
"Parent": "{#{\r\n\t\thostName = \"ex1\"\r\n\t\tipAddress = \"192.1.1.1\"\r\n
n\t#{\r\n\t\thostName = \"ex2\"\r\n\t\tipAddress = \"192.1.1.2\"\r\n\t}\r\n\t}"
}
},
"password": "xxxx"
}
What is the mistake I have done? I had tried several websites seeking for the answer. All the examples were for flattened container. I want to understand, how to populate list inside a container.
In JSON, [] means list or array - so instead of enclosing the Params value in {} (which makes it a scriptblock), use the array subexpression operator #() instead:
$externalAPP = #{
appId = 1
appName = "test"
appType = 1
userName = "Administrator#test"
password = "xxxxxxxx"
status = "1"
resourceParams = #(
#{
data1 = "test"
data2 = "test"
data3 = "test"
}
)
Params = #(
#{
hostName = "ex1"
ipAddress = "192.1.1.1"
},
#{
hostName = "ex2"
ipAddress = "192.1.1.2"
}
)
}
Which will produce:
{
"userName": "Administrator#test",
"appType": 1,
"appId": 1,
"Params": [
{
"ipAddress": "192.1.1.1",
"hostName": "ex1"
},
{
"ipAddress": "192.1.1.2",
"hostName": "ex2"
}
],
"resourceParams": [
{
"data1": "test",
"data2": "test",
"data3": "test"
}
],
"status": "1",
"appName": "test",
"password": "xxxxxxxx"
}