MSGraph - Invoke-WebRequest (403) Forbidden - json

I have a delegate App with Directory.ReadWrite.All permissions and a PS script to auth users over the app. It works when I use GET but I'm getting Forbidden when try PATCH method
Here's the part of that script:
$uri = "https://graph.microsoft.com/v1.0/devices/1111-2222-3333-4444-5555"
$method = "PATCH"
$body = '{
"extensionAttributes": {
"extensionAttribute2": "text"
}
}'
Invoke-WebRequest -Method $method -Uri $uri -Body $body -ContentType "application/json" -Headers #{Authorization = "Bearer $token"} -UseBasicParsing -ErrorAction Stop
Another thing: when using device ObjectID to construct Uri I'm getting the 403 Forbidden but if I use a $filter over a DeviceID I get 405 Method not allowed. Does it mean it doesn't like a filter and have to stick with the ObjectID? Is there a way when I run the GET with $filter to save in a variable only ObjectID within JSON query?
Thanks

sorted it, I needed Directory.AccessAsUser.All and used this to get the objectId variable:
$DsregCmdStatus = dsregcmd /status
if($DsregCmdStatus -match "DeviceId")
{
$DeviceId = $DsregCmdStatus -match "DeviceID"
$DeviceId = ($DeviceId.Split(":").trim())
$DeviceId = $DeviceId[1]
}
# Find Id
$uri = "https://graph.microsoft.com/v1.0/devices?`$filter=deviceId eq '$DeviceId'"
$method = "GET"
# Run Graph API query
$query = Invoke-WebRequest -Method $method -Uri $uri -ContentType "application/json" -Headers #{Authorization = "Bearer $token"} -UseBasicParsing -ErrorAction Stop
$output = ConvertFrom-Json $query.Content
$id = $output.value
$id = $id.id
Write-Host "Machine ID is $id"

Related

PowerShell JSON Headers not Converting correctly

I am using an API REST call, but the problem is that it for some reason is not passing the header value correctly. I am getting an error about it not converting from "System.String" to "System.Collections.IDictionary".
The code is:
$Headers = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]'
$Headers.Add('X-CENTRIFY-NATIVE-CLIENT', 'true')
$Headers.Add('Content-Type', 'application/json')
$Body = #{
TenantId = 'ID'
User = 'cloudadmin#andrew1.com'
Version = '1.0'
}
#$wr = Invoke-WebRequest -Method Post -Uri $url -Headers $Headers -Body $Body -Verbose
Invoke-RestMethod -Uri "https://uri/Security/StartAuthentication" -Method Post -Headers ($Headers | ConvertTo-Json -Compress) -UseBasicParsing -Body $Body
But when I execute I get this error (FQID):
Invoke-RestMethod : Cannot bind parameter 'Headers'. Cannot convert the "{
"X-CENTRIFY-NATIVE-CLIENT": "true",
"Content-Type": "application/json"
}" value of type "System.String" to type "System.Collections.IDictionary".
At line:31 char:109
+ ... tication" -Method Post -Headers ($Headers1 | ConvertTo-Json) -UseBas ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-RestMethod], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I have tried my headers being like this as well:
$headers = #{
'Content-Type'= 'application/json'
'X-CENTRIFY-NATIVE-CLIENT'= 'true'
}
But I still get that same error. It is odd that it keeps complaining about this reference; This library is not native to PoSH. Is there a DLL I should load or is there a better way to go about this?
The -Headers parameter expects a dictionary, not a json object.
Pass $Headers directly:
$uri = "https://uri/Security/StartAuthentication"
Invoke-RestMethod -Uri $uri -Method Post -Headers $Headers -UseBasicParsing -Body $Body
You can inspect parameter details with Get-Help:
PS > Get-Help Invoke-WebRequest -Parameter Headers
-Headers <IDictionary>
Required? false
Position? Named
Accept pipeline input? false
Parameter set name (All)
Aliases None
Dynamic? false
I took the json conversion out of the header on your invoke restmethod. That part will need to be done on your payload $Body. Give this a try.
$Headers = #{}
$Headers.Add('X-CENTRIFY-NATIVE-CLIENT', 'true')
$Headers.Add('Content-Type', 'application/json')
$Body = #{
TenantId = 'ID'
User = 'cloudadmin#andrew1.com'
Version = '1.0'
}
$Body = ($Body | ConvertTo-Json)
#$wr = Invoke-WebRequest -Method Post -Uri $url -Headers $Headers -Body $Body -Verbose
Invoke-RestMethod -Uri "https://uri/Security/StartAuthentication" -Method Post -Headers $Headers -UseBasicParsing -Body $Body

Running multiple iteration API calls using Powershell

I need to run 1000 API calls for 1000 different URI's. I tried to run 1000 different URI in one go as shown below but the API has a limit of 1000 lines.
Is there a way to run this code 1000 times producing 1000 separate JSON files or in one JSON file without me having to run the URI with the powershell script indivdiually.
$access_token ="dfdfgdfgf45h5676rdffghfghfbazbfgjvdrtwsffrgr"
$LogPath ='C:\StackOVerflow'
$URI = 'https://api.web.ser/audits/a_80weqwepeopeoA'
'https://api.web.ser/audits/a_B0980kdfl;skfd'
'https://api.web.ser/audits/a_Csdfsdfsjlksdc'
'https://api.web.ser/audits/a_Tlksdjfalkjdff'
'https://api.web.ser/audits/a_Fldkfjlsfjdfdl'
'https://api.web.ser/audits/a_Fsdfsdfsdfsd34'
'https://api.web.ser/audits/a_G34gfgf4ffsdrf'
'https://api.web.ser/audits/a_Haere34534fdgf'
'https://api.web.ser/audits/a_Ifdl023lererew'
'https://api.web.ser/audits/a_Afrererl45645w'
$headers = #{“authorization” = “Bearer $access_token”}
$result = Invoke-RestMethod -Uri $URI -Headers $headers |ConvertTo-Json| out-file "$LogPath\id_ExtractLogs$(((get-date).ToString("yyyyMMdd"))).json"
$result
You cannot pass an array of uri to the Invoke-RestMethod cmdlet; they must be iterated.
Here's a working solution:
$uri = 'https://api.web.ser/audits'
$reportList = #(
'a_80weqwepeopeoA'
'a_B0980kdfl;skfd'
# .. etc.
)
$token = 'secret'
$headers = #{ Headers = #{ Authorization = "Bearer $token" }}
$logPath = 'C:\StackOverflow'
foreach ($report in $reportList) {
$stamp = Get-Date -Format FileDateTime
Invoke-RestMethod -Uri "$uri/$report" -OutFile "$logPath\id_$stamp.json" #headers
}

CURL script to powershell

I am trying to convert curl to powershell with Invoke-RestMethod for onesignal push
the script that is used for onesignal:
curl --include \
--request POST \
--header "Content-Type: application/json; charset=utf-8" \
--header "Authorization: Basic YOUR_REST_API_KEY" \
--data-binary "{\"app_id\": \"YOUR_APP_ID\",
\"contents\": {\"en\": \"English Message\"},
\"included_segments\": [\"Subscribed Users\"]}" \
https://onesignal.com/api/v1/notifications
I have tried with following example which I was using for pushover but without success.
$uri = "https://onesignal.com/api/v1/notifications"
$parameters = #{
app_id = 'YOUR_APP_ID'
contents = "en: English Message"
included_segments = 'Subscribed Users'
data = 'foo:bar'
}
$parameters | Invoke-RestMethod -Uri $uri -Method Post
I have used this powershell script for pushover which worked fine, but now I want to move to onesignal and I have problems with where/how to put rest api key inside with already using app_id to push messages forward to users.
The code is snatched from: https://documentation.onesignal.com/v5.0/reference#section-example-code-create-notification
I hope that someone can assist me with this problem.
Regards
Try the following
$basicAuth = "Basic REST_API_KEY";
$headers = #{ Authorization = $basicAuth };
$uri = "https://onesignal.com/api/v1/notifications";
$body = #{ app_id = 'YOUR_APP_ID'; contents = #{ en = 'English Message' }; included_segments = #('Subscribed Users'); data = #{ foo = 'bar' }} | ConvertTo-Json;
Invoke-RestMethod -Method Post -Uri $uri -Headers $headers -ContentType "application/json; charset=utf-8" -Body ([System.Text.Encoding]::UTF8.GetBytes($body));
I have no idea how this endpoint works but it should work something like this:
$key = "Basic RESTAPIKEY"
$headers = #{}
$headers.Add("Authorization",$Key)
$headers.Add("Content-Type","application/json; charset=utf-8")
$uri = "https://onesignal.com/api/v1/notifications"
$parameters = #{
app_id = 'YOUR_APP_ID'
contents = "en: English Message"
included_segments = 'Subscribed Users'
data = 'foo:bar'
} | ConvertTo-Json
Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes($parameters)) -ContentType "application/json"
If the data-binary part is sent with PowerShell you could also use the -InFile parameter from Invoke-RestMethod.
If just read a little at the link you posted and think the body part should be like the following:
$parameters = #{
app_id = "5eb5a37e-b458-11e3-ac11-000c2940e62c"
included_segments = "Array of active users"
data = #{
foo = "bar"
}
contents = #{
en = "English Message"
}
} | ConvertTo-JSON

Powershell Script to create user and add to servicedesk suddenly not working

last year I created a PS script, that took care of automatically creating users and adding them to our servicedesk, we use a special user creation account for this, the credentials are locally saved in a text file. It all worked fine, however the script doesn't seem to work anymore, did the JIRA API change?
I get following error message: Invoke-Rest-Method: The remote server returned an error (401) Unauthorized at response = Invoke-Rest-Method -Uri...etc
I checked and our user creation account still has all the permissions to create users, I can manually create them and the log shows that the user also logs in normally through the script.
Hopefully somebody can help with my problem!
Here's the code:
$jiraCredentials = Get-Content -Raw -Path "C:\PowerShellScripts\New-AdUser\credentials.json" |ConvertFrom-Json
$bytes = [System.Text.Encoding]::ASCII.GetBytes("${$jiraCredentials.username}:${$jiraCredentials.password}")
$base64 = [System.Convert]::ToBase64String($bytes)
$basicAuthValue = "Basic $base64"
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", $basicAuthValue)
$headers.add("X-Experimentalapi", "opt-in")
$headers.add("Content-Type", "application/json")
#$headers.add("X-Atlassian-Token", "nocheck")
$JSON = #"
{
"fullName": "$emailAddressClean",
"email": "$emailAddressClean"
}
"#
$response = Invoke-RestMethod -Uri https://jira.dilax.com/rest/servicedeskapi/customer -Method POST -Body $JSON -ContentType "application/json" -Headers $headers
#add customer to servicedesk
$JSON2 = #"
{
"usernames":[
"$emailAddressClean"
]
}
"#
$response2 = Invoke-RestMethod -Uri https://jira.dilax.com/rest/servicedeskapi/servicedesk/9/customer -Method POST -Body $JSON2 -ContentType "application/json" -Headers $headers
managed to fix it because the log in credentials didn't get transmitted correctly:
$jiraCredentials = Get-Content -Raw -Path "C:\PowerShellScripts\New-AdUser\credentials.json" |ConvertFrom-Json
$user = $jiraCredentials.username
$pass = $jiraCredentials.password
$pair = "${user}:${pass}"
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
$basicAuthValue = "Basic $base64"

Invoke-RestMethod Powershell V3 Content-Type

I am able to use the JIRA rest API from powershell v5. However the same code throws the below error in powershell v3.
WARNING: Remote Server Response: The 'Content-Type' header must be modified using the appropriate property or method.
Source Code
$basicAuth = "Basic " + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Username):$Password"))
$headers = #{
"Authorization" = $basicAuth
"Content-Type"="application/json"
}
$response = Invoke-RestMethod -Uri $requestUri -Method POST -Headers $headers -Body $body
Invoke-Restmethod has a -ContentType parameter, so the error seems to be indicating you should use that to specify Content Type instead of passing it via the headers parameter:
$basicAuth = "Basic " + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Username):$Password"))
$headers = #{
"Authorization" = $basicAuth
}
$response = Invoke-RestMethod -Uri $requestUri -Method POST -Headers $headers -Body $body -ContentType 'application/json'