locked
Powershell API- Upload PDF to Endpoint from Local Machine RRS feed

  • Question

  • Hello, I am running into issues getting this to work. 

     What I'm trying to do is upload a "PDF" to our system using API commands in Powershell. I've been able to upload "documents" from my disk drive, but when I try to view them they are either "Document not found" or "Cannot open this PDF" or ""The input is not a valid Base-64 string as it contains a non-base 64 character". If it is successful, the PDF is blank. I've tried different methods: encoding/decoding in a variety of ways, I've tried opening it in several different programs- doesn't seem like nothing is working and I'm losing sleep.

    Below is my code for just straight upload:

    $fileName = "C:\files\Test1.pdf"
    $data = ConvertTo-Json @{
    
    encrypted="false";
    allowSaveBinaryData="True";
    binaryData=$fileName;
    divider="Expense Report";
    isMultipageImage="true";
    extension="pdf";
    name="Test1.pdf";
    relProjectId="31";
    }
    
    $addproject="https://ENDPOINT URL.com/v4/documents/597?guid=$temp&fbsite=https://MYURL.com/"
    
    
    Invoke-RestMethod -ContentType 'application/json' -Method PUT -Body $data -Uri $addproject

    Below is my code I tried using encoding/decoding:

    $fileName = "C:\files\Test1.pdf"
    $fileContent = get-content -raw $fileName
    $fileContentBytes = [System.Text.Encoding]::Unicode.GetBytes($fileContent)
    $fileContentEncoded = [System.Convert]::ToBase64String($fileContentBytes)
    
    $data
    = ConvertTo-Json @{ encrypted="false"; allowSaveBinaryData="True"; binaryData=$fileContentEncoded; divider="Expense Report"; isMultipageImage="true"; extension="pdf"; name="Test1.pdf"; relProjectId="31"; } $addproject="https://ENDPOINT URL.com/v4/documents/597?guid=$temp&fbsite=https://MYURL.com/" Invoke-RestMethod -ContentType 'application/json' -Method PUT -Body $data -Uri $addproject


    Saturday, April 14, 2018 5:51 PM

Answers

  • WIth a PDF this should work:

    Invoke-RestMethod -ContentType 'application/pdf' -InFile$file -MethodPOST -Uri$addproject

    You will need to authenticate and use a websession to use the authentication.


    \_(ツ)_/

    • Marked as answer by Lilith Mae Saturday, April 14, 2018 11:32 PM
    Saturday, April 14, 2018 8:43 PM

All replies

  • What makes you think that the web site allows uploads?  A web site must be specially designed to allow uploads.

    If them site allows uploads then use the WebClient to do the upload.

    $wc = New-Object System.Net.WebClient
    $wc.UploadFile($url,$filename)


    \_(ツ)_/

    Saturday, April 14, 2018 7:38 PM
  • Here is an example of using the REST API to upload a file:

    https://gallery.technet.microsoft.com/office/How-to-upload-large-file-1c5c2e6c


    \_(ツ)_/

    Saturday, April 14, 2018 7:41 PM
  • Thank you jrv for the tip.

    Our cloud software allows calls to a web API. I am trying to add a PDF, but having issues completing this. I can add projects and successfully authenticate in. I can "add" documents (upload from my local drive), but they are either "not found" or "cannot open this file". In some cases, depending on how I play around with the code, it will upload just a blank PDF.

    However, from what I understand, I need to encode the pdf file to Base64. This is where I am running into issues. I either get an error, "Invoke-RestMethod : "Startxref not found" or I get "The input is not a valid Base-64 string as it contains a non-base 64 character".

    So, yes, our website allows REST API integration. The problem is, I'm having issues with this code. I can successfully communicate and authenticate in, I'm just having issues getting the PDF through without being corrupt. Above, under Encoding/Decoding, is what I am using in my attempts. Thank you :)
    Saturday, April 14, 2018 7:55 PM
  • You have to look at the look I posted.  It shows you how to create an uploadable document.  Ask the vendor of your web for sample code that they use as each web can have variations of the method.

    When uploading the document is encoded into the body of the call using a correct wrapper.


    \_(ツ)_/


    • Edited by jrv Saturday, April 14, 2018 8:04 PM
    Saturday, April 14, 2018 8:03 PM
  • Here is the simple POST method that will create the MPF wrapper for you.

    $uri = "http://blahblah.com"
    $filePath = 'c:/mydoc.pdf'
    Invoke-RestMethod -Uri $uri -Method Post -InFile $filePath -ContentType 'multipart/form-data' 


    \_(ツ)_/

    • Proposed as answer by jrv Saturday, April 14, 2018 8:19 PM
    • Unproposed as answer by Lilith Mae Saturday, April 14, 2018 9:17 PM
    Saturday, April 14, 2018 8:08 PM
  • Thank you very much for your input.

    The only example given is a cURL, but in this particular case we need to use Powershell. Here is that example:

    
    
    curl -X PUT -H "Content-Type: application/json"
    
    -d '{"allowSaveBinaryData": true,
     "binaryData": "'"$(base64 example.pdf)"'",
     "encrypted": false,
     "extension": "PDF",
     "fileId": 1234,
     "name": "example.pdf",
     "separator": "example_separator",
     "divider": "example_divider"}'
    
    'http://APIENDPOINT/v5/documents/1234?guid=xxx-xxx-xxx-xxx&fbsite=https://yoursite.com'


    Saturday, April 14, 2018 8:16 PM
  • FYI, I tried your MPF wrapper suggestion, but received error "Invoke-RestMethod : {"Message":"The request entity's media type 'mutlipart/mixed' is not supported for this resource."}"

    Thank you.
    Saturday, April 14, 2018 8:29 PM
  •  'multipart/form-data'

    \_(ツ)_/

    Saturday, April 14, 2018 8:31 PM
  • Typo, my mistake. Yes, I've tried that:

    $file="C:\files\Test1.pdf"
    
    $data = ConvertTo-Json @{
    encrypted="false";
    allowSaveBinaryData="false";
    extension="pdf";
    name="Test1.pdf";
    divider="Expense Report";
    relProjectId="31";
    fileID="597"}
    
    $addproject="https://ENDPOINT.com/v4/documents/597?guid=$temp&fbsite=https://MYURL.com/&$data"
    
    Invoke-RestMethod -ContentType 'multipart/form-data' -InFile $file -Method POST -Uri $addproject





    Invoke-RestMethod : {"Message":"The request entity's media type 'multipart/form-data' is not supported for this resource."}
    Saturday, April 14, 2018 8:39 PM
  • WIth a PDF this should work:

    Invoke-RestMethod -ContentType 'application/pdf' -InFile$file -MethodPOST -Uri$addproject

    You will need to authenticate and use a websession to use the authentication.


    \_(ツ)_/

    • Marked as answer by Lilith Mae Saturday, April 14, 2018 11:32 PM
    Saturday, April 14, 2018 8:43 PM
  • Also, here is another example that is used for this particular call:

    PUT https://ENDPOINT.com/v4/documents/50?fbsite=https://THEURL.com/
    
    {   "documentID": 0,
       "fileId": 50,   "divider": "Example",
       "status": 1,
       "extension": "pdf",
       "name": "Example.pdf",
       "dateFiled": "2015-04-17T13:46:24",
       "dateCreated": "2015-04-17T13:46:24",
       "documentDate": "1990-01-01T00:00:00",
       "batchDate": "1990-01-01T00:00:00",
       "eFormComplete": "1990-01-01T00:00:00",
       "eFormDue": "1990-01-01T00:00:00",
       "lastView": "1990-01-01T00:00:00",
       "allowSaveBinaryData": true,
       "binaryData" : "VGhlIGNvbnRlbnQgZm9yIHRoaXMgdGVzdCBwYWdl"}

    Saturday, April 14, 2018 8:43 PM
  • I've tried that, and I'm still not able to get through. The first request authenticates, the second one attempts to upload. Here is the complete request I am making:

    [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
    $obj = New-Object psobject
    $obj | Add-Member -MemberType NoteProperty -Name "username" -Value "USER"
    $obj | Add-Member -MemberType NoteProperty -Name "password" -Value "PASS"
    $body = ConvertTo-Json -InputObject $obj
    
    $login="https://ENDPOINT.com/v4/login?fbsite=https://MYURL.com/"
    
    
    Invoke-RestMethod -ContentType 'application/json' -Method Post -Body $body -Uri $login -OutVariable temp
    
    $file="C:\files\Test1.pdf"
    
    
    $addproject="https://EDNPOINT.com/v4/documents/597?guid=$temp&fbsite=https://MYURL.com/"
    
    
    Invoke-RestMethod -ContentType 'application/pdf' -InFile $file -Method PUT -Uri $addproject
    
    Invoke-RestMethod :
    {"Message":"The request entity's media type 'application/pdf' is not supported for this resource."}

    Saturday, April 14, 2018 8:57 PM
  • I  a not going to try yo keep up with your changes.   You need to use a "SessionVariable" and then use it for the "WebSession".  I recommend carefully reading the help then search for the many examples of different ways to use this to upload files.  Yo can, of course, always use curl from PowerShell.


    \_(ツ)_/

    Saturday, April 14, 2018 9:45 PM
  • Orion Samael to LilithMae. How quaint. Is that your real pic? LOL.

    La vida loca

    Saturday, April 14, 2018 10:33 PM
  • Actually, JRV, with your assistance, my persistence, and a little bit of outside reference, I was able to figure this out by taking your suggestions and meshing them with mine.

    I appreciate all your help. Thank you so much.
    Saturday, April 14, 2018 11:31 PM
  • Invoke-RestMethod -Header 'application/pdf' -ContentType 'application/json' -body $data -Method PUT -Uri$addproject

    $data= defined, converted to json

    'application/pdf' was actually a seperate variable i put in $headers and placed into the request line

    Thanks again!
    Saturday, April 14, 2018 11:34 PM
  • Actually, JRV, with your assistance, my persistence, and a little bit of outside reference, I was able to figure this out by taking your suggestions and meshing them with mine.

    I appreciate all your help. Thank you so much.

    I was waiting for you to do that. In the end you have to try to understand the particular REST implementation and adapt.

    Many implementation are incomplete and just plain wrong.


    \_(ツ)_/


    • Edited by jrv Saturday, April 14, 2018 11:49 PM
    Saturday, April 14, 2018 11:47 PM