updating values in JSON using PUT method - json

I have a nested JSON file. I want to update some values with PUT method. I can change some values, but the problem is in the nested values.
$Authorization = "Bearer API-KEY"
$update = [ordered]#{
name = 'ppp'
asset_tag = 'BBB'
custom_fields = #(
[ordered] #{
Mediensatz = #(
[ordered] #{
value = "B2T-XXX"
}
)
}
)
}
$json = $update | ConvertTo-Json -Depth 100
#Write-Host $json
$response = Invoke-RestMethod 'URL' -Method Put -Body $json -ContentType 'application/json' -Headers #{'Authorization' = $Authorization}
My JSON file look like this:
{
"total": 888,
"rows": [
{
"id": 11,
"name": "AAA",
"asset_tag": "CCC",
"model": {
"id": 34,
"name": "TTT"
},
"user_can_checkout": true,
"custom_fields": {
"Mediensatz": {
"field": "lll",
"value": "B2T-YYY",
"field_format": "ANY"
},
"Ueberschreibschutz": {
"field": "lll",
"value": "2019-07-10",
"field_format": "DATE"
}
}
}
I can change the "name" and "asset_tag", but the problem is "value" in custom_fields → Mediensatz → value.
When I try to run my code with Write-Host $json it's look like this:
{
"name": "PPP",
"asset_tag": "BBB",
"custom_fields": [
{
"Mediensatz": [
{
"value": "B2T-XXX"
}
]
}
]
}

Related

Parsing through PowerShell API Response

I build a C# project which called an API and received a response as shown below and I looped through to determine how many times the System.State "New Value" was Resolved. We want to move this to run on a schedule via a pipeline so I am attempting to translate this into PowerShell.
I'm unfamiliar with how to create objects and loop through them in PowerShell as I'v shown in my C# project. Any guidance would be appreciated.
I've tried Invoke-RestMethod with | ConvertFrom-JSON:
$HistoryQueryResult = Invoke-RestMethod -Method Get -ContentType application/json -Uri $QueryUri -Headers $header | ConvertFrom-Json
..but, I'm unsure after this point.
var RootObjects = JsonConvert.DeserializeObject<WorkItemHistoryJson.Root>(result2);
foreach (var item in RootObjects.value)
{
if (item.fields != null)
{
if (item.fields.SystemState != null)
{
if (item.fields.SystemState.newValue == StateToCheck)
{
TES_WorkItem.CountOfTestingRounds += 1;
}
}
}
}
{
"count": 6,
"value": [
{
"id": 1,
"workItemId": 226,
"rev": 1,
"revisedBy": {
"id": "0e7735b9-cf6a-6468-82c1-81e6b092addd",
"descriptor": "aad.MGU3NzM1YjktY2Y2YS03NDY4LTgyYzEtODFlNmIwOTJhZGRk"
},
"revisedDate": "2020-05-22T09:49:00.81Z",
"fields": {
"System.Id": {
"newValue": 226
},
"System.Reason": {
"newValue": "New"
},
"System.CreatedDate": {
"newValue": "2020-05-22T07:59:22.64Z"
},
"System.ChangedDate": {
"newValue": "2020-05-22T07:59:22.64Z"
}
}
},
{
"id": 2,
"workItemId": 226,
"rev": 2,
"revisedDate": "2020-05-22T09:49:04.45Z",
"fields": {
"System.Rev": {
"oldValue": 1,
"newValue": 2
},
"System.State":{
"oldValue":"New",
"newValue":"Resolved"
}
}
}
]
}
I believe, assuming the JSON follows this exact structure, you could do it just like this, which returns 1 when testing with the one posted in question:
$json = Invoke-RestMethod -Method Get -ContentType application/json -Uri $QueryUri -Headers $header
(#($json.value.fields.'system.state'.newValue) -eq 'Resolved').Count
-eq can be used for filtering if the LHS of the comparison is an array, hence the use of the array sub-expression #(..).

PowerShell ConvertTo-Json object output with leading unwanted numbers

Below function is giving me required result except the numbers (0,1,2,0) populating before JSON object beginning. Can someone help me to get rid of those numbers.
$V1='11' $V2='1881' $V3='111','222','333'
$body=CreateJsonBody $V1 $V2 $V3
function CreateJsonBody{
param($objectId,$AttributeId,$AttributeValues)
$jsonBase=#{"objectId"= $objectId;}
$vlist = New-Object System.Collections.ArrayList
$alist = New-Object System.Collections.ArrayList
foreach ($Val in $AttributeValues) {
$vlist.Add(#{"value"= $Val;})
}
$alist.Add(#{"AttributeId"= $AttributeId;"AttributeValues"=$vlist;})
$jsonBase.Add("attributes",$alist)
return $jsonBase | ConvertTo-Json -Depth 10
}
Output:
PS C:\WINDOWS\system32> $body
0
1
2
0
{
"objectId": "105",
"attributes": [
{
"AttributeId": "1887",
"AttributeValues": [
{
"value": "111"
},
{
"value": "222"
},
{
"value": "333"
}
]
}
]
}

Parse json values into a single row

{
"value": [{
"ExternalKey": "12345",
"PortfolioId": "ABC",
"InceptionDate": null,
"TerminationDate": null,
"Version": 2,
"SourceRef": "ABC",
"MasterSeries": [{
"Points": [{
"Date": "1900-01-01T00:00:00+00:00",
"Name": "XYZ Name",
"Type": "IP",
"Status": "Active",
"Version": 1
}],
"ExternalKey": "12345",
"Version": 1,
"IsDeleted": false,
"SourceRef": "ABC"
}]
}]
}
I tried to loop through each level and manually selecting the keys
ForEach($d in $json.value) { $row=$d.column1+","+ $d.column2 ..
$rootProps = $d| Get-Member | Where-Object { $_.MemberType -match "Property"}
$rootProps | ForEach-Object {
if($_.Name -eq "MasterSeries") {
$d | select -Expand MasterSeries | select-object * -ExcludeProperty Points | ForEach { $row = $_.column1 + "," $_.column2 ..
}
}
and so on..... but when I export it to Out-File "Export.csv" and try importing it gives me a UTF error. Is there a better way to achieve?
If this helps any, here's the typical way to loop through json properties in powershell 5 using the hidden psobject.properties. You might search for "flatten json".
$a = get-content file.json | convertfrom-json
$a.value[0].psobject.properties | select name,value
Name Value
---- -----
ExternalKey 12345
PortfolioId ABC
InceptionDate
TerminationDate
Version 2
SourceRef ABC
MasterSeries
For this you will need to create a recursive function.
To make things easier, I recommend you to use the ConvertFrom-Json -AsHashTable parameter which will return [HashTable] objects rather than [PSCustomObject] Objects
Function Get-Values($Object) {
if ($Object -is [String]) { $Object } # A string is also Enumerable
elseif ($Object -is [Collections.IDictionary]) { $Object.get_Values() | ForEach-Object { Get-Values $_ } }
elseif ($Object -is [Collections.IEnumerable]) { $Object.GetEnumerator() | ForEach-Object { Get-Values $_ } }
else { $Object }
}
$Object = ConvertFrom-Json -AsHashTable '{
"value": [
{
"ExternalKey": "12345",
"PortfolioId": "ABC",
"InceptionDate": null,
"TerminationDate": null,
"Version": 2,
"SourceRef": "ABC",
"MasterSeries": [
{
"Points": [
{
"Date": "1900-01-01T01:00:00+01:00",
"Name": "XYZ Name",
"Type": "IP",
"Status": "Active",
"Version": 1
}
],
"ExternalKey": "12345",
"Version": 1,
"IsDeleted": false,
"SourceRef": "ABC"
}
]
}
]
}'
Get-Values $Object
12345
False
1
IP
Monday, January 1, 1900 1:00:00 AM
XYZ Name
Active
ABC
1
12345
2
ABC
ABC

Converting JSON to NDJSON with Powershell

I'm trying to convert a text file that has an array of json objects to an NDJSON formatted file for another team to consume.
I've almost got it, except for one problem. I have an array of objects nested inside the JSON (which then has nested arrays and objects inside of it, the structure gets pretty complex, I'll include a sample below) and for whatever reason, when I use ConvertFrom-JSON it drops this nested array and in my output, I end up with a blank string for that key, instead of the nested array object. I tried using the -Depth flag but when I do that my output file ends up blank, which doesn't make a ton of sense to me. I don't have a whole lot of experience with powershell, so I'm not really sure where I'm going wrong here.
Code:
$JSONSourceFile = Get-Content -Path "input/sample.json" | ConvertFrom-JSON
$NDJSONTargetFile = "output/sample.json"
New-Item $NDJSONTargetFile -ItemType file
for ( $i = 0 ; $i -lt $JSONSourceFile.Length ; $i++) {
$item = $JSONSourceFile.item($i)
$row = ($item | ConvertTo-JSON -Compress)
Add-Content $NDJSONTargetFile $row
}
Input File:
[
{
"id": "1",
"TransactionDttm": "2021-02-22T15:45:00:00.000-05:00",
"Array1": [
{
"UserID": "ak2354",
"Preferences": [
{
"CagegoryID": "01",
"CategoryName": "Reminder",
"Channels": [
{
"ChannelID": "1",
"ChannelName": "Email",
"Preference": "Y"
},
{
"ChannelID": "2",
"ChannelName": "Text",
"Preference": "N"
}
]
}
]
}
]
},
{
"id": "2",
"TransactionDttm": "2021-02-22T15:45:00:00.000-05:00",
"Array1": [
{
"UserID": "ak1234",
"Preferences": [
{
"CagegoryID": "01",
"CategoryName": "Reminder",
"Channels": [
{
"ChannelID": "1",
"ChannelName": "Email",
"Preference": "Y"
},
{
"ChannelID": "2",
"ChannelName": "Text",
"Preference": "Y"
}
]
}
]
}
]
},
{
"id": "3",
"TransactionDttm": "2021-02-22T15:45:00:00.000-05:00",
"Array1": [
{
"UserID": "ak5678",
"Preferences": [
{
"CagegoryID": "01",
"CategoryName": "Reminder",
"Channels": [
{
"ChannelID": "1",
"ChannelName": "Email",
"Preference": "N"
},
{
"ChannelID": "2",
"ChannelName": "Text",
"Preference": "N"
}
]
}
]
}
]
}
]
And then when I convert it to the output, this is what I get:
{"id":"1","TransactionDttm":"2021-02-22T15:45:00:00.000-05:00","Array1":[{"UserID":"ak2354","Preferences":""}]}
{"id":"2","TransactionDttm":"2021-02-22T15:45:00:00.000-05:00","Array1":[{"UserID":"ak1234","Preferences":""}]}
{"id":"3","TransactionDttm":"2021-02-22T15:45:00:00.000-05:00","Array1":[{"UserID":"ak5678","Preferences":""}]}
Thanks to the comment from Doug Maurer I figured it out, I was adding -Depth to my ConvertFrom-Json command when it should have been in my ConvertTo-Json command. This is the final script and what it gives me:
$JSONSourceFile = Get-Content -Path "input/sample.json" | ConvertFrom-JSON
$NDJSONTargetFile = "output/sample.json"
New-Item $NDJSONTargetFile -ItemType file
for ( $i = 0 ; $i -lt $JSONSourceFile.Length ; $i++) {
$item = $JSONSourceFile.item($i)
$row = ($item | ConvertTo-JSON -Compress -Depth 20)
Add-Content $NDJSONTargetFile $row
}
and the output:
{"id":"1","TransactionDttm":"2021-02-22T15:45:00:00.000-05:00","Array1":[{"UserID":"ak2354","Preferences":[{"CagegoryID":"01","CategoryName":"Reminder","Channels":[{"ChannelID":"1","ChannelName":"Email","Preference":"Y"},{"ChannelID":"2","ChannelName":"Text","Preference":"N"}]}]}]}
{"id":"2","TransactionDttm":"2021-02-22T15:45:00:00.000-05:00","Array1":[{"UserID":"ak1234","Preferences":[{"CagegoryID":"01","CategoryName":"Reminder","Channels":[{"ChannelID":"1","ChannelName":"Email","Preference":"Y"},{"ChannelID":"2","ChannelName":"Text","Preference":"Y"}]}]}]}
{"id":"3","TransactionDttm":"2021-02-22T15:45:00:00.000-05:00","Array1":[{"UserID":"ak5678","Preferences":[{"CagegoryID":"01","CategoryName":"Reminder","Channels":[{"ChannelID":"1","ChannelName":"Email","Preference":"N"},{"ChannelID":"2","ChannelName":"Text","Preference":"N"}]}]}]}

PowerShell retrieve MS Graph 3rd level data return non-json result

I got a PS script to retrieve an AuditLog event from MS Graph. The script code is below. It gets the event details in JSON format.
# Create Authentication Token for MS Graph
Function GetAuthToken
{
param
(
[Parameter(Mandatory=$true)]
$TenantName
)
Import-Module Azure
$clientId = "ef9bcdf0-a675-4cd5-9ec3-fa549f9ee4cf"
$redirectUri = "https://RedirectURI.com"
$resourceAppIdURI = "https://graph.microsoft.com"
$authority = "https://login.microsoftonline.com/$TenantName"
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority
$Credential = Import-Clixml -Path "C:\MIMA\tom_admin_cred.xml"
$AADCredential = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserCredential" -ArgumentList $credential.UserName,$credential.Password
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId,$AADCredential)
return $authResult
}
Function Get-aAuditEvent
{
param
(
[Parameter(Mandatory=$true)]
$Tenant
)
if($Version -eq $null) {$Version='Beta'}
#------Get the authorization token------#
$token = GetAuthToken -TenantName $tenant
#------Building Rest Api header with authorization token------#
$authHeader = #{
'Content-Type'='application\json'
'Authorization'=$token.CreateAuthorizationHeader()
}
$uri = "https://graph.microsoft.com/beta/auditlogs/directoryAudits/Directory_3WOOD_3967500"
# $uri = "https://graph.microsoft.com/beta/auditlogs/directoryAudits"
Try {
$results = Invoke-RestMethod -Uri $uri –Headers $authHeader –Method Get
$results |ConvertTo-Json -depth 4
}
catch{
Write-Host "Error while retrieving report!" -ForegroundColor red
$auditReports = $_.Exception.Response
}
}
Get-aAuditEvent -Tenant "contoso.onmicrosoft.com"
The result of the code is as below. Notice the content of "modifiedProperties" is not in JSON format? It seems somehow the value of this property has converted to hashtable. However, I tried to put this value into a hashtable and it couldn't parse it properly anyway. Maybe because "newValue" is too long for a hash table?
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#auditLogs/directoryAudits/$entity",
"id": "Directory_3WOOD_3967500",
"category": "Core Directory",
"correlationId": "559450b1-d1e8-4020-a420-4c3c6234ba44",
"result": "success",
"resultReason": "",
"activityDisplayName": "Update user",
"activityDateTime": "2018-10-13T14:57:33.328183Z",
"loggedByService": null,
"initiatedBy": {
"app": null,
"user": {
"id": "9327abf7-93ea-4007-a15c-9b77b5360cc9",
"displayName": null,
"userPrincipalName": "tom-admin#contoso.onmicrosoft.com",
"ipAddress": "\u003cnull\u003e"
}
},
"targetResources": [
{
"#odata.type": "#microsoft.graph.targetResourceUser",
"id": "2a58e6ca-2207-4fc0-ba5d-210cd5de25dc",
"displayName": null,
"userPrincipalName": "tom.chen#contoso.com",
"modifiedProperties": [
"#{displayName=AssignedLicense; oldValue=[]; newValue=[\"[SkuName=ENTERPRISEPACK, AccountId=cdc4b90d-7fa9-4a12-8d58-c2872266673c, SkuId=6fd2c87f-b296-42f0-b197-1e91e994b900, DisabledPlans=[]]\"]}",
"#{displayName=AssignedPlan; oldValue=[]; newValue=[{\"SubscribedPlanId\":\"f0e58183-18c1-4fa6-939b-e78d050533b6\",\"ServiceInstance\":\"To-Do/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:
57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"c87f142c-d1e9-4363-8630-aaea9c4d9ae5\"},{\"SubscribedPlanId\":\"ea0d7e34-84a0-4329-910a-f38d7d4f2c00\",\"ServiceInstance\":\"OfficeForms/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"
2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"2789c901-c14e-48ab-a76a-be334d9d793a\"},{\"SubscribedPlanId\":\"0defa810-1846-4ebf-8c01-4b72f9dbec2c\",\"ServiceInstance\":\"MicrosoftStream/NA001\",\"CapabilityStatus\":0,\"Assi
gnedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"9e700747-8b1d-45e5-ab8d-ef187ceec156\"},{\"SubscribedPlanId\":\"e56c4814-73b8-4a12-ac13-bd2236e1c61c\",\"ServiceInstance\":\"Deskless/NA001\",\"CapabilityStatus
\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"8c7d2df8-86f0-4902-b2ed-a0458298f3b3\"},{\"SubscribedPlanId\":\"ef68b42e-5730-41b8-b119-a78dd199cd39\",\"ServiceInstance\":\"ProcessSimple/NA001\",\"
CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"76846ad7-7776-4c40-a281-a386362dd1b9\"},{\"SubscribedPlanId\":\"d69c693a-dfc8-49f8-9bd2-68b570bc3dd8\",\"ServiceInstance\":\"PowerApp
sService/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"c68f8d98-5534-41c8-bf36-22fa496fa792\"},{\"SubscribedPlanId\":\"b3e7a5a5-bfae-4ae6-887c-ce9665de0610\",\"ServiceIn
stance\":\"TeamspaceAPI/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"57ff2da0-773e-42df-b2af-ffb7a2317929\"},{\"SubscribedPlanId\":\"c9dbc746-7d1d-449f-9a2c-f80c99df11f
2\",\"ServiceInstance\":\"ProjectWorkManagement/PROD_OC_Org_Ring_010\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"b737dad2-2f6c-4c65-90e3-ca563267e8b9\"},{\"SubscribedPlanId\
":\"6aa67dd9-afd1-47c4-b81f-065ba3495692\",\"ServiceInstance\":\"Sway/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"a23b959c-7ce8-4e57-9140-b90eb88a9e97\"},{\"Subscribed
PlanId\":\"6d4d99fc-d0e1-4350-a4da-cb79cadd739e\",\"ServiceInstance\":\"YammerEnterprise/NA009\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"7547a3fe-08ee-4ccb-b430-5077c50416
53\"},{\"SubscribedPlanId\":\"ac1fca1c-7d64-476c-b1f8-1c336ccac213\",\"ServiceInstance\":\"RMSOnline/AP\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"bea4c11e-220a-4e6d-8eb8-8
ea15d019f90\"},{\"SubscribedPlanId\":\"2cc87a99-6c05-4bf2-a8a7-4a75e26a6afd\",\"ServiceInstance\":\"MicrosoftOffice/NorthAmerica\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"
43de0ff5-c92c-492b-9116-175376d08c38\"},{\"SubscribedPlanId\":\"97006162-e810-4814-98e7-3ae3745b28bc\",\"ServiceInstance\":\"MicrosoftCommunicationsOnline/Instance04-S\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\
"Capability\":null,\"ServicePlanId\":\"0feaeb32-d00e-4d66-bd5a-43b5b83db82c\"},{\"SubscribedPlanId\":\"10985cf4-2206-4e47-9910-426586912b1a\",\"ServiceInstance\":\"SharePoint/SPOS0017\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"Initi
alState\":null,\"Capability\":null,\"ServicePlanId\":\"e95bec33-7c88-4a70-8e19-b10bd9d0c014\"},{\"SubscribedPlanId\":\"e0592405-cc57-4152-8cc0-3f8e5651e47d\",\"ServiceInstance\":\"SharePoint/SPOS0017\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.16
83839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"5dbe027f-2339-4123-9542-606e4d348a72\"},{\"SubscribedPlanId\":\"552916d8-55f1-44be-a7e1-9a56b8086a9b\",\"ServiceInstance\":\"exchange/apcprd03-001-01\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2
018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"efb87545-963c-4e0d-99df-69c6916d9eb0\"}]}",
"#{displayName=Included Updated Properties; oldValue=; newValue=\"AssignedLicense, AssignedPlan\"}",
"#{displayName=TargetId.UserType; oldValue=; newValue=\"Member\"}"
]
}
],
"additionalDetails": [
{
"key": "UserType",
"value": "Member"
}
]
}
This is very odd, as when I retrieve the same event from MS Graph Explorer, I get different result, which is all in proper JSON foramt. Below is the output from MS Graph Explorer. As you can see, the "modifiedProperties" pair is still presented in JSON format.
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#auditLogs/directoryAudits/$entity",
"id": "Directory_3WOOD_3967500",
"category": "Core Directory",
"correlationId": "559450b1-d1e8-4020-a420-4c3c6234ba44",
"result": "success",
"resultReason": "",
"activityDisplayName": "Update user",
"activityDateTime": "2018-10-13T14:57:33.328183Z",
"loggedByService": null,
"initiatedBy": {
"app": null,
"user": {
"id": "9327abf7-93ea-4007-a15c-9b77b5360cc9",
"displayName": null,
"userPrincipalName": "tom-admin#contoso.onmicrosoft.com",
"ipAddress": "<null>"
}
},
"targetResources": [
{
"#odata.type": "#microsoft.graph.targetResourceUser",
"id": "2a58e6ca-2207-4fc0-ba5d-210cd5de25dc",
"displayName": null,
"userPrincipalName": "tom.chen#contoso.com",
"modifiedProperties": [
{
"displayName": "AssignedLicense",
"oldValue": "[]",
"newValue": "[\"[SkuName=ENTERPRISEPACK, AccountId=cdc4b90d-7fa9-4a12-8d58-c2872266673c, SkuId=6fd2c87f-b296-42f0-b197-1e91e994b900, DisabledPlans=[]]\"]"
},
{
"displayName": "AssignedPlan",
"oldValue": "[]",
"newValue": "[{\"SubscribedPlanId\":\"f0e58183-18c1-4fa6-939b-e78d050533b6\",\"ServiceInstance\":\"To-Do/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"c87f142c-d1e9-4363-8630-aaea9c4d9ae5\"},{\"SubscribedPlanId\":\"ea0d7e34-84a0-4329-910a-f38d7d4f2c00\",\"ServiceInstance\":\"OfficeForms/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"2789c901-c14e-48ab-a76a-be334d9d793a\"},{\"SubscribedPlanId\":\"0defa810-1846-4ebf-8c01-4b72f9dbec2c\",\"ServiceInstance\":\"MicrosoftStream/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"9e700747-8b1d-45e5-ab8d-ef187ceec156\"},{\"SubscribedPlanId\":\"e56c4814-73b8-4a12-ac13-bd2236e1c61c\",\"ServiceInstance\":\"Deskless/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"8c7d2df8-86f0-4902-b2ed-a0458298f3b3\"},{\"SubscribedPlanId\":\"ef68b42e-5730-41b8-b119-a78dd199cd39\",\"ServiceInstance\":\"ProcessSimple/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"76846ad7-7776-4c40-a281-a386362dd1b9\"},{\"SubscribedPlanId\":\"d69c693a-dfc8-49f8-9bd2-68b570bc3dd8\",\"ServiceInstance\":\"PowerAppsService/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"c68f8d98-5534-41c8-bf36-22fa496fa792\"},{\"SubscribedPlanId\":\"b3e7a5a5-bfae-4ae6-887c-ce9665de0610\",\"ServiceInstance\":\"TeamspaceAPI/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"57ff2da0-773e-42df-b2af-ffb7a2317929\"},{\"SubscribedPlanId\":\"c9dbc746-7d1d-449f-9a2c-f80c99df11f2\",\"ServiceInstance\":\"ProjectWorkManagement/PROD_OC_Org_Ring_010\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"b737dad2-2f6c-4c65-90e3-ca563267e8b9\"},{\"SubscribedPlanId\":\"6aa67dd9-afd1-47c4-b81f-065ba3495692\",\"ServiceInstance\":\"Sway/NA001\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"a23b959c-7ce8-4e57-9140-b90eb88a9e97\"},{\"SubscribedPlanId\":\"6d4d99fc-d0e1-4350-a4da-cb79cadd739e\",\"ServiceInstance\":\"YammerEnterprise/NA009\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"7547a3fe-08ee-4ccb-b430-5077c5041653\"},{\"SubscribedPlanId\":\"ac1fca1c-7d64-476c-b1f8-1c336ccac213\",\"ServiceInstance\":\"RMSOnline/AP\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"bea4c11e-220a-4e6d-8eb8-8ea15d019f90\"},{\"SubscribedPlanId\":\"2cc87a99-6c05-4bf2-a8a7-4a75e26a6afd\",\"ServiceInstance\":\"MicrosoftOffice/NorthAmerica\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"43de0ff5-c92c-492b-9116-175376d08c38\"},{\"SubscribedPlanId\":\"97006162-e810-4814-98e7-3ae3745b28bc\",\"ServiceInstance\":\"MicrosoftCommunicationsOnline/Instance04-S\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"0feaeb32-d00e-4d66-bd5a-43b5b83db82c\"},{\"SubscribedPlanId\":\"10985cf4-2206-4e47-9910-426586912b1a\",\"ServiceInstance\":\"SharePoint/SPOS0017\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"e95bec33-7c88-4a70-8e19-b10bd9d0c014\"},{\"SubscribedPlanId\":\"e0592405-cc57-4152-8cc0-3f8e5651e47d\",\"ServiceInstance\":\"SharePoint/SPOS0017\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"5dbe027f-2339-4123-9542-606e4d348a72\"},{\"SubscribedPlanId\":\"552916d8-55f1-44be-a7e1-9a56b8086a9b\",\"ServiceInstance\":\"exchange/apcprd03-001-01\",\"CapabilityStatus\":0,\"AssignedTimestamp\":\"2018-10-13T14:57:33.1683839Z\",\"InitialState\":null,\"Capability\":null,\"ServicePlanId\":\"efb87545-963c-4e0d-99df-69c6916d9eb0\"}]"
},
{
"displayName": "Included Updated Properties",
"oldValue": null,
"newValue": "\"AssignedLicense, AssignedPlan\""
},
{
"displayName": "TargetId.UserType",
"oldValue": null,
"newValue": "\"Member\""
}
]
}
],
"additionalDetails": [
{
"key": "UserType",
"value": "Member"
}
]
}
In fact both results (via PowerShell and Microsoft Graph Explorer) seems to be identical (except some formatting differences).
In both cases a valid JSON value is returned.
Now comes the turn of oldValue and newValue property values.
According to documentation, modifiedProperty property of targetResource resource
returns the collection of name, old value and new value which represented in JSON format like this:
{
"displayName": "String",
"newValue": "String",
"oldValue": "String"
}
meaning newValue and oldValue return the converted to string values.
Example
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#auditLogs/directoryAudits/$entity",
"id": "Directory_GIRJA_107870298",
//...
"targetResources": [
{
"#odata.type": "#microsoft.graph.targetResourceGroup",
//...
"modifiedProperties": [
{
"displayName": "foo",
"oldValue": "[]",
"newValue": "[\"bar\"]"
},
//...
{
"displayName": "json_value",
"oldValue": null,
"newValue": "[{\"first_name\":\"Jon\",\"last_name\":\"Doe\"}]"
}
]
}
],
"additionalDetails": []
}
Note: pay attention to the second modifiedProperty entry newValue property, which represents JSON value and is returned as a string: {"first_name":"Jon","last_name":"Doe"}
Using the following example newValue could be converted to JSON:
$uri = "https://graph.microsoft.com/beta/auditLogs/directoryAudits/{directory-id}"
$results = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get
$results.targetResources | Select -ExpandProperty modifiedProperties | Select -ExpandProperty newValue | ConvertFrom-Json
I managed to solve the problem by putting the "modifiedProperties" section into a hashtable (Didn't do this properly last time). I use a function to convert the JSON result to Hashtable. The function code is copied from here.
Function ConvertTo-Hashtable {
[CmdletBinding()]
[OutputType('hashtable')]
param (
[Parameter(ValueFromPipeline)]
$InputObject
)
process {
## Return null if the input is null. This can happen when calling the function
## recursively and a property is null
if ($null -eq $InputObject) {
return $null
}
## Check if the input is an array or collection. If so, we also need to convert
## those types into hash tables as well. This function will convert all child
## objects into hash tables (if applicable)
if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string]) {
$collection = #(
foreach ($object in $InputObject) {
ConvertTo-Hashtable -InputObject $object
}
)
## Return the array but don't enumerate it because the object may be pretty complex
Write-Output -NoEnumerate $collection
} elseif ($InputObject -is [psobject]) { ## If the object has properties that need enumeration
## Convert it to its own hash table and return it
$hash = #{}
foreach ($property in $InputObject.PSObject.Properties) {
$hash[$property.Name] = ConvertTo-Hashtable -InputObject $property.Value
}
$hash
} else {
## If the object isn't an array, collection, or other object, it's already a hash table
## So just return it.
$InputObject
}
}
}
$hashtable1 = #{}
$hashtable2 = #{}
$hashtable1 = Get-aAuditEvent -Tenant "contoso.onmicrosoft.com"|ConvertFrom-Json|ConvertTo-HashTable
$hashtable2 = $hashtable1.targetResources.modifiedProperties
$hashtable2[0].displayName
$hashtable2[0].oldValue
$hashtable2[0].newValue
The output of the code is below. I still need to workout how to parse "newValue" properly. But at least I can show what actions have been done and what have been changed.
AssignedLicense
[]
["[SkuName=ENTERPRISEPACK, AccountId=cdc4b90d-7fa9-4a12-8d58-c2872266673c, SkuId=6fd2c87f-b296-42f0-b197-1e91e994b900, DisabledPlans=[]]"]