This happens using the new -Form parameter that takes a hashtable of values and creates the multi-part form data.
Invoke-WebRequest -Uri $Uri -Method POST -Form @{
APPLICATION_NAME = "Name"
APPLICATION_VERION = "3.0"
UPLOADED_FILE = Get-Item .\foo.zip
}
Upload works as it does when using Python script to upload the file. Observe that in this Fiddler trace, that the form-data field values are quoted:

PowerShell fails and after some experimenting it is because the name values are not quoted:

With just a few extra quotes e.g.:
Invoke-WebRequest -Uri $Uri -Method POST -Form @{
'"APPLICATION_NAME"' = "Name"
'"APPLICATION_VERION"' = "3.0"
'"UPLOADED_FILE"' = Get-Item .\foo.zip
}
I can get the PowerShell request to quote all the field data values except the file's filename field. And that is enough to break the upload. Besides that, the above workaround is ugly.
As an aside, is there a way to control the filename value? If there was, I could work-around this by supplying the quotes myself. Also, I could see someone wanting to change the filename to something other than the original file's filename.
This also makes me wonder if we could use a new parameter like -RequestFilter that took a scriptblock with a signature like {param($requestText) ... } where you could get the request text just before it is sent. Then you could manipulate it however you needed to and return that text from this scriptblock. With such a feature I might be able to do this:
Invoke-WebRequest -Uri $Uri -Method POST `
-RequesetFilter {param($r) $r -replace '(?<=filename=)(\S+)','"$1"' } `
-Form @{
'"APPLICATION_NAME"' = "Name"
'"APPLICATION_VERION"' = "3.0"
'"UPLOADED_FILE"' = Get-Item .\foo.zip
}
> $PSVersionTable
Name Value
---- -----
PSVersion 6.1.0-preview.2
PSEdition Core
GitCommitId v6.1.0-preview.2
OS Microsoft Windows 10.0.16299
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
As an aside, is there a way to control the filename value? If there was, I could work-around this by supplying the quotes myself. Also, I could see someone wanting to change the filename to something other than the original file's filename.
For the -Form way, no. This was intentionally simplistic. For customization, users can create their own MultipartFormDataContent objects and pass them to -Body.
I'm not a fan of the -RequestFilter Idea, but, I would consider accepting an HttpRequestMessage. The cmdlets do not send a raw request, so there is no way to really do what you are wanting, The Cmdlets use HttpClient and creates a HttpRequestMessage so we could consider allowing the user to supply their own.
Re: the issue at hand.
I did some research and the major browsers and curl all enclose the filename value and the field names in quotes. It seems that .NET is the only thing not doing that. I'll have a PR soon to correct this.
@rkeithhill Would you be so kind as to try using one of these artifacts https://ci.appveyor.com/project/PowerShell/powershell/build/v6.1.0-preview.9234/artifacts to test against your API and let me know if it works?
It works!! Thanks Mark!
-Keith
Sent from Mailhttps://go.microsoft.com/fwlink/?LinkId=550986 for Windows 10
From: Mark Kraus notifications@github.com
Sent: Tuesday, May 1, 2018 3:25:41 AM
To: PowerShell/PowerShell
Cc: Keith Hill; Mention
Subject: Re: [PowerShell/PowerShell] Invoke-WebRequest multipart form-data fails file upload when field names not quoted (#6780)
@rkeithhillhttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Frkeithhill&data=02%7C01%7C%7C065e5978285242acc85008d5af45828d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636607635426145690&sdata=FSQLHzCJpbioidxPGpcsljPdnKoJt9EI5TMWmj9nNi0%3D&reserved=0 Would you be so kind as to try using one of these artifacts https://ci.appveyor.com/project/PowerShell/powershell/build/v6.1.0-preview.9234/artifactshttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fci.appveyor.com%2Fproject%2FPowerShell%2Fpowershell%2Fbuild%2Fv6.1.0-preview.9234%2Fartifacts&data=02%7C01%7C%7C065e5978285242acc85008d5af45828d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636607635426145690&sdata=yiTa%2BiKawirOnQdkVpuyVQwj6xh5YzkaVaftV6Omreo%3D&reserved=0 to test against your API and let me know if it works?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FPowerShell%2FPowerShell%2Fissues%2F6780%23issuecomment-385633094&data=02%7C01%7C%7C065e5978285242acc85008d5af45828d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636607635426301940&sdata=bxrEHKCbhzixBmWruAlRHHn5tVN8AGJ8erSwS7LYKy4%3D&reserved=0, or mute the threadhttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAE8AqKY4Fdb84D9ieUTS-ekcoDOcKaPNks5tuCoVgaJpZM4TtUfG&data=02%7C01%7C%7C065e5978285242acc85008d5af45828d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636607635426301940&sdata=trvx7oIkqRodmGkhIBCrgg6yWQNXtX062k%2BZ51RtSGQ%3D&reserved=0.
Most helpful comment
@rkeithhill Would you be so kind as to try using one of these artifacts https://ci.appveyor.com/project/PowerShell/powershell/build/v6.1.0-preview.9234/artifacts to test against your API and let me know if it works?