I am trying to make an API call to update one devicegroup in each loop using the reference ID. I am able to fetch token but having issue when using PUT to update the devicegroup. Here is what i tried so far:
$Header1 = #{}
$Header1["Authorization"] = "Bearer " + $Token
try
{
#Using /devices to get the group level path as I am trying to update a customattribute on group level instead of each device
$response1 = Invoke-RestMethod -Uri "https://$MCFQDN/MobiControl/api/devices" -Headers $Header1
#Using /devicegroups for reference ID
$response2 = Invoke-RestMethod -Uri "https://$MCFQDN/MobiControl/api/devicegroups" -Headers $Header1
}
catch
{
$($_.Exception.Message)
}
foreach ($path1 in $response1)
{
foreach ($path2 in $response2)
{
if ($path1.Path -eq $path2.Path)
{
$refid = "referenceId:" + $path2.ReferenceId
#$refid = [System.Web.HttpUtility]::UrlEncode($refid) #tried encoding refid but no use
$uri = "https://$MCFQDN/MobiControl/api/devicegroups/$refid/customAttributes/{Custom_Attribute_Name}"
#This is the value for my Custom_Attribute_Name
$groupname = ($path2.Path).split('\')[-1]
$Body1 = #{}
$Body1["customAttributeValue"] = $groupname
# tried $Body1 = #{$groupname} but in vain
Invoke-RestMethod -Uri $uri -Method PUT -Body ($Body1 | ConvertTo-Json) -Headers $Header1 -ContentType "application/json"
}
}
}```
When trying to execute the above, getting below error:
*Invoke-RestMethod : {
"$type": "ErrorDetails",
"ErrorCode": 0,
"Message": "Contract validation failed",
"Data": [
"customAttributeValue: Error parsing value"
],
"HelpLink": null
}*
Any help is greatly appreciated.
Based off a brief test on the api page (https://FQDN/MobiControl/api). I receive the same “customAttributeValue: Error parsing value” error if I don’t quote the customAttributeValue value itself with single or double quotes. Try amending your $groupname variable with that in mind.
Related
need help here: I have this api which i run in Postman (https://dev.azure.com/abc/Abc/_apis/build/builds/24169/workitems?api-version=4.1), I get result as
{
"count": 50,
"value": [
{
"id": "21610",
"url": "https://dev.azure.com/abc/_apis/wit/workItems/21610"
},
{
"id": "21606",
"url": "https://dev.azure.com/abc/_apis/wit/workItems/21606"
}]}
I need to call this in Powershell, and get a list of all IDs. I am doing this way but I am not getting anything..what wrong am I doing?
Function GET-RELEASEWIT {
$AzureDevOpsPAT ='psgklxbjircg5g5fda'
$AzureDevOpsAuthenicationHeader = #{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($AzureDevOpsPAT)")) }
$uriAcc = "https://dev.azure.com/abc/ABC/_apis/build/builds/24169/workitems?api-version=4.1"
write-host $uriAcc
$responseRelW = Invoke-RestMethod -Uri $uriAcc -Method get -Headers $AzureDevOpsAuthenicationHeader
write-host $responseRelW
$BID = #()
$BID += $responseRelW.value.id
write-host "********START****************"
write-host $BID
}
I've tried the below and it works. Only difference I can see is that I've used UTF8.GetBytes instead of ASCII.GetBytes when converting the PAT token to a base64 string, which shouldn't cause any difference since the character mappings are the same.
$uri = "https://dev.azure.com/abc/ABC/_apis/build/builds/24169/workitems?api-version=4.1"
$AzureDevOpsPAT ='psgklxbjircg5g5fda'
$B64Pat = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$AzureDevOpsPAT"))
$headers = #{ Authorization = "Basic $B64Pat" }
Invoke-RestMethod -Uri $uri -Headers $headers
Note the URI and PAT token are obviously different when I tested this, but this should work for you.
I am just starting out with REST API and the only language I have available to me is PowerShell
I am calling a list of "things" - this works and I get the ID property
I then try to iterate through that list and get a more detailed record for the "thing" (The second Invoke-RestMethod) - when I attempt this I get an error:
Invoke-RestMethod : {"reply": {"err_code": 500, "err_msg": "Got an invalid input while processing XDR public API", "err_extra": "request_data must be of type: dict"}}
I thought that convertto-json would convert the hashtable "request" to a dictionary.
I am new to this so please don't assume I know anything.
$ContentType = "application/json"
$URL_All = 'https://api-<company>.xdr.eu.paloaltonetworks.com/public_api/v1/endpoints/get_endpoints/'
$URLEndpoint = 'https://api-<company>.xdr.eu.paloaltonetworks.com/public_api/v1/endpoints/get_endpoint/'
$endpoints = Invoke-RestMethod -uri $URL_All -method POST -Headers #{"x-xdr-auth-id" = "1"; "Authorization" = "<API-KEY_Goes_Here>" } -ContentType "application/json" -Verbose
if ($endpoints.reply.count -gt 0){
write-host "Found $($endpoints.reply.count) details"
}
else {
write-host " API didn't return any endpoint - ending script "
break
}
foreach ($endpoint in $endpoints.reply) {
if($endpoint.agent_id -ne $null){
$request = #{
request_data = '{}'
filters = #{
field = "endpoint_id_list"
operator = "in"
Value = "$($endpoint.agent_ID)"
Search_from = 0
Search_to = 1
sort = #{
field = "last_seen"
keyword = "desc"
}
}
} | ConvertTo-Json
$Endpoint_full += Invoke-RestMethod -uri $URLEndpoint -method POST -Body $request -Headers #{"x-xdr-auth-id" = "1"; "Authorization" = "<API-KEY_Goes_Here>" } -ContentType "application/json" -Verbose
}
}
Your JSON conversion isn't the issue, the hint is in the error message.
"request_data must be of type: dict"
Key being request_data which just consists of this in your request:
request_data = '{}'
Ie. it's basically blank while the API expects a hash table or similar structure.
I am trying to use a REST API to configure some alerts in RecoverPoint for Virtual Machines (RP4VM). I am trying to enter multiple filters at the same using json. The json file looks like this:
[
{
"JsonSubType": "SystemEventLogsFilter",
"level": "WARNING",
"scope": "NORMAL",
"eventsIDs": [],
"filterUID": {
"id": 1570417688566256135
},
"name": "RPA_issue",
"topic": "RPA",
"groupsToInclude": null
},
{
"JsonSubType": "SystemEventLogsFilter",
"level": "WARNING",
"scope": "ADVANCED",
"eventsIDs": [],
"filterUID": {
"id": -1728986321682574312
},
"name": "cluster_events",
"topic": "CLUSTER",
"groupsToInclude": null
}
]
When I try to run the script I get an error:
Unexpected token (START_ARRAY), expected START_OBJECT: need JSON Object to contain As.PROPERTY type information (for class com.emc.fapi.version5_2.commons.SystemEventLogsFilter)
at [Source: org.apache.catalina.connector.CoyoteInputStream#75b592c2; line: 1, column: 1]
If I remove the square brackets it does the first value but not the second. Is this an issue with my code or an issue with theirs?
The script:
$rp4vmcl = import-csv -Path .\test_clusters.csv
$credential = Get-Credential
$username = $credential.GetNetworkCredential().UserName
$password = $credential.GetNetworkCredential().password
$credPair = "$($username):$($password)"
$encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credPair))
$headers = #{
Authorization = "Basic $encodedCredentials";
"Accept" = "application/json";
"Content-Type" = "application/json"
}
$comp = "/system/event_logs_filters"
$json = Get-Content .\event_log_filter.json -Raw
foreach ($s in $rp4vmcl) {
$cluster = $s.cluster_name
$uid = $s.cluster_uid
$curl = $s.cluster_url
$url = "$curl$comp"
$cluster
$results = Invoke-RestMethod -Method POST -uri $url -SkipCertificateCheck -Headers $headers -Body $json
}
If the recipient expect one Call per Json Object it will not be able to handle arrays. It's totally dependant from the implementation of the webservice. Btw, better change the body:
$results = Invoke-RestMethod -Method POST -uri $url -SkipCertificateCheck -Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes($json))
Try this first, and if this is doesnt help, loop through the elemnts and call the webservice individual:
$jsonObject = $json | ConvertFrom-Json
$results = #()
$jsonObject | foreach {
$json = $_ | ConvertTo-Json -Depth 99
$results += Invoke-RestMethod -Method POST -uri $url -SkipCertificateCheck -Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes($json))
}
Btw, the invoke-restmethod is buggy in powershell < 6 Version, so if youre will with the standard V5 Windows Version, check the response headers via invoke-webservice, and if the response header is:
"application/json"
and not
"application/json; charset=utf-8"
powershell will misinterpret this as a windows encoding. So if youree experiencing encoding issues, you have four options:
1.) if you can modify the webservice, change the response header
2.) switch to a newer powershell version (v7 is recommended)
3.) build your own webservice call directly via the .net cmdlets
4.) use the invoke-webservice, write the answer directly into a file with the OutFile Paramater
see also:
Powershell Invoke-RestMethod incorrect character
The Powershell code bellow writes and reads values to Google Sheets (works fine) and should run the function myfunction in an Apps Script project using API, but Invoke-WebRequest returns the error bellow:
Invoke-WebRequest : 404. That’s an error. The requested URL /v1/scripts/=ya29.a0Ae4lvC3k8aahOCPBgf-tRf4SRFxdcCE97fkbXLAJqZ4zRCLnBp9prwEcBYBAf
lYP6zyW3fLeD3u4iSw5jYtDAdgZiSsTjzQbCpj9e_ahCA0xwC_1NBTjYkPwqFdLli7LNpfFcuedFDhdUpfnKTRZdbBWIf2ZyxyuGc6p was not found on this server. That’s
all we know.
No C:\Users\F76254C\Desktop\Nova pasta\Batch files\Available Projects\Latam HIL Lab Menu\libs\Google\WriteToGoogleSheets.ps1:64 caractere:13
+ $resp = Invoke-WebRequest -Uri "https://script.googleapis.com/v1/ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
I am not sure if the JSON representation of request body is set correctly or if the error was caused for something else.
Powershell Code:
function doit{
$json = ".\client_id.json"
$jdata = get-content $json | convertfrom-json
<#
$jdata | ForEach-Object {
$_.PSObject.Properties.Value
}
#>
$ClientID = $jdata.web.client_id.ToString()
$ClientSecret = $jdata.web.client_secret.ToString()
$refreshToken = "1//04VvG_FTyDGhiCgYIARAAGAQSNwF-L9IrZ-o1kaZQQccvzL5m4TUTNz6b9Q4KCb16t4cH11gGCshWZWvgaCoMlg73FgpLAGOYTEk"
$grantType = "refresh_token"
$requestUri = "https://accounts.google.com/o/oauth2/token"
$GAuthBody = "refresh_token=$refreshToken&client_id=$ClientID&client_secret=$ClientSecret&grant_type=$grantType"
$GAuthResponse = Invoke-RestMethod -Method Post -Uri $requestUri -ContentType "application/x-www-form-urlencoded" -Body $GAuthBody
$accessToken = $GAuthResponse.access_token
$headers = #{"Authorization" = "Bearer $accessToken"
"Content-type" = "application/json"}
$DocumentID = "1htbeGlqZ4hojQBWl9fxE4nW_KZI9uVwi0ApzNOIbwnY"
$currentDate = (Get-Date).ToString('MM/dd/yyyy')
$currentTime = (Get-Date).ToString('HH:mm:sstt')
$json = #”
{
"range": "HIL_APP!A1:G1",
"majorDimension": "ROWS",
"values":
[[
"HIL_NAME",
"$env:ComputerName",
"$currentDate",
"$currentTime",
"$env:UserName",
"input from user",
"attempt"
],]
}
“#
$write = Invoke-WebRequest -Uri "https://sheets.googleapis.com/v4/spreadsheets/$DocumentID/values/HIL_APP!A1:G1:append?valueInputOption=USER_ENTERED&access_token=$($accessToken)" -Method Post -ContentType "application/json" -Body $json
$read = Invoke-WebRequest -Uri "https://sheets.googleapis.com/v4/spreadsheets/$DocumentID/values/HIL_APP!A1:G1?access_token=$($accessToken)"
Write-Output "Response: " ($read.Content | ConvertFrom-Json)
$scriptId = "1eF7ZaHH-pw2-AjnRVhOgnDxBUpfr0wALk1dVFg7B220bg_KuwVudbALh"
$json = #”
{
"function": "myfunction",
"parameters": [
"attempt" string
],
"devMode": true
}
“#
$resp = Invoke-WebRequest -Uri "https://script.googleapis.com/v1/scripts/$scriptId:run?access_token=$($accessToken)" -Method Post -ContentType "application/json" -Body $json
# Write-Output "Response: " ($resp.Content | ConvertFrom-Json)
}
clear
doit
EDIT:
Google App Script code:
function toSpreadsheet(text2write)
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("HIL_APP");
for (var i = 1; i < sheet.getLastRow(); i++)
{
sheet.getRange(i+1, 8, 1).setValue(text2write)
}
return "myreturn"
}
function myfunction(params)
{
toSpreadsheet(params)
}
You could confirm that the script for writing and reading values for Google Sheets worked fine.
You want to modify only the script for running the Google Apps Script using Apps Script API.
You have already been able to use Apps Script API.
Your access token can be used for running the Google Apps Script.
You want to achieve this using Invoke-WebRequest of powershell.
Modification points:
From your error message and your script, I would like to propose the following modification points.
From "https://script.googleapis.com/v1/scripts/$scriptId:run?access_token=$($accessToken)" to "https://script.googleapis.com/v1/scripts/${scriptId}:run"
In your script, the endpoint is https://script.googleapis.com/v1/scripts/. This is incomplete endpoint.
I think that the reason of your current error message is due to this.
Please use the access token at the request header instead of the query parameter. Ref
I think that this can be also said for using Sheets API.
I think that "attempt" string is "attempt".
Please modify ” to ".
Modified script:
When the request to Apps Script API in your script is modified, it becomes as follows.
$scriptId = "1eF7ZaHH-pw2-AjnRVhOgnDxBUpfr0wALk1dVFg7B220bg_KuwVudbALh"
$json = #"
{
"function": "myfunction",
"parameters": ["attempt"],
"devMode": true
}
"#
$resp = Invoke-WebRequest -Uri "https://script.googleapis.com/v1/scripts/${scriptId}:run" -Method Post -ContentType "application/json" -Body $json -Headers #{"Authorization"="Bearer ${accessToken}"}
Note:
In my environment, I could confirm that above modified script worked. Unfortunately, I cannot understand about your flow for setting to run the Google Apps Script with Apps Script API. So if in your environment, an error occurs, please confirm the settings for running the script with Apps Script API, again.
I think that "Bearer ${accessToken}" can be also modified to "Bearer $accessToken".
Reference:
Executing Functions using the Apps Script API
I'm trying to create an event in a calendar in an Office 365 group via powershell.
This is my first experience to do this type of programming so sorry if my question will be very basic :-)
First, I created a simple json file (calendar.json)
{
"start":
{
"dateTime":"2017-03-12T17:00:00.0000000",
"timeZone":"UTC"
},
"end":
{
"dateTime":"2017-03-12T17:30:00.0000000",
"timeZone":"UTC"
},
"responseStatus": {
"response": "None"
},
"iCalUId": "null",
"isReminderOn": false,
"subject": "Test Event created from API"
}
Then I create the event with these steps:
Use a tested powershell function that give me the token
Add header with this code:
$headers = #{}
$headers.Add('Authorization','Bearer ' + $token.AccessToken)
$headers.Add('Content-Type',"application/json")
Because I'm starting now, I convert the json file in an object and then the object in json (I know, it's quite stupid, but I've done so beacuse I have no knowledge of json and how convert without error in powershell code)
$json = ConvertFrom-Json -InputObject (Gc 'C:\Users\mmangiante\OneDrive - Interactive Media S.p.A\Office 365\calendar.json'-Raw)
$body = ConvertTo-Json $json
Call the Invoke-RestMethod
response = Invoke-RestMethod 'https://graph.microsoft.com/v1.0/groups/768afb0c-bafd-4272-b855-6b317a3a9953/calendar/events' -Method Post -Headers $headers -Body $json
What is returned is a 400 bad request.
It's the same error of Sending Microsoft Graph request events returns 400
Given the answer given to that question I modified my code to return the error:
try{$restp=Invoke-RestMethod 'https://graph.microsoft.com/v1.0/groups/768afb0c-bafd-4272-b855-6b317a3a9953/calendar/events' -Method Post -Headers $headers -Body $json
} catch {$err=$_}
$err
like suggested in How do I get the body of a web request that returned 400 Bad Request from Invoke-RestMethod but I found nothing of interest.
The only thing that I found is that, at the time of writing, the Invoke-RestMethod doesn't return the full response as in this https://github.com/PowerShell/PowerShell/issues/2193
I suppose my json is not "well formed", but I don't know why.
Does anyone have a suggestion?
This formatting has worked for me in the past. Let me know if this resolves your issues:
$headers = #{
"Authorization" = ("Bearer {0}" -f $token);
"Content-Type" = "application/json";
}
$body = #{
Name1 = 'Value1';
Name2 = 'Value2';
}
$bodyJSON = $body | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri <API HERE> -Headers $headers -Body $bodyJSON -OutFile $output
Thanks Shawn,
I tried your suggestion but without luck; I have done other test with 2 other api and found discordant results.
The first test is to use the graph api related to contact, creating a contact as in https://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/user_post_contacts
I created the powershell representation of the sample json:
$contactbody = #{
givenName = 'Ciccio';
surname = 'Patacca';
emailAddresses = #(
#{
address = 'cicciopatacca#cicciociccio.com'
name = 'Ciccio Patacca'
}
)
businessPhones = (
'+39 555 123 4567'
)
}
and then converted in json
$contactbody = $contactbody | ConvertTo-Json
I retrieved from Azure Portal the object ID related to my user in my company and so I call the rest method:
$response = Invoke-RestMethod 'https://graph.microsoft.com/v1.0/users/e37d2dbe-bdaf-4098-9bb0-03be8c653f7d/contact' -Method Post -Headers $headers -Body $contactbody
The final result is a 400 bad request error.
So, I tried another example and reused some code retrieved from a google search.
This time I copied the powershell json representation as in the sample and converted:
$body = #{"displayName"="ps-blog"; "mailEnabled"=$false; "groupTypes"=#("Unified"); "securityEnabled"=$false; "mailNickname"="ps1" } | ConvertTo-Json
and, as stated in https://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/group_post_groups I called the rest method
$response = Invoke-RestMethod 'https://graph.microsoft.com/v1.0/groups' -Method Post -Headers $headers -Body $body
and this worked.
So I thought that the previously powershell representations of the sample with the error were not correctly formed (even if when I printed it they are equal to the samples on the graph api); for test, I rewritten the last powershell of the body as this:
$body = #{
displayName = 'TestGraphGroup';
mailEnabled = $true;
groupTypes = #('Unified')
securityEnabled = $false;
mailNickname = 'TestGraphGroup'
}
$body = $body | ConvertTo-Json
and invoked last method: it worked again.
So, where I'm doing wrong?
A new SDK was released that makes this easier.
Checkout instructions on how to use it here