Invoke-WebRequest content ConvertFrom-Json: Conversion from JSON failed with error: Unexpected character encountered while parsing value (CR;LF) - powershell

I successfully sent an webrequest to a Website and got a responde:
$Uri = "https://URLXYZ"
$Method = "POST"
$Header = #{
"Accept" = "*/*";
"Connection" = "keep-alive";
"Accept-Encoding" = "gzip, deflate, br";
"Content-Type" = "text/json; charset=""UTF-8"""
}
$Body = #"
{
"Items": [
{
"Type": "XX",
"Value": "YY",
}
],
"TypeId": XY,
"LiveConditions": []
}
"#
$webrequest = Invoke-WebRequest -Uri $Uri -Body $Body -Headers $Header -Method $Method
Now, I am trying to convert it from JSON without success:
$webrequest.Content | ConvertFrom-Json
ConvertFrom-Json: Conversion from JSON failed with error: Unexpected character encountered while parsing value: . Path '', line 0, position 0.
When I copy the output ($webrequest.Content) to Notepad++ I can see a carriage return (CR) and line feed (LF):
$webrequest.Content
[{"MailG":[{"DisplayName":{"7":"Worker","9":"Person"},"Mails":"max.mustermann#gmai.com;"}],"ResultCount":1,"Rows":[{"ElementGroups":[{"ObjectContainer":{"Id":55
6677889900,"UID":"1122334455","Info":[],"PreCalculatedSelectedProperties":{"11":"Mustermann","22":"","33":"StreetName","44":"","55":"max.mustermann#gmai.com","66":"","77":"Berlin","88":"","99":"Max Mustermann","00":"+49 00 000 000","111":"userid","222":"xyz","333":"company","444":"1122334455","555":"roomnumber","666":"Germany","777":"Team","888":"+49 000 0 00 0","999":"Max","000":""},"TID":5,"RuleConditionPartResults":{"1448925":false,"1448926":false,"1448927":false,"1448928":false,"1448929":false,"1448930":false,"1448931":false,"1448932":false,"1448933":false,"1448934":false,"1448935":false,"1448936":false,"1448937":false,"1448938":false,"1448939":false,"1448940":false,"1448941":false,"1448942":false},"Img":{"3714":["picture"]},"Parents":[],"Childs":[],"UpObjects":0,"Down":0,"LinkCount":0,"FootObject":{},"BoxIds":[],"DisplayValue":"Max Mustermann","Key":"1122334455"},"Columns":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]}],"Blank":{},"Score":0.0,"SInd":0}],"Page":0,"TID":5}]
This is unexpected cause the CR;LF is e.g. in the middle of an email address.
If the response is longer, there are multiple CR;LF within the content of the webrequest.
The $webrequest.content is TypeName: System.String
If I manually remove the CR;CF in Notepad++ and PrettyPrint it is working:
[
{
"MailG": [
{
"DisplayName": {
"7": "Worker",
"9": "Person"
},
"Mails": "max.mustermann#gmai.com;"
}
],
"ResultCount": 1,
"Rows": [
{
"ElementGroups": [
{
"ObjectContainer": {
"Id": 556677889900,
"UID": "1122334455",
"Info": [],
"PreCalculatedSelectedProperties": {
"11": "Mustermann",
"22": "",
"33": "StreetName",
"44": "",
"55": "max.mustermann#gmai.com",
"66": "",
"77": "Berlin",
"88": "",
"99": "Max Mustermann",
"00": "+49 00 000 000",
"111": "userid",
"222": "xyz",
"333": "company",
"444": "1122334455",
"555": "roomnumber",
"666": "Germany",
"777": "Team",
"888": "+49 000 0 00 0",
"999": "Max",
"000": ""
},
"TID": 5,
"RuleConditionPartResults": {
"1448925": false,
"1448926": false,
"1448927": false,
"1448928": false,
"1448929": false,
"1448930": false,
"1448931": false,
"1448932": false,
"1448933": false,
"1448934": false,
"1448935": false,
"1448936": false,
"1448937": false,
"1448938": false,
"1448939": false,
"1448940": false,
"1448941": false,
"1448942": false
},
"Img": {
"3714": [
"picture"
]
},
"Parents": [],
"Childs": [],
"UpObjects": 0,
"Down": 0,
"LinkCount": 0,
"FootObject": {},
"BoxIds": [],
"DisplayValue": "Max Mustermann",
"Key": "1122334455"
},
"Columns": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17
]
}
],
"Blank": {},
"Score": 0.0,
"SInd": 0
}
],
"Page": 0,
"TID": 5
}
]
I already tried to convert it or even replace the CR;LF it in PowerShell without success.
The only workaround I found is to write the content to a .txt-file and read it again.
$webrequest.Content | Out-File "C:\Temp\WebRequestTemp.txt"
$json = Get-Content "C:\Temp\WebRequestTemp.txt" | ConvertFrom-Json
Afterwards I was able to convert it from JSON and work with the data.
Why can I not directly convert it from JSON as usual?

To help you with a more detailed answer. It is useful to share the contents of the web response. But maybe the line below will solve your problem.
$jsonCorrected = [Text.Encoding]::UTF8.GetString([Text.Encoding]::GetEncoding(28591).GetBytes(($webrequest.Content)))

I had a similar issue, and the issue was there was an unknown invisible character at the beginning of the content block. This character was "U+FEFF".
I managed to get it to be replaced by doing $webrequest.Content -replace '\uFEFF' | ConvertFrom-Json
I hope this works for anyone else too.

Related

Replace string in text file with PowerShell

I am attempting to replace a string in a text file on a specific line number using PowerShell but the command is removing a majority of the content. I would like to leverage the line number because the string to be replaced occurs on several lines but only want the string on line 51 to be updated. I am currently attempting to use the following to perform the replacement:
$content = Get-Content "file.txt"
$contentUpdate = $content[51] -replace '"Endpoint": ""','"Endpoint": "bucket.s3.us-west-1.vpce.amazonaws.com",'
Set-Content file.txt $contentUpdate
When the above commands are run against the file referenced at the bottom of this question, only the following remains in the file:
"Region": "",
File content:
{
"Profile":{
"ShareCreds" : true,
"ShareProfile" : "",
"ForceUpdateCreds" : false,
"KeyAutoRotateDays": 0
},
"Mds": {
"CommandWorkersLimit" : 5,
"StopTimeoutMillis" : 20000,
"Endpoint": "",
"CommandRetryLimit": 15
},
"Ssm": {
"Endpoint": "",
"HealthFrequencyMinutes": 5,
"CustomInventoryDefaultLocation" : "",
"AssociationLogsRetentionDurationHours" : 24,
"RunCommandLogsRetentionDurationHours" : 336,
"SessionLogsRetentionDurationHours" : 336,
"PluginLocalOutputCleanup": "",
"OrchestrationDirectoryCleanup": ""
},
"Mgs": {
"Region": "us-west-1",
"Endpoint": "",
"StopTimeoutMillis" : 20000,
"SessionWorkersLimit" : 1000,
"DeniedPortForwardingRemoteIPs" : [
"169.254.169.254",
"fd00:ec2::254",
"169.254.169.253",
"fd00:ec2::253"
]
},
"Agent": {
"Region": "",
"OrchestrationRootDir": "",
"SelfUpdate": false,
"TelemetryMetricsToCloudWatch": false,
"TelemetryMetricsToSSM": true,
"AuditExpirationDay" : 7,
"LongRunningWorkerMonitorIntervalSeconds": 60
},
"Os": {
"Lang": "en-US",
"Name": "",
"Version": "1"
},
"S3": {
"Endpoint": "",
"Region": "",
"LogBucket":"",
"LogKey":""
},
"Kms": {
"Endpoint": ""
}
}
Well, seeing that this is a JSON you're working with, I would treat it as such:
$content = Get-Content "file.txt" -Raw | ConvertFrom-Json
$content.S3.Endpoint = "bucket.s3.us-west-1.vpce.amazonaws.com"
$content | ConvertTo-Json | Set-Content "file.txt"
This way you avoid trying to index through an array and work with the objects themselves.

update/create TFS Server variable group using REST API with powershell gives object reference not set

Allright i have been fiddling with this for a few hours now and i can't seem to find any resources online or solve the issue.
Looking at the api documentation at https://learn.microsoft.com/en-us/rest/api/azure/devops/distributedtask/variablegroups/get?view=azure-devops-rest-6.0
I can get info regarding the variable group that i created as a test:
$invRestMethParams = #{
Uri = "https://xxx.xxx.nl/tfs/DefaultCollection/$($project)/_apis/distributedtask/variablegroups/242/?api-version=6.0-preview.2"
Method = 'GET'
ContentType = 'application/json'
}
Invoke-RestMethod #invRestMethParams -UseDefaultCredentials
I then convert the result to json to get the required values for the PUT or POST to update or create:
{
"variables": {
"check": {
"value": "value"
}
},
"id": 242,
"type": "Vsts",
"name": "TestUpdate",
"description": "",
"isShared": false,
"variableGroupProjectReferences": [
{
"projectReference": "#{id=0add8cd8-0fc8-4aca-8eb4-164cd8d09c9d; name=AutoUpdateVariableGroups}",
"name": "TestUpdate",
"description": ""
}
]
}
The documentation states the update url is:
PUT https://{instance}/{collection}/_apis/distributedtask/variablegroups/{groupId}?api-version=6.0-preview.2
With request body having the above json values (without the ID as this is in the URI). So my update json becomes:
$body = #"
{
"variables": {
"checkupdated": {
"value": "valueupdated"
}
},
"type": "Vsts",
"name": "TestUpdate",
"description": "",
"isShared": false,
"variableGroupProjectReferences": [
{
"projectReference": "#{id=0add8cd8-0fc8-4aca-8eb4-164cd8d09c9d; name=AutoUpdateVariableGroups}",
"name": "TestUpdate",
"description": ""
}
]
}
"#
i convert it from json to see if its valid (no errors).
and use it in my PUT request:
$invRestMethParams = #{
Uri = "https://xxx.xxx.nl/tfs/DefaultCollection/_apis/distributedtask/variablegroups/242/?&api-version=6.0-preview.2"
Method = 'PUT'
ContentType = 'application/json'
Body = $body
}
Invoke-RestMethod #invRestMethParams -UseDefaultCredentials
The error i receive is:
Invoke-RestMethod : {"$id":"1","innerException":null,"message":"Object reference not set to an instance of an object.","typeName":"System.NullReferenceException, mscorlib","typeKey":"NullReferenceException","errorCode":0,"eventId":0}
At line:32 char:1
+ Invoke-RestMethod #invRestMethParams -UseDefaultCredentials
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Not sure how to troubleshoot this, does anyone know how to fix this issue? seems i am forgetting a value but im kinda lost as to what is the issue here.
From your script, it seems that it has issue with your request body.
In projectReference field, you need to use , to replace the ; and you need to modify the format.
"projectReference": {"id":"projectID", "name":"projectname"},
Refer to my sample:
$JSON = #"
{
"variables": {
"checkupdate": {
"value": "vaslueupdate"
}
},
"type": "Vsts",
"name": "AA",
"description": "",
"isShared": false,
"variableGroupProjectReferences": [
{
"projectReference": {"id":"108e4d7c-0bf3-4940-80da-4793f83def92", "name":"kevin1012"},
"name": "AA",
"description": ""
}
]
}
"#

change the value in jsonresponse for particular user

{
"User": {
"id": "iERl6YK6mEmzpotHBvVBiA",
"lastUpdated": 1643789241,
"userInputWeightInKG": "70",
"hasPhoto": true,
"introDone": true,
"photoTime": 1643621107,
"photofmt": "png",
"firstName": "new user",
"lastName": "new user",
"dateOfBirth": "01/31/1994",
"email": "newuser123#gmail.com",
"gender": "m",
"heightMeters": 1.7,
"fingerPrint": "",
"aadhaarNumber": "",
"mobileNumber": "2159863566",
"higiScore": 200.0,
"user_score": {
"A1": 23,
"A2": 8,
"A3": 13,
"A4": 28,
"A5": 8,
"A6": 28,
"A7": 8,
"A8": 23,
"B1": 28,
"B2": 28,
"B3": 28,
"B4": 28,
"C1": 22,
"C2": 8,
"C3": 8,
"C4": 8,
"C5": 22,
"D1": 19,
"D2": 19,
"D3": 19,
"D4": 19,
"E1": 0,
"E2": 0,
"E3": 0,
"E4": 0,
"T": 408
},
"accountCreated": "/Date(1643621096288+0530)/",
"termsHistory": [
{
"termsAgreedDate": "/Date(1643621116912+0530)/",
"termsFileName": "termsofuse_v9_01122016"
}
],
"terms": {
"termsAgreedDate": "/Date(1643621116912+0530)/",
"termsFileName": "termsofuse_v9_01122016"
},
"privacyAgreed": {
"privacyAgreedDate": "/Date(1643621116912+0530)/",
"privacyFileName": "privacypolicy_v7_08112014"
},
"privacyAgreedHistory": [
{
"privacyAgreedDate": "/Date(1643621116912+0530)/",
"privacyFileName": "privacypolicy_v7_08112014"
}
],
"Notifications": {
"EmailCheckins": "true",
"EmailMonthlyRecap": "true",
"EmailHigisphereNotifications": "true",
"EmailHigiNews": "true",
"EmailMonthlyDigest": "true"
},
"currentHigiScore": 0.0,
"hasPassword": true,
"privacy": {
"leaderBoard": {
"enabled": false
},
"thirdPartySharing": {
"nonIdentifiableSharing": true
}
},
"tags": {
"isEarndItUser": false,
"testTag1": 12345
},
"joint_user_detail_list": {
"joint_user1": {
"ihl_user_id": "17Jf3sYhwkGjNaAPPvZugQ",
"ihl_user_name": "firstuser",
"status": "requested",
"vital_read": true,
"vital_write": true,
"teleconsult_read": true,
"teleconsult_write": true
},
"joint_user2": {
"ihl_user_id": "n9RFAVPnvEitJhESoTnFtg",
"ihl_user_name": "seconduser",
"status": "Active",
"vital_read": true,
"vital_write": true,
"teleconsult_read": true,
"teleconsult_write": true
}
}
}
}
This is my response from api..
i have to change the "joint_user2": status of guest user to from "Active" to "Inactive" if i click on that second user in UI
how can i do that
please help
I would suggest creating a class which stores your user data. Then, using a fromMap() or fromJSON() method, you can create an object from your API response. You can have a look at the JSON Serialiser on pub.dev (https://pub.dev/packages/json_serializable).
After that, changing any of the values of that object becomes trivial.
onPressed: () {
guestUser.status = 'Inactive' / UserStatus.Inactive ;
}
I would recommend using enums or some other set value type rather than a string, if you need to perform operations on the guest user's status.

Powershell Iterate through multidimensional array of hashtables to find a match and combine values from both arrays

I need to combine values from 2 JSONs:
If there is a match in alerts IDs, I need to create structure, that will take data from both jsons
Result for a match should look like:
$array = #()
$hashtable = #{}
$hashtable.AlertID (does not matter what JSON is it from)
$hashtable.Tags (from JSON 1)
$hashtable.IncidentName (from JSON2)
$hashtable.IncidentID (from JSON2)
$array += $hashtable
I would prefer if this would be done with c style powershell loop.
c style for loop = for ($x = 0; $x -array.count; $x++)
JSON 1:
[
{
"Status": "Active",
"IncidentId": "3",
"tags": "SINC0008009",
"AlertId": [
"da637563185629568182_-638872186",
"da637563185631732095_1120592736",
"da637563185706412029_-614525914",
"da637563185760439486_-276692370",
"da637563185856325888_-1949235651",
"da637563186785996176_2128073884",
"da637563186789897000_1239551047",
"da637563186806513555_1512241399",
"da637563193194338043_-244132089"
],
"severity": "Medium"
},
{
"Status": "Active",
"IncidentId": "4",
"tags": "SINC0008008",
"AlertId": [
"da637643650725801726_1735022501",
"da637643650741237104_1473290917",
"da637643650748739479_-40211355",
"da637643652767933265_-1887823168",
"da637643670830160376_-443360743"
],
"severity": "Medium"
},
{
"Status": "Active",
"IncidentId": "2",
"tags": null,
"AlertId": [
"caD76232A5-F386-3C5D-94CD-7C82A7F778DC"
],
"severity": "Medium"
},
{
"Status": "Active",
"IncidentId": "1",
"tags": null,
"AlertId": [
"ca6534FF45-D62A-3FB7-BD6B-FF5029C553DB"
],
"severity": "Medium"
}
]
JSON 2:
{
"value": [
{
"incidentId": 3,
"incidentName": "Multi-stage incident involving Initial access & Discovery on one endpoint",
"status": "Active",
"severity": "Medium",
"tags": ["SINC0000001"],
"comments": [],
"alerts": [
{
"alertId": "da637563185629568182_-638872186",
"incidentId": 3,
"description": "A suspicious PowerShell activity was observed on the machine. ",
"status": "New",
"severity": "Medium",
"devices": [
{
"deviceDnsName": "xxxxx"
}
],
"entities": [
{
"entityType": "User",
"accountName": "xxxxxx",
"userPrincipalName": "xxx#xx.xx"
},
{
"entityType": "Process"
},
{
"entityType": "Process",
"verdict": "Suspicious"
},
{
"entityType": "File"
}
]
},
{
"alertId": "da637563185631732095_1120592736",
"incidentId": 3,
"devices": [
{
"osPlatform": "Windows10",
"version": "1909"
}
],
"entities": [
{
"entityType": "User",
"remediationStatus": "None"
}
]
}
]
},
{
"incidentId": 4,
"incidentName": "Multi-stage incident involving Initial access & Discovery on one endpoint",
"status": "Active",
"severity": "Medium",
"tags": ["SINC0000002"],
"comments": [],
"alerts": [
{
"alertId": "da637563185629568182_-638872186",
"incidentId": 3,
"description": "A suspicious PowerShell activity was observed on the machine. ",
"status": "New",
"severity": "Medium",
"devices": [
{
"deviceDnsName": "xxxxx"
}
],
"entities": [
{
"entityType": "User",
"accountName": "xxxxxx",
"userPrincipalName": "xxx#xx.xx"
},
{
"entityType": "Process"
},
{
"entityType": "Process",
"verdict": "Suspicious"
},
{
"entityType": "File"
}
]
},
{
"alertId": "da637563185631732095_1120592736",
"incidentId": 3,
"devices": [
{
"osPlatform": "Windows10",
"version": "1909"
}
],
"entities": [
{
"entityType": "User",
"remediationStatus": "None"
}
]
}
]
}
]
}
Till now, I was looking into using nested foreach loop to address it but it does not behave like I want. I am looking for for loop as I could use the indexes.
Instead of creating an array of Hashtables, I think it's better to create an array of PsCustomObjects, because outputting the result to console/file/json would be a lot easier then.
$json1 = Get-Content -Path 'X:\json1.json' -Raw | ConvertFrom-Json
$json2 = Get-Content -Path 'X:\json2.json' -Raw | ConvertFrom-Json
$result = foreach ($incident in $json1) {
foreach ($alertId in $incident.AlertId) {
$json2.value | Where-Object { $_.alerts.alertId -eq $alertId } | ForEach-Object {
# output an object with the wanted properties
[PsCustomObject]#{
AlertID = $alertId # from json1
Tags = $incident.Tags # from json1
IncidentName = $_.incidentName # from json2
IncidentID = $_.incidentId # from json2
}
}
}
}
# output on screen
$result | Format-Table -AutoSize # or use Out-GridView
# output to new JSON
$result | ConvertTo-Json
# output to CSV file
$result | Export-Csv -Path 'X:\incidents.csv' -NoTypeInformation
Using your examples, the output to console window is:
AlertID Tags IncidentName IncidentID
------- ---- ------------ ----------
da637563185629568182_-638872186 SINC0008009 Multi-stage incident involving Initial access & Discovery on one endpoint 3
da637563185629568182_-638872186 SINC0008009 Multi-stage incident involving Initial access & Discovery on one endpoint 4
da637563185631732095_1120592736 SINC0008009 Multi-stage incident involving Initial access & Discovery on one endpoint 3
da637563185631732095_1120592736 SINC0008009 Multi-stage incident involving Initial access & Discovery on one endpoint 4

Error while trying to create a release definition using Azure DevOps Rest API

I am using below script to create a release definition in Azure DveOps with a PowerShell script, but its failing with error message as below. Not sure where am giving incorrect details.
Invoke-RestMethod :
{"$id":"1","innerException":null,"message":"VS402903: The specified
value is not convertible to type ReleaseDefinition. Make sure it is
convertible to type ReleaseDefinition and try again."
Code snippet is:
Param(
[string]$organisation = "ORGNAME",
[string]$project = "PROJECTNAME",
[string]$keepForever = "true",
[string]$user = "userid",
[string]$token = "tokenID" )
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
Write-host $base64AuthInfo
$postresults = "https://vsrm.dev.azure.com/$organisation/$project/_apis/release/definitions?api-version=6.0"
Write-host $postresults
$body =
#"
{ "name": "New release pipeline ",
"comment": "test",
"definitionId": 860,
"description": "Create Release from PowerShell",
"artifacts": [],
"isDraft": false,
"reason": "Demo purpose",
"manualEnvironments": null,
"environmentsMetadata": null,
"properties": null,
"variables": null
"environments": [
{
"name": "PROD",
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": false,
"isNotificationOn": false,
"approver": {
"displayName": null,
"id": ""
},
"id": 0
}
]
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 0
}
]
},
"deployPhases": [
{
"deploymentInput": {
"parallelExecution": {
"parallelExecutionType": "none"
},
"skipArtifactsDownload": false,
"artifactsDownloadInput": {},
"queueId": 391,
"demands": [],
"enableAccessToken": false,
"timeoutInMinutes": 0,
"jobCancelTimeoutInMinutes": 1,
"condition": "succeeded()",
"overrideInputs": {}
},
"rank": 1,
"phaseType": "agentBasedDeployment",
"name": "Run on agent",
"workflowTasks": []
}
],
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
}
}
],
"path": "\\",
"releaseNameFormat": "Release",
"description": ""
}
"# | ConvertTo-Json -Depth 100
$result = Invoke-RestMethod -Uri $postresults -Method Post -Body $body -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
if ($result.count -eq 0)
{
throw "Unable to locate Release Definition Id $($definitionId)"
}
else
{
Write-host "Success!!!"
}
You have few issues in the json body:
The description exist twice.
You have missing , near the "variables": null.
You need to specify a valid id in the preDeployApprovals:
"approver": {
"displayName": null,
"id": "PUT-HERE-ID"
},
Add the above section also to the
You don't need to convert it again to json, remove the | ConvertTo-Json -Depth 100 from the code.