-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathConvertTo-MultipartFormData.ps1
84 lines (74 loc) · 2.44 KB
/
ConvertTo-MultipartFormData.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<#
.SYNOPSIS
Creates multipart/form-data to send as a request body.
.INPUTS
Any System.Collections.IDictionary type of key-value pairs to encode.
.OUTPUTS
System.Byte[] of encoded key-value data.
.FUNCTIONALITY
HTTP
.LINK
https://docs.microsoft.com/dotnet/api/system.net.http.multipartformdatacontent
.LINK
Invoke-WebRequest
.LINK
Invoke-RestMethod
.LINK
New-Guid
.EXAMPLE
@{ title = 'Name'; file = Get-Item avatar.png } |ConvertTo-MultipartFormData.ps1 |Invoke-WebRequest $url -Method POST
Sends two fields, one of which is a file upload.
#>
#Requires -Version 3
[CmdletBinding()][OutputType([byte[]])] Param(
<#
The fields to pass, as a Hashtable or other dictionary.
Values of the System.IO.FileInfo type will be read, as for a file upload.
#>
[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)][Collections.IDictionary] $Fields
)
DynamicParam
{
$boundary = "$(New-Guid)"
$PSDefaultParameterValues['Invoke-WebRequest:ContentType'] = "multipart/form-data; boundary=$boundary"
$PSDefaultParameterValues['Invoke-RestMethod:ContentType'] = "multipart/form-data; boundary=$boundary"
}
Begin
{
$cmdletname = $MyInvocation.MyCommand.Name
if((Get-Module Microsoft.PowerShell.Utility).Version -ge [version]6.1)
{
Write-Warning "Invoke-WebRequest and Invoke-RestMethod appear to natively support multipart/form-data."
}
try{[void][Net.Http.StringContent]}catch{Add-Type -AN System.Net.Http |Out-Null}
}
Process
{
$content = New-Object Net.Http.MultipartFormDataContent $boundary
foreach($field in $Fields.GetEnumerator())
{
if($field.Value -isnot [IO.FileInfo])
{
$content.Add([Net.Http.StringContent]$field.Value,$field.Key)
Write-Verbose "$cmdletname : $($field.Key)=$($field.Value)"
}
else
{
Write-Verbose "$cmdletname : Adding file $($field.Value.FullName)"
$content.Add((New-Object Net.Http.StreamContent ($field.Value.OpenRead())),$field.Key,$field.Value.Name)
}
}
$content.Headers.GetEnumerator() |
ForEach-Object {Write-Verbose "$cmdletname header : $($_.Key)=$($_.Value -join "`n`t")"}
[Threading.Tasks.Task[byte[]]]$getbody = $content.ReadAsByteArrayAsync()
$getbody.Wait()
[byte[]]$body = $getbody.Result
$content.Dispose()
Write-Verbose "$cmdletname : Body is $($body.Length) bytes"
return,$body
}
End
{
$PSDefaultParameterValues.Remove('Invoke-WebRequest:ContentType')
$PSDefaultParameterValues.Remove('Invoke-RestMethod:ContentType')
}