API - Upload files with powershell 7

I try to upload a file with powershell 7 but always get error

Invoke-WebRequest: {"error": "Bad request."}

Same Request in Postman works. Where should I search? here my code:

$headersGet=@{}
$headersGet.Add("accept", "application/json")
$headersGet.Add("authorization", "Bearer $seafileApiToken")

$seafileFolders = Invoke-WebRequest -Uri "https://<server>/api2/repos/$seafileRepoId/dir/?p=$seafileDestFolder&recursive=0" -Method GET -Headers $headersGet
$seafileFolders = $seafileFolders | ConvertFrom-Json
$seafileUploadLink = Invoke-WebRequest -Uri "https://<server>/api2/repos/$seafileRepoId/upload-link/?p=%2FTest%2F" -Method GET -Headers $headersGet | ConvertFrom-Json

$headersPost=@{}
$headersPost.Add("accept", "application/json")
$headersPost.Add("authorization", "Bearer $seafileApiToken")

$body = @{
           file = Get-Item "C:\Temp\demo.pdf"
           parent_dir = "/Test"
          }

$response = Invoke-WebRequest -Uri $seafileUploadLink -Method Post -Headers $headersPost -Form $body

I tested in Postman with missing “file” oder “parent_dir” and got the error that these values missing. so i don’t think my values are the problem. I can also list the files and directories with powershell.

Any ideas?

Here are suggestions by AI that can help you (I have double checked):

The user is encountering a “Bad request.” error when trying to upload a file to the Seafile API using PowerShell 7, while the same request works successfully in Postman. This suggests a discrepancy in how PowerShell constructs the HTTP request compared to Postman. Here are some key points to check to diagnose and resolve the issue:

  1. Inspect the full HTTP Request: The most crucial step is to compare the actual HTTP request generated by PowerShell 7’s Invoke-WebRequest with the one generated by Postman. Tools like Fiddler, Wireshark, or the -Debug switch with Invoke-WebRequest (though less detailed for multipart bodies) can help capture and inspect the raw request headers and body. Pay close attention to:

    • Content-Type header: Ensure it’s multipart/form-data and that the boundary string is correctly formatted and matches the body content.
    • Form field names: Confirm that "file" and "parent_dir" are being sent with the exact names and case sensitivity expected by the API.
    • File content encoding: Verify how the file content (C:\Temp\demo.pdf) is being encoded and included in the multipart body.
  2. PowerShell Invoke-WebRequest -Form Behavior: While -Form is designed to handle multipart/form-data, sometimes there can be subtle differences in its implementation across PowerShell versions or environments. Ensure that the Get-Item object for the file is correctly interpreted and included as a file part in the multipart request.

  3. API Expectations vs. PowerShell Output: The “Bad request.” error is generic. It’s possible the API has very specific requirements for the multipart request that PowerShell’s automatic -Form handling isn’t fully meeting. If inspection reveals differences, consider manually constructing the multipart/form-data body for greater control, though this is more complex.

  4. URL Encoding of parent_dir: While parent_dir = "/Test" is in the $body as a form field, ensure that if there’s any implicit URL encoding happening on the server side, it’s not causing issues. However, since the API accepts it from Postman, this is less likely to be the primary cause.

  5. Postman Collection Export (Code Snippet): If possible, export the working Postman request as a code snippet for PowerShell (if Postman offers that feature) and compare it against the current PowerShell code. This can sometimes reveal subtle header or body construction differences.

By comparing the exact HTTP requests, especially the Content-Type header and the structure of the multipart body, between the working Postman request and the failing PowerShell request, the root cause of the “Bad request.” error should become apparent.

Hello Daniel,
thanks for your response.

I have already tried many ways to solve this, including AI, but unfortunately without success.

I have now switched to TypeScript with NodeJS. That works :slightly_smiling_face: