File upload via Pipedrive API - powershell

I need to include the lead_id in the body with the file content. The file uploads well when I use
$data = Invoke-RestMethod -Uri $URL -Method 'Post' -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $BodyLines.
Naturally the file is not attached to the lead. When I use
$data = Invoke-RestMethod -Uri $URL -Method 'Post' -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $Body
I always get error 400. Specification of $Body is wrong, but how?
#URL for Deal listing with your $company_domain and $api_token variables
$URL = 'https://' + $company_domain + '.pipedrive.com/api/v1/files?api_token=' + $api_token
$URL
#
$FilePath = $LOCALpath + "\webtilaus\Tarjouspyynto_2023-02-03_09-50-44.txt"
$data =#()
$fileBytes = [System.IO.File]::ReadAllBytes($FilePath);
$fileEnc = [System.Text.Encoding]::GetEncoding('UTF-8').GetString($fileBytes);
$boundary = [System.Guid]::NewGuid().ToString();
$LF = "`r`n";
""
$BodyLines = (
"--$boundary",
"Content-Disposition: form-data; name=`"file`"; filename=`"temp.txt`"",
"Content-Type: application/octet-stream$LF",
$fileEnc,
"--$boundary--"+ $LF
) -join $LF
$Body = #{
"deal_id" = "25"
"file" = $bodyLines
}
$data = Invoke-RestMethod -Uri $URL -Method 'Post' -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $BodyLines # This uploads
$data = Invoke-RestMethod -Uri $URL -Method 'Post' -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $Body # This gives error 400`

Related

InvalidOperation in PowerShell RestMethod API Call using Bearer sending Body as HASHTABLE

In PowerShell using Invoke-RestMetjhod to call different API´s I am stuck getting an InvalidOperation error when trying to pass both header and body information to the POST call.
My script is:
Set-StrictMode -Version Latest
$ApiToken = Get-Content ‘C:\APIEnergiNet\api_token.txt’
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer $ApiToken")
$response = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/token' -Method 'GET' -Headers $headers
$GetMetringPointID = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/meteringpoints/meteringpoints?includeAll=true' -Headers #{ Authorization = "Bearer " + $response.result }
foreach($result in $GetMetringPointID){
$CurrentMeteringID = $GetMetringPointID.result.meteringPointId
foreach($Currentresult in $CurrentMeteringID){
$MeterID = $Currentresult
$GetCharges = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/MeteringPoints/MeteringPoint/GetCharges' -Method 'POST' -Headers #{ Authorization = "Bearer " + $response.result } -Body #{ meteringPoints = #( #{meteringPoint = "$Currentresult" } ) }
$GetCharges
}
}
The API needs the following sent in the body :
{
"meteringPoints": {
"meteringPoint": [
"string"
]
}
}
if I create variable $postParams containing the data like this:
$postParams = #{
meteringPoints = #(
#{meteringPoint = "$MeterID" }
)
}
$postParams
it returns:
meteringPoints {System.Collections.Hashtable}
The API has a swagger here https://api.eloverblik.dk/customerapi/index.html
Can anyone help me why I get this error and how to fix it?
Best Regards
Stig :-)
UPDATE WITH LATEST CODE BELOW:
Set-StrictMode -Version Latest
$ApiToken = Get-Content ‘C:\APIEnergiNet\api_token.txt’
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer $ApiToken")
$response = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/token' -Method 'GET' -Headers $headers
$GetMetringPointID = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/meteringpoints/meteringpoints?includeAll=true' -Headers #{ Authorization = "Bearer " + $response.result }
foreach ($result in $GetMetringPointID)
{
$CurrentMeteringID = $GetMetringPointID.result.meteringPointId
foreach ($Currentresult in $CurrentMeteringID)
{
$MeterID = $Currentresult
$postParams = #{
meteringPoints = #(
#{ meteringPoint = "$MeterID" }
)
} | ConvertTo-Json
$resultlist = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/MeteringPoints/MeteringPoint/GetCharges' -Method 'POST' -ContentType 'application/json' -Headers #{ Authorization = "Bearer " + $response.result } -Body #{ $postParams }
$resultlist
}
}
ERROR I NOW GET:
ParserError: C:\APIEnergiNet\api.ps1:31:245
Line |
31 | … Authorization = "Bearer " + $response.result } -Body #{ $postParams }
| ~
| Missing '=' operator after key in hash literal.
I've made this little PS for you based on yours
$Path = "C:\EnergiNet\"
$TokenFile = $Path + "token.txt"
$JSON_ResponseFile = $Path + "Response.json"
$XML_ResponseFile = $Path + "Response.xml"
$ApiToken = Get-Content $TokenFile
# Get Auth token #
$response = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/token' -Method 'GET' -Headers #{ Authorization = "Bearer " + $ApiToken }
$Auth_Token = $response.result
$body = '{ "meteringPoints": {"meteringPoint": ["571313174xxxxxxxxxxx","571313174xxxxxxxxxxx","571313174xxxxxxxxxxx"] }}'
$headers = #{
'Authorization' = "Bearer " + $response.result
'Accept' = 'application/json'
}
Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/meterdata/gettimeseries/2023-01-01/2023-02-01/Quarter' -Method 'POST' -ContentType 'application/json' -Headers $headers -Body $body | ConvertTo-Json -Depth 100 | out-file $JSON_ResponseFile
$headers = #{
'Authorization' = "Bearer " + $response.result
'Accept' = 'application/xml'
}
(Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/meterdata/gettimeseries/2023-01-01/2023-02-01/Quarter' -Method 'POST' -ContentType 'application/json' -Headers $headers -Body $body).outerXml | out-file $XML_ResponseFile

How to POST Json file in the request body of Powershell Invoke-Webrequest

Can you please help me, How can I upload a Json file in the body of PUT request, is the following approach correct?
'''
$filename = "C:/Users/timtim/Downloads/default.json"
[hashtable]$headers=#{
'Authorization' = "Bearer $token"
}
$url= "url.com"
$statusCode = Invoke-WebRequest -Uri $url -Method PUT -InFile $filename -Headers $headers -ContentType "application/json"
Write-Host "$statusCode"
'''
Try this:
$filename = "C:/Users/timtim/Downloads/default.json"
$content = gc $filename
[hashtable]$headers=#{}
$headers.Add("Authorization", "Bearer $token")
$headers.Add('Content-Type', 'application/json')
$statusCode = Invoke-WebRequest -Uri $url -Method PUT -Body $content -Headers $headers
Write-Host $statusCode
Your syntax in the $headers was off. I replaced that part by initializing the hashtable, then we add our pieces to that one at a time. I was not sure why URL was in there so I removed it. You can add that back if needed. Send your JSON in a -body param. There is also $content = gc $filename where gc is an alias for "get-content". It's getting the content of the JSON from the file with that.

Powershell upload a pdf file using boundary MIME to RightFax Web Service

I am trying to upload a pdf file into Right fax via the RightFax Web Api. I can do this via PostMan and I am able to send the attachment afterwards. When I try do upload via PowerShell an I send my attachment I only get the Object Name in the actual fax ex. System.Net.Http.StreamContent. Here is my borrowed powershell code:
Add-Type -AssemblyName System.Net.Http
$AuthURL = "http://" + $RESTAPIServer + "/RightFax/API"
$BaseURL = "http://" + $RESTAPIServer + "/RightFax/API/SendJobs"
$AttachURL = "http://" + $RESTAPIServer + "/RightFax/API/Attachments"
$Base = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($RESTAPIUser+":"+$RESTAPIPassword))
$vCenterSessionURL = $BaseAuthURL
$Header = #{"Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($RESTAPIUser+":"+$RESTAPIPassword))}
$TARGET_FOLDER_PATH = "\\SomeFolderPath\"
$TokenUri = "http://" + $RESTAPIServer + "/RightFax/API/Login?rememberMe={rememberMe}"
$Token = Invoke-RestMethod -Method GET -Headers $Header -Uri $TokenUri
Get-ChildItem $TARGET_FOLDER_PATH -Filter *.pdf |
Foreach-Object {
$TARGET_FILE_NAME = $_.Name
$LDA_TARGET_FILE_NAME = $TARGET_FOLDER_PATH + $TARGET_FILE_NAME
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Basic $Base")
$fileName = $TARGET_FILE_NAME
$uri = $AttachURL
$filePath = $LDA_TARGET_FILE_NAME
$FileStream = [System.IO.FileStream]::new($filePath, [System.IO.FileMode]::Open)
$fileContent = [System.Net.Http.StreamContent]::new($FileStream)
$boundary = [System.Guid]::NewGuid().ToString()
$LF = "`r`n"
$bodyLines = (
"--$boundary",
"Content-Disposition: attachment; name=`"$fileName`"; filename=`"$filePath`"",
"Content-Type: application/octet-stream",
"Content-Transfer-Encoding: base64$LF",
$fileContent,
"--$boundary--$LF"
) -join $LF
$Attach = Invoke-RestMethod -Uri $uri -Headers $headers -Method Post -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $bodyLines #-InFile $filePath
write-host $Attach
$FileStream.Dispose()
$fileContent.Dispose()
}
I figured it out. I needed to encode the file. For those of you who are here to actually get help and not here to play police for other users posts but neglect to add any actual positive helpful comments.... Here is the code for RightFax add attachments to a fax.
$AttachURL = "http://" + $RESTAPIServer + "/RightFax/API/Attachments"
$Base = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($RESTAPIUser+":"+$RESTAPIPassword))
$vCenterSessionURL = $BaseAuthURL
$Header = #{"Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($RESTAPIUser+":"+$RESTAPIPassword))}
$TARGET_FOLDER_PATH = "\\SomeFolderPath\"
$TokenUri = "http://" + $RESTAPIServer + "/RightFax/API/Login?rememberMe={rememberMe}"
$Token = Invoke-RestMethod -Method GET -Headers $Header -Uri $TokenUri
Get-ChildItem $TARGET_FOLDER_PATH -Filter *.pdf |
Foreach-Object {
$TARGET_FILE_NAME = $_.Name
$LDA_TARGET_FILE_NAME = $TARGET_FOLDER_PATH + $TARGET_FILE_NAME
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Basic $Base")
$fileName = $TARGET_FILE_NAME
$uri = $AttachURL
$filePath = $LDA_TARGET_FILE_NAME
$fileRead = [IO.File]::ReadAllBytes($filePath)
$enc = [System.Text.Encoding]::GetEncoding("iso-8859-1")
$fileEnc = $enc.GetString($fileRead)
$boundary = [System.Guid]::NewGuid().ToString()
$LF = "`r`n"
$bodyLines = (
"--$boundary",
"Content-Disposition: form-data; name=`"$fileName`"; filename=`"$ResultFilePath`"", # filename= is optional
"Content-Type: application/pdf$LF",
$fileEnc,
"--$boundary--$LF"
) -join $
$Attach = Invoke-RestMethod -Uri $uri -Headers $headers -Method Post -ContentType "multipart/form-data; boundary=`"$boundary`"" -TimeoutSec 20 -Body $bodyLines
Write-host $Attach
}
I'm setting up a different fax service (SRFax) that needs the attachments in base64.
$file = [IO.File]::ReadAllBytes("C:\Users\Path\To\File.pdf")
$filebase64 = [System.Convert]::ToBase64String($file)

Azure DevOps how to edit Wiki page via REST API

I want to edit a Azure DevOps wiki page over the REST API (Azure DevOps Server 2019.0.1).
When I run this PowerShell script:
#VARIABLES
$api = "api-version=5.0"
$root = "http://136.202.18.216:8070/Samples"
$personalToken = "uwawlzqp6j7i1nd5dasspwkwp63tr2w2sxb5563zrla2bivynbza"
#AUTHORIZATION
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))
$headers = #{
"Authorization" = ('Basic {0}' -f $token)
"If-Match" = '*'
}
#PROJECT VARIABLES
$project = "Framework%20A"
$pageToUpdate = "/Seite2"
#BODY
$body = #"
{
"content": "Hello"
}
"#
#GET
$url = "$root/$project/_apis/wiki/wikis/2e887fde-ce76-4180-aa8d-f26ed4799eb3/pages?version=wikiMaster&path=$pageToUpdate&includeContent=True&$api"
$content = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $headers
Write-Host "$($content.path) = $($content.content)" -ForegroundColor Yellow
#PUT
$url = "$root/$project/_apis/wiki/wikis/2e887fde-ce76-4180-aa8d-f26ed4799eb3/pages?version=wikiMaster&path=$pageToUpdate&$api"
$update = Invoke-RestMethod -Uri $url -Method Put -ContentType "application/json" -Headers $header -Body $body -Verbose
Write-Host $update.content -ForegroundColor Yellow
exit(0)
The consolen output is:
/Seite2 = Seite 2 Content
AUSFÜHRLICH: PUT http://136.202.18.216:8070/Samples/Framework A/_apis/wiki/wikis/2e887fde-ce76-4180-aa8d-f26ed4799eb3/pages?version=wikiMaster&path=/Seite2&api-version=5.0 with -1-byte payload
Invoke-RestMethod: {"$ id": "1", "innerException": null, "message": "The required \" IfMatch \ "header specified in the request is an invalid page version Version of the
Wiki page as \ "IfMatch \" header for the request. \ R \ nParameterName: IfMatch "," typeName ":" Microsoft.TeamFoundation.SourceControl.WebServer.InvalidArgumentValueException,
Microsoft.TeamFoundation.SourceControl.WebServer "," TypeKey ":" InvalidArgumentValueException "," error code ": 0," eventId ": 0}
In C:\Users\mkober\Desktop\Azure DevOps Skripte (Bearbeitung)\WikiAPI.ps1:34 Zeichen:11
+ $update = Invoke-RestMethod -Uri $url -Method Put -ContentType "appli ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
The first line /Seite2 = Seite 2 Content is the result of a successful get request from the page I want to edit. The put request occures the error. What am I doing wrong here?
UPDATE: (Working Example)
#VARIABLES
$api = "api-version=5.0"
$root = "http://136.202.18.216:8070/Samples"
$personalToken = "uwawlzqp6j7i1nd5dasspwkwp63tr2w2sxb5563zrla2bivynbza"
#AUTHORIZATION
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))
$headers = #{
"Authorization" = ('Basic {0}' -f $token)
"If-Match" = '{0}'
}
#PROJECT VARIABLES
$project = "Framework%20A"
$pageToUpdate = "/Seite2"
#BODY
$body = #"
{
"content": "Hello"
}
"#
#---------------------------------------------------------------------------------------------------------------------------
#GET
$url = "$root/$project/_apis/wiki/wikis/2e887fde-ce76-4180-aa8d-f26ed4799eb3/pages?version=wikiMaster&path=$pageToUpdate&includeContent=True&$api"
$content = Invoke-WebRequest -Uri $url -Method Get -ContentType "application/json" -Headers $headers
$etag = $content.Headers.ETag
$headers.'If-Match' = $headers.'If-Match' -f $etag
Write-Host "$($content.path) = $($content.content)" -ForegroundColor Yellow
#PUT
$url = "$root/$project/_apis/wiki/wikis/2e887fde-ce76-4180-aa8d-f26ed4799eb3/pages?version=wikiMaster&path=$pageToUpdate&$api"
$update = Invoke-RestMethod -Uri $url -Method Put -ContentType "application/json" -Headers $headers -Body $body -Verbose
Write-Host $update.content -ForegroundColor Yellow
exit(0)
#---------------------------------------------------------------------------------------------------------------------------
In the If-Match header you can't just put '*', you need to put there the ETag of the page.
How do you get it? in your first GET call use Invoke-WebRequest (instaed of Invoke-RestMethod), now in the response you will get also headers response and there the ETag exist:
$page = Invoke-WebRequest -Uri $url ...........
$etag = $page.Headers.ETag
$headers = #{
"Authorizaion = ....."
"If-Match" = $etag
}
Now the second Invoke-RestMethod will work to update the page.

Getting Unauthorised error while triggering TFS build from release definition

I need to trigger a build after successful deployment of a release. I have tried using below code in Powershell in the release definition.
After executing, I get this error - Access is denied due to invalid credentials
$url = "http://abc:8080/tfs/GlobalCollection/Project/_apis/build/builds?
api-version=2.0"
$body = "{ 'definition' : { 'id' : 1} }"
$type = "application/json"
$headers = #{
Authorization = "Basic d3JlblxzcsampleTIzNA=="
}
Write-Host "URL: $url"
$definition = Invoke-RestMethod -Uri $url -Body $body -ContentType $type -
Method Post -Headers $headers
Write-Host "Definition = $($definition | ConvertTo-Json -Depth 1000)"`
Based on my test, you can use -UseDefaultCredentials :
$type = "application/json"
$url = "http://abc:8080/tfs/GlobalCollection/Project/_apis/build/builds?api-version=2.0"
$body = "{ 'definition' : { 'id' : 56} }"
Write-Host "URL: $url"
$definition = Invoke-RestMethod -Uri $url -Body $body -ContentType $type -Method Post -UseDefaultCredentials
Write-Host "Definition = $($definition | ConvertTo-Json -Depth 1000)"
Alternatively provide the specific Credential:
$user = "username"
$password = "password"
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$password)))
$headers = #{Authorization=("Basic {0}" -f $base64AuthInfo)}
$type = "application/json"
$url = "http://abc:8080/tfs/GlobalCollection/Project/_apis/build/builds?api-version=2.0"
$body = "{ 'definition' : { 'id' : 56} }"
Write-Host "URL: $url"
$definition = Invoke-RestMethod -Uri $url -Body $body -ContentType $type -Method Post -Headers $headers
Write-Host "Definition = $($definition | ConvertTo-Json -Depth 1000)"