PowerShell and Google Calendar - 400 Error when creating event - powershell

so this'll be the first time posting on the Google Dev Forum, fingers crossed I can get this resolved as I am pulling my hair out!
I have the following script in PowerShell. I have sorted the OAuth2 and I am able to hit my Calendar API and see the hits in the dashboard. So, authentication is fine. I used the API Explorer to get a rough idea of what I would need to send in order to create a new Calendar event, but in doing so I get a 400 error.
Here's the section I am running:
$requestUri = "https://www.googleapis.com/calendar/v3/calendars/mysite#blah.com/events?"
$body=#{
end='dateTime:2017-06-07T08:30:00+01:00'
start='dateTime:2017-06-07T08:00:00+01:00'
}
$json = $body | ConvertTo-Json
$header=#{Authorization = "Bearer $($tokens.access_token)"}
Invoke-RestMethod -Headers $header -Uri $requestUri -Method POST -Body
$json -ContentType 'application\json' -TransferEncoding gzip
Here is the error I receive:
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
$json is formed like this:
{
"end": "dateTime:2017-06-07T08:30:00+01:00",
"start": "dateTime:2017-06-07T08:00:00+01:00"
}
I can remove transferEncoding and I get the same error.
As always, any help would be great :)
thanks

Moving my comment to an answer, the -ContentType looks weird with a backslash in it, and maybe it should be a forward slash, e.g.
$json -ContentType 'application/json'

Related

Graphi API - Creating Document Set with Invoke-RestMethod

I need some help to get my code to create a Document Set in SharePoint Online using Graph API directly from a PowerShell script using Invoke-RestMethod.
I tested the request under the Graph Explorer portal and it works fine and I get a nice HTTP 201 (OK) as seen on the picture below:
Trying the very same request from my PowerShell script fails and returns HTTP 400 (Bad Request), I can't get the folder created and that is the first step to get the document set created, according to my research and an example found here:
Is it possible to create a project documentset using graph API?
As the first step mentioned in the example above, I need to first create the folder and then proceed to the following steps to achieve the creation of the document set but I can't get this first step done.
My application has the necessary permissions as I tested in the Graph Explorer:
Files.ReadAndWrite.All
Sites.ReadAndWrite.All
Sites.FullControl.All (not required but I had to try this one to make sure!)
I'm on the second step (folder creation) and I can't get past this point, according to the link above, once I get this working I will need to get the new folder ID, and then send a new PATCH to alter its content type to match the desire document set, I hope I can get some help, all the examples are vague and pretty much describe only on what to do but no actual functional code to sample from.
Thanks in advance!
$uri = "https://graph.microsoft.com/v1.0/drives/b!yVnguUBzyUC1PxgTM0JP-_ERFp1PTZFCjycaWZK6yKulBi9Ce_J8RIfF-OkWKE4B/root/children"
$headers = #{
"Authorization" = "$($token.token_type) $($token.access_token)"
"Content-Type" = "application/json"
}
$body = #{
"name" = "Test"
"folder" = {}
"#microsoft.graph.conflictBehavior" = "rename"
}
$request = Invoke-RestMethod -Headers $headers -Body $body -Method Post -Uri $uri
It should work when you modify $body like this
$body = #{
"name" = "Test"
"folder" = #{}
"#microsoft.graph.conflictBehavior" = "rename"
} | ConvertTo-Json
$body is a JSON object and you need to convert it to JSON. For initialing an empty folder object you have to use #{} instead of {}.
Thanks #user2250152, you gave me a great idea by solving part of the problem!
I did add the conversion to JSON as you recommended and decided to add the content-type back to my original header and it did the trick!
Adding the content-type solved the issue but your collaboration was essential, so thank you very much!
Now wish me luck to get the other steps done and achieve the conclusion of this thing!
$headers = #{
"Authorization" = "$($token.token_type) $($token.access_token)"
"Content-Type" = "application/json"
}

Invoke-WebRequest return only 100 value

I run this code and only returning the first 100 records, not sure why.
Can you please advise?
I belive this is what I should modify but don't know how:
$select=displayName,userPrincipalName,signInActivity
This is the full code:
Invoke-WebRequest -Headers $AuthHeader1 -Uri "https://graph.microsoft.com/beta/users?`$select=displayName,userPrincipalName,signInActivity" -UseBasicParsing
Update:
$LastLogin = Invoke-WebRequest -Headers $AuthHeader1 -Uri "https://graph.microsoft.com/beta/users?`$top=999&$select=displayName,userPrincipalName,signInActivity&$skiptoken=Paged=TRUE&$odata.nextlink" -UseBasicParsing
$NextLink = $LastLogin."#odata.nextLink"
$LastLoginpage2 = Invoke-WebRequest -Method Get -Headers $AuthHeader1 -Uri '$NextLink' -UseBasicParsing
Thanks.
Gabor
By default every API has its own limit per page to give number of records as a response. Here the /users gives 100 users per page and additionally it gives a #odata.nextLink as a reference to the next page as shown below in the image.
You can use the odata.nextLink and make another call and get the next page of users.
If you want to modify the limit per page, you can use $top query parameter to get 200 or 300 user objects per page. Use the below query to get 200 records per page.
GET https://graph.microsoft.com/v1.0/users?$top=200&$select=displayName,userPrincipalName,signInActivity

Invoke-WebRequest with a random token + forms unavailable

Website I am attempting to do this on: https://www.netvendor.net/login
I am trying to login to the website automatically and kick off a script to create users in bulk for us.
If you run an Invoke-WebRequest on this page, it returns information, but nothing about the forms. They are simply not displayed. However, if you view the page source or inspect element, there are clearly forms on the page and they are not composed of JS or anything else that would mess it up. How can I get PowerShell to recognize these fields? I am using the following command:
Invoke-WebRequest -Uri "www.netvendor.net/login" -Method GET -UseBasicParsing
Because of the issue above, I decided I would just POST the information I needed by examining the request. The request requires three things:
email
password
_token
Unfortunately, the token is randomly generated each time a browser session is initiated. If you view source on the page and search for "_token", you will get the parameter that is needed. It doesn't seem like there is any way to retrieve this from the page? I am a bit lost as to what I can do at this point, especially since there is no API or anything else for me to work with.
For all interested, here is the final working script:
$nvlogin = Invoke-WebRequest "https://www.netvendor.net/login" -SessionVariable "netvendor"
$nvtoken = $nvlogin.InputFields.Where({ $_.Name -eq "_token" })[0].Value
$nvbody = #{
"_token" = $nvtoken
"email" = "your.name#website.com"
"password" = 'credentials'
}
Invoke-WebRequest -Uri "https://www.netvendor.net/login" -WebSession $netvendor -Method 'POST' -Body $nvbody

Error while updating VSTS release definition from powershell

I use the APIs listed in the VSTS API documentation here. On modifying a variable and saving the definition the error I get from the server is VS402982: Retention policy is not set for the environment 'environmentName'.
The portion of the PS script that performs the update is -
$c = Invoke-WebRequest 'https://accountname.vsrm.visualstudio.com/projectname/_apis/release/definitions/definitionId' -Method Get -Headers #{Authorization = 'Bearer ' + $authtoken}
$jsonObj = $c | ConvertFrom-Json
$url3 = "https://accountname.vsrm.visualstudio.com/projectname/_apis/release/definitions/definitionId?api-version=4.1-preview.3";
$contentType3 = "application/json"
$headers3 = #{
Authorization = 'Bearer ' + $authtoken
};
$d = $jsonObj | ConvertTo-Json;
Invoke-RestMethod -Method PUT -Uri $url3 -ContentType $contentType3 -Headers $headers3 -Body $d;
What could be wrong here?
This problem has been reported a couple of times in different forms, and is mostly related to a small problem with the powershell code in the question.
If you see error like the one mentioned in the question or this - VS402903: The specified value is not convertible to type ReleaseDefinition. Make sure it is convertible to type ReleaseDefinition and try again it means that there is a problem in the JSON object that you are posting to the server. Easiest problem will be to capture the request payload and analyse it for issues.
However, in the code mentioned in the question, the problem lies with powershell's ConvertTo-JSON method. Do note, the release definition has multiple layers of nested objects, definition -> environment -> steps/approvals etc, and ConvertTo-JSON by default goes only 2 levels deep to form a JSON object, which means you are missing some vital properties while calling the VSTS APIs. The fix would be to specify a large value for the -Depth parameter so that you do not miss any properties while calling the service.
eg. ConvertTo-Json -Depth 100
More details on the problem and how it's fixed in the script can be seen here.
Additionally to divyanshm's solution make sure encoding is correct:
$d = [Text.Encoding]::UTF8.GetBytes($d)

Checking if a Rest Call succeeds in PowerShell

I'm currently writing a PowerShell script that will remove all users from a tool via Rest API. The current script works as intended but is lacking in error handling. The only thing I want to check for is if the Rest Call is successfully completed. After googling, I couldn't really find much or maybe I'm searching the wrong terms. Any thoughts or direction is much appreciated!
Here's an example of code I've used successfully (assuming you've defined Uri, Headers, and Body if required - also note the Method here is set to Post):
try
{
Write-Verbose "Calling $Uri"
Invoke-RestMethod -Uri $Uri -Method Post -Headers $Headers -Body $Json -ContentType 'application/json' -ErrorAction Stop
}
catch
{
throw $_
}