Upload image via API using powershell

Hello,
I am able to upload images using postman. In that case postman uploads the image from my local PC to it’s cloud and then uploads it in Cloudflare.
I want to be able to upload image using PowerShell directly form my local PC. For that I sue this code (generated from postman)

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer MYTOKEN")
$headers.Add("Cookie", "__cflb=0H28vgHxwvgAQtjUGU4yFBDJQfw1pfzuKKNbHepFeNH; __cfruid=93e6708395db9c727114f67cc5294023e8a72bb1-1710940328")

$multipartContent = [System.Net.Http.MultipartFormDataContent]::new()

#$multipartFile = 'postman-cloud:///1eee750c-af44-44b0-968a-7303db7bb05b'
$multipartFile = "C:\Temp\images\1.png"

$FileStream = [System.IO.FileStream]::new($multipartFile, [System.IO.FileMode]::Open)
$fileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data")
$fileHeader.Name = "file"
#$fileHeader.FileName = "postman-cloud:///1eee750c-af44-44b0-968a-7303db7bb05b"
$fileHeader.FileName = "C:\Temp\images\1.png"
$fileContent = [System.Net.Http.StreamContent]::new($FileStream)
$fileContent.Headers.ContentDisposition = $fileHeader
$multipartContent.Add($fileContent)

$body = $multipartContent

$response = Invoke-RestMethod 'https://api.cloudflare.com/client/v4/accounts/c242f2eff3d18cdb3a510619d3f6e62c/images/v1' -Method 'POST' -Headers $headers -Body $body
$response | ConvertTo-Json

But it is not working. Is there any working example for PowerShell?

Thanks in advance

here is a function to do that

function UploadImage {
    param (
        [string]$SignedUrl,
        [string]$FilePath,
        [string]$Filename,
        [string]$ContentType
    )

    try {

        $fileBytes = [System.IO.File]::ReadAllBytes($FilePath);
        $FileContent = [System.Text.Encoding]::GetEncoding('iso-8859-1').GetString($fileBytes)
        $boundary = [System.Guid]::NewGuid().ToString(); 
        $headers = @{}
        $headers.Add("Content-Type", "multipart/form-data; boundary=`"$boundary`"")
        $headers.Add("Authorization", "Bearer undefined")
    
        $LF = "`r`n";
        
        $bodyLines = ( 
            "--$boundary",
            "Content-Disposition: form-data; name=`"file`"; filename=`"$Filename`"",
            "Content-Type: $ContentType$LF",
            $FileContent,
            "--$boundary--$LF" 
        ) -join $LF

     
        return Invoke-RestMethod -Uri $SignedUrl -Method Post -Headers $headers -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $bodyLines

    }
    catch {
        Write-Host "Error uploading image: $_"
    }
}

Hello,
Thanks for the feedback.
I’ve tried the code using these as variables, I wonder if I use them right

$FilePath = "C:\Temp\images\"
$Filename = "1.png"
$SignedUrl = "https://api.cloudflare.com/client/v4/accounts/MYACCOUNT/images/v1"
$ContentType = "multipart/form-data"```

and get this error:

Error uploading image: Exception calling "ReadAllBytes" with "1" argument(s): "Empty path name is not legal."

Can you please advice on this?

Check your FilePath it should be the full path to the image on your disk i.e C:\Temp\images\1.png

so it should be

$Filename = "1.png"

$FilePath = "C:\Temp\images\"

$FullPath = Join-Path -Path $FilePath -ChildPath $Filename

then fileBytes should be

$fileBytes = [System.IO.File]::ReadAllBytes($FullPath);

I get the same error after change :frowning:

If you want to do a direct upload without requesting a one-time uploadUrl just do this

$ContentType = "image/jpg"
$FilePath = 'C:\Temp\images\1.jpg' #  full path to file
$AccountId = "7i3j4rij3rkpo4rkop"  #  use your api token
$ApiToken = "hsdkfjhdkfklklweC"  #  use your api token
$url = "https://api.cloudflare.com/client/v4/accounts/$AccountId/images/v1"
$filename = Split-Path -Path $FilePath -Leaf
$fileBytes = [System.IO.File]::ReadAllBytes($FilePath);
$FileContent = [System.Text.Encoding]::GetEncoding('iso-8859-1').GetString($fileBytes)
$boundary = [System.Guid]::NewGuid().ToString(); 
$headers = @{}
$headers.Add("Content-Type", "multipart/form-data; boundary=`"$boundary`"")
$headers.Add("Authorization", "Bearer $ApiToken")
    
$LF = "`r`n";
        
$bodyLines = ( 
    "--$boundary",
    "Content-Disposition: form-data; name=`"file`"; filename=`"$filename`"",
    "Content-Type: $ContentType$LF",
    $FileContent,
    "--$boundary--$LF"
) -join $LF
    
$res = Invoke-RestMethod -Uri $url -Method Post -Headers $headers -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $bodyLines 
      
Write-Host "$($res | ConvertTo-Json)"

result:

Thank you, the solution worked :slight_smile:

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.