Created
January 5, 2017 09:42
-
-
Save jeroenheijmans/91825c214073e804a1d0378b784e8aa5 to your computer and use it in GitHub Desktop.
Powershell Module with cmdlet to upload files in a multipart-form POST
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
# It can be called like this: | |
$url ="http://localhost:12345/home/upload" | |
$form = @{ description = "Test 123." } | |
$pwd = ConvertTo-SecureString "s3cr3t" -AsPlainText -Force | |
$creds = New-Object System.Management.Automation.PSCredential ("john", $pwd) | |
Get-ChildItem *.txt | Send-MultiPartFormToApi $url $form $creds -Verbose -WhatIf | |
#> | |
function Send-MultiPartFormToApi { | |
# Attribution: [@akauppi's post](http://stackoverflow.com/a/25083745/419956) | |
# Remixed in: [@jeroen's post](http://stackoverflow.com/a/41343705/419956) | |
[CmdletBinding(SupportsShouldProcess = $true)] | |
param ( | |
[Parameter(Position = 0)] | |
[string] | |
$Uri, | |
[Parameter(Position = 1)] | |
[HashTable] | |
$FormEntries, | |
[Parameter(Position = 2, Mandatory = $false)] | |
[System.Management.Automation.Credential()] | |
[System.Management.Automation.PSCredential] | |
$Credential, | |
[Parameter( | |
ParameterSetName = "FilePath", | |
Mandatory = $true, | |
ValueFromPipeline = $true, | |
ValueFromPipelineByPropertyName = $true | |
)] | |
[Alias("Path")] | |
[string[]] | |
$FilePath, | |
[Parameter()] | |
[string] | |
$FilesKey = "files" | |
); | |
begin { | |
$LF = "`n" | |
$boundary = [System.Guid]::NewGuid().ToString() | |
Write-Verbose "Setting up body with boundary $boundary" | |
$bodyArray = @() | |
foreach ($key in $FormEntries.Keys) { | |
$bodyArray += "--$boundary" | |
$bodyArray += "Content-Disposition: form-data; name=`"$key`"" | |
$bodyArray += "" | |
$bodyArray += $FormEntries.Item($key) | |
} | |
Write-Verbose "------ Composed multipart form (excl files) -----" | |
Write-Verbose "" | |
foreach($x in $bodyArray) { Write-Verbose "> $x"; } | |
Write-Verbose "" | |
Write-Verbose "------ ------------------------------------ -----" | |
$i = 0 | |
} | |
process { | |
$fileName = (Split-Path -Path $FilePath -Leaf) | |
Write-Verbose "Processing $fileName" | |
$fileBytes = [IO.File]::ReadAllBytes($FilePath) | |
$fileDataAsString = ([System.Text.Encoding]::GetEncoding("iso-8859-1")).GetString($fileBytes) | |
$bodyArray += "--$boundary" | |
$bodyArray += "Content-Disposition: form-data; name=`"$FilesKey[$i]`"; filename=`"$fileName`"" | |
$bodyArray += "Content-Type: application/x-msdownload" | |
$bodyArray += "" | |
$bodyArray += $fileDataAsString | |
$i += 1 | |
} | |
end { | |
Write-Verbose "Finalizing and invoking rest method after adding $i file(s)." | |
if ($i -eq 0) { throw "No files were provided from pipeline." } | |
$bodyArray += "--$boundary--" | |
$bodyLines = $bodyArray -join $LF | |
# $bodyLines | Out-File data.txt # Uncomment for extra debugging... | |
try { | |
if (!$WhatIfPreference) { | |
Invoke-RestMethod ` | |
-Uri $Uri ` | |
-Method Post ` | |
-ContentType "multipart/form-data; boundary=`"$boundary`"" ` | |
-Credential $Credential ` | |
-Body $bodyLines | |
} else { | |
Write-Host "WHAT IF: Would've posted to $Uri body of length " + $bodyLines.Length | |
} | |
} catch [Exception] { | |
throw $_ # Terminate CmdLet on this situation. | |
} | |
Write-Verbose "Finished!" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment