Upload multiple files from Powershell script

后端 未结 4 1363
悲哀的现实
悲哀的现实 2020-12-01 11:17

I have a webapplication that can process POSTing of a html form like this:

4条回答
  •  北荒
    北荒 (楼主)
    2020-12-01 11:55

    I've been crafting multipart HTTP POST with PowerShell today. I hope the code below is helpful to you.

    • PowerShell itself cannot do multipart form uploads.
    • There are not many sample about it either. I built the code based on this and this.
    • Sure, Invoke-RestMethod requires PowerShell 3.0 but the code in the latter of the above links shows how to do HTTP POST with .NET directly, allowing you to have this running in Windows XP as well.

    Good luck! Please tell if you got it to work.

    function Send-Results {
        param (
            [parameter(Mandatory=$True,Position=1)] [ValidateScript({ Test-Path -PathType Leaf $_ })] [String] $ResultFilePath,
            [parameter(Mandatory=$True,Position=2)] [System.URI] $ResultURL
        )
        $fileBin = [IO.File]::ReadAllBytes($ResultFilePath)
        $computer= $env:COMPUTERNAME
    
        # Convert byte-array to string (without changing anything)
        #
        $enc = [System.Text.Encoding]::GetEncoding("iso-8859-1")
        $fileEnc = $enc.GetString($fileBin)
    
        <#
        # PowerShell does not (yet) have built-in support for making 'multipart' (i.e. binary file upload compatible)
        # form uploads. So we have to craft one...
        #
        # This is doing similar to: 
        # $ curl -i -F "file=@file.any" -F "computer=MYPC" http://url
        #
        # Boundary is anything that is guaranteed not to exist in the sent data (i.e. string long enough)
        #    
        # Note: The protocol is very precise about getting the number of line feeds correct (both CRLF or LF work).
        #>
        $boundary = [System.Guid]::NewGuid().ToString()    # 
    
        $LF = "`n"
        $bodyLines = (
            "--$boundary",
            "Content-Disposition: form-data; name=`"file`"$LF",   # filename= is optional
            $fileEnc,
            "--$boundary",
            "Content-Disposition: form-data; name=`"computer`"$LF",
            $computer,
            "--$boundary--$LF"
            ) -join $LF
    
        try {
            # Returns the response gotten from the server (we pass it on).
            #
            Invoke-RestMethod -Uri $URL -Method Post -ContentType "multipart/form-data; boundary=`"$boundary`"" -TimeoutSec 20 -Body $bodyLines
        }
        catch [System.Net.WebException] {
            Write-Error( "FAILED to reach '$URL': $_" )
            throw $_
        }
    }
    

提交回复
热议问题