REST API failure: Invoke-WebRequest : 404 - powershell

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

Related

Updating text file inside of Google Team Drive using Google Docs API- PowerShell

I have a powershell script currently that pulls in data from a Google Sheet on a team drive and then creates Active Directory users in our environment based on that data. I haven't gotten to fully test this part yet, but don't believe it will cause me any problems.
Where I am having issues is I would like to use a Team-Shared Google Drive Document to contain all of my logging for this automation.
I have had no issues authenticating but cannot seem to get the POST request correct for batchUpdating the document itself. I am able to obtain the revision Id without any problem. I cannot seem to find out where to pass the "batchUpdate" object in my request. I am not worried about where the text is stored on the page once it is added, just looking to add the text to the file.
Documentation:
https://developers.google.com/docs/api/reference/rest/v1/documents/batchUpdate#http-request
Here is how I am obtaining my access token
function Get-Auth{
#Obtains access token for the Google API's
#Runs everytime to ensure there is a fresh access token available to the service account
$refresh_body = #{
client_id='338139966542-qaa4me7l4fs0l1ltl2e6kjidjr9tf3up.apps.googleusercontent.com';
client_secret='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';
refresh_token='1//04GjkX_q30ioyCgYIARAAGAQSNwF-L9IrKggdZo-Pq9E_t3qEbmhHmQe8JVVDW4vaXGoeFiRxxJ5KRu7f7TpQVDsHrwMdmc7Xqn4';
grant_type="refresh_token";
}
#Makes a request to obtain the access token
$refresh_token = Invoke-RestMethod -Uri "https://www.googleapis.com/oauth2/v4/token" -Method POST -Body $refresh_body
$access_token = $refresh_token.access_token
}
Here is where I am attempting to update the document
$document = Invoke-RestMethod -Headers #{Authorization = "Bearer $access_token"} -ContentType "application/json" -Method GET -Uri "https://docs.googleapis.com/v1/documents/1K8_q_VCTWin_s8aVb0D16DNujqA72eravHojMfM9cyo"
$revId = $document.revisionId
$updateObject = {
requests = [
{
insertText= {
text= "The Red Dog Crosses the Road";
endOfSegmentLocation= {
segmentId= ""
}
}
}
]
writeControl= {
requiredRevisionId= $revId;
}
}
Invoke-RestMethod -Headers #{Authorization = "Bearer $access_token"} -ContentType "application/json" -Method POST -Uri "https://docs.googleapis.com/v1/documents/1K8_q_VCTWin_s8aVb0D16DNujqA72eravHojMfM9cyo:batchUpdate" -Body $updateObject
Here is the error I receive when trying to make this request.
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At line:39 char:1
+ Invoke-RestMethod -Headers #{Authorization = "Bearer $access_token"} ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExceptio
n
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I think I just need to find the correct place to put my batchUpdate object in the request, but I could be completely off. Any help would be much appreciated.
In your script, how about the following modification? I thought that the reason of your issue is due to the value of $updateObject and the request body of -Body $updateObject. In this case, the request body is required to be the string value. I thought that this might be the reason of your issue.
Modified script:
$document = Invoke-RestMethod -Headers #{Authorization = "Bearer $access_token"} -Method GET -Uri "https://docs.googleapis.com/v1/documents/1K8_q_VCTWin_s8aVb0D16DNujqA72eravHojMfM9cyo"
$revId = $document.revisionId
$updateObject = #{
requests = #(
#{
insertText = #{
text = "The Red Dog Crosses the Road";
endOfSegmentLocation = #{
segmentId = "";
}
}
}
)
writeControl = #{
requiredRevisionId = $revId;
}
}
Invoke-RestMethod -Headers #{Authorization = "Bearer $access_token"} -ContentType "application/json" -Method POST -Uri "https://docs.googleapis.com/v1/documents/1K8_q_VCTWin_s8aVb0D16DNujqA72eravHojMfM9cyo:batchUpdate" -Body (ConvertTo-Json -Depth 4 $updateObject)
Note:
When this script is run, I confirmed that the text of "The Red Dog Crosses the Road" is appended to the Google Document.
Reference:
Method: documents.batchUpdate

How to attach CSV file to Service Now incident via REST API using PowerShell?

I need to attach the file either xlsx or CSV to a particular incident via SNOW REST API using PowerShell script. I have tried with the below code:
if (!$script:ServiceNowCreds) {
$script:ServiceNowCreds = Get-Credential
}
$snow_url = 'https://dev652xx.service-now.com/api/now/table/incident'
$Body = #{
'number' = 'INC00xx059'
}
$result = Invoke-RestMethod -Uri $snow_url -Credential $script:ServiceNowCreds -Body $Body -ContentType "application/json"
$result.result | select sys_id, number | ForEach-Object {
$Upload_snow_url ='https://dev652xx.servicenow.com/api/now/attachment/upload'
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add('Content-Type','text/csv')
$headers.Add('Accept','*/*')
$sys_id = $_.sys_id
$incident_number = $_.number
$UploadBody = #{
'table_name'='incident';
'table_sys_id'=$sys_id;
'file_name' = 'C:\Users\suganthanraj.p\Documents\Servers.csv'
}
$uploadParam = $UploadBody | ConvertTo-JSon
Write-Host $sys_id
Write-Host $incident_number
$UploadResult = Invoke-RestMethod -Uri $Upload_snow_url -Credential $script:ServiceNowCreds -Body $uploadParam -Method Post -Headers $headers
$UploadResult
}
When I execute the above script I am getting the below error:
Invoke-RestMethod : The remote server returned an error: (415) Unsupported
Media Type.
At C:\Users\suganthanraj.p\Desktop\SNOW-UploadAttachment.ps1:39 char:21
+ ... oadResult = Invoke-RestMethod -Uri $Upload_snow_url -Credential $scr ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Try changing you content type to "multipart/form-data"
$headers.Add('Content-Type','multipart/form-data')
$UploadBody = #{
'table_name'='incident';
'record_sys_id'=$sys_id;
'uploadFile' = 'C:\Users\suganthanraj.p\Documents\Servers.csv'
}
The error says "The remote server returned an error: (415) Unsupported
Media Type."
Doco on the api can be found here:
https://docs.servicenow.com/bundle/geneva-servicenow-platform/page/integrate/inbound_rest/reference/r_AttachmentAPI-POSTmultipart.html
Your best option would be leverage the OOB Attachment API in ServiceNow. You will need to make a post call from powershell. Powershell has two options for this Invoke-RestMethod and Invoke-WebRequest. I have had better luck with the latter when trying to POST. You might also first build your rest call in Postman make sure you can get the attachment into ServiceNow, then worry about writing your PS.
$Body = #{
User = 'jdoe'
password = 'P#S$w0rd!'
}
$LoginResponse = Invoke-WebRequest 'http://www.contoso.com/login/' - SessionVariable 'Session' -Body $Body -Method 'POST'
$Session
$ProfileResponse = Invoke-WebRequest 'http://www.contoso.com/profile/' -`WebSession $Session $ProfileResponse`
Finally i found answer from the below link
https://community.servicenow.com/community?id=community_question&sys_id=d3707023dbaceb8023f4a345ca961949 and below is the code:
# Eg. User name="admin", Password="admin" for this code sample.
$user = "admin"
$pass = "XXX"
# Build auth header
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user, $pass)))
# Set proper headers
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add('Authorization',('Basic {0}' -f $base64AuthInfo))
$headers.Add('Accept','application/json')
$headers.Add('Content-Type','application/json')
# Specify endpoint uri
$uri = "https://dev652XX.service-now.com/api/now/attachment/file?table_name=incident&table_sys_id=850XXXXX2200e0ef563dbb9a71c1&file_name=TreeSizeReport.csv"
# Specifiy file to attach
$fileToAttach = "C:\Users\suganthanraj.p\Desktop\TreeSizeReport.csv"
# Specify HTTP method (POST, PATCH, PUT)
$method = "POST"
# Send HTTP request
$response = Invoke-WebRequest -Headers $headers -Method $method -Uri $uri -InFile $fileToAttach
# Print response
$response.RawContent

Error 400 bad request when creating a group calendar event in powershell with Microsoft Graph 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

'CompactToken parsing failed with error code: -2147184105' when trying to access Users with Office 365 Unified API using PowerShell

I am trying to list users using Office 365 Unified API with the following code:
$TenantID = "xxx"
$F_ClientID = "yyy"
$F_ClientSecret = "zzz"
Add-Type #'
using System;
public class OAuthContext{
public string AccessToken{get;set;}
public string TokenType{get;set;}
public string ExpiresIn{get;set;}
public string RefreshToken{get;set;}
}
'#
$Uri = "https://login.microsoftonline.com/$($TenantID)/oauth2/token"
$ContentType = 'application/x-www-form-urlencoded'
$Headers = #{}
$Body = [System.Text.Encoding]::UTF8.GetBytes('grant_type=client_credentials&client_id='+$F_ClientID+'&client_secret='+$F_Clie ntSecret+'&resource"=https://graph.microsoft.com')
$Response = Invoke-RestMethod -Method POST -Uri $Uri -Headers $Headers -ContentType $ContentType -Body $Body
$Response
$Context = New-Object OAuthContext
$Context.AccessToken = $Response.access_token
$Context.ExpiresIn = $Response.expires_in
$Context.RefreshToken = $Response.refresh_token
$Context.TokenType = $Response.token_type
$Context
$Headers = #{}
$Headers.Add('Authorization',$Context.TokenType + ' ' + $Context.AccessToken)
$Headers
$Uri = "https://graph.microsoft.com/v1.0/users"
Invoke-RestMethod -Method GET -Uri $Uri -Headers $Headers
As seen from the result, the access token seems to be successfully generated.
But when trying to list the users, I get the following error:
Invoke-RestMethod : {
"error": {
"code": "InvalidAuthenticationToken",
"message": "CompactToken parsing failed with error code: -2147184105",
"innerError": {
"request-id": "067c7044-0c59-4a39-86ac-b89e6b13229c",
"date": "2016-02-12T17:09:56"
}
}
}
At line:41 char:1
+ Invoke-RestMethod -Method GET -Uri $Uri -Headers $Headers
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I don't really know what I am doing wrong here!
Thanks for your help!
The response actually indicates that the access token was not successfully generated or passed to the graph endpoint. Microsoft Graph couldn't parse it as a JWT token and thus attempted to process it as a Microsoft Account/Live Id compact token, which also failed. Please check the response that you got from the call to login.microsoftonline.com and that the token passed to graph.microsoft.com is a valid JWT token.
Can you check through this page if the client secret that you are sending matches the result of the page when coding it?
The recipient when viewing 'application / x-www-form-urlencoded' will decode the url, and if your client secret is not encode well, someone characters will disappear. (This was my problem)
I used this code and it worked
What i recommend is to test your query you are sending to the graph api by using the graph explorer tool first. and then mimic the same request in your PS script.
https://graphexplorer2.azurewebsites.net

Use Powershell to upload to Bitbucket Downloads section

So we switched to Bitbucket recently - Love the different pricing model / the branch and repo permissions. But, I REALLY miss the Releases feature in GitHub.
BB does however have a "Downloads" section that we can upload recent binaries to. But... It isnt exposed via their API.
I found a nifty script that uses cURL, but I wanted to do this in PowerShell so I dont need any special programs (we use AppVeyor as our CI Server, no cURL).
I have this mostly working - The process is:
Load Signin page to get CSRF token - working
Sign in, redirecting to downloads page - working
Upload file - failing
My code is here
I have isolated the problem to the form data. Here is what it looks like in fiddler when I just do the upload myself:
But when I use Powershell I cannot get it to populate the "WebForms" tab of the request. I've tried using the -InFile and specifying the file to upload, but Bitbucket requires the other shown parameters as well.
How do I specify a series of "Form Fields" to include in the request with Powershell?
EDIT
Adding code here, even though it makes this messy.
$baseUri = "https://bitbucket.org"
$teamName = "xxxxxxxxx"
$projectName = "xxxxxxxxxxxxxxx"
$page = "/$teamName/$projectName/downloads"
$uri = "https://bitbucket.org/account/signin/"
$username = "xxxxxxxxxxxxxxxx"
$password = "xxxxxxxxxxxxxxxx"
$headers = #{
"referer" = "$uri"
}
$json = #"
{
"username":"$username",
"password":"$password",
"submit":"",
"next":"$page",
"csrfmiddlewaretoken":""
}
"#
$formData = #"
{
"token":"",
"csrfmiddlewaretoken":""
}
"#
$body = $json | ConvertFrom-Json
$formData2 = $formData | ConvertFrom-Json
#Load the page once to get the csrf token
Invoke-RestMethod -Uri $uri -SessionVariable mySession -Method Get -OutFile test2.html
#Parse the token
$body.csrfmiddlewaretoken = $mySession.Cookies.GetCookies("https://bitbucket.org")[0].Value
$formData2.csrfmiddlewaretoken = $mySession.Cookies.GetCookies("https://bitbucket.org")[0].Value
#Load the token into the object
$json = $body | ConvertTo-Json
$formData = $formData2 | ConvertTo-Json
#build the uri data needed by bb
$uriData = "username=" + $body.username + "&password=" + $body.password + "&submit=&next=" + $body.next + "&csrfmiddlewaretoken=" + $body.csrfmiddlewaretoken
#Sign into BB now
Invoke-RestMethod -Uri "https://bitbucket.org/account/signin/" -WebSession $mySession -Body $uriData -Method Post -OutFile test.html -Headers $headers
#Update referer to the downloads page
$headers.referer = $baseuri + $page
$fulluri = $baseuri + $page
#Upload the file
Invoke-RestMethod -Uri "$fulluri" -Method Post -OutFile test3.html -WebSession $mySession -Headers $headers -Body $formData -ContentType "multipart/form-data"