Upload multiple files from Powershell script

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

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

4条回答
  •  情话喂你
    2020-12-01 12:11

    I have found a solution to my problem after studying how multipart/form-data is built. A lot of help came in the form of http://www.paraesthesia.com/archive/2009/12/16/posting-multipartform-data-using-.net-webrequest.aspx.

    The solution then is to build the body of the request up manually according to that convention. I have left of niceties like correct Content-Lengths etc.

    Here is an excerpt of what I am using now:

        $path = "/Some/path/to/data/"
    
        $boundary_id = Get-Date -Format yyyyMMddhhmmssfffffff
        $boundary = "------------------------------" + $boundary_id
    
        $url = "http://..."
        [System.Net.HttpWebRequest] $req = [System.Net.WebRequest]::create($url)
        $req.Method = "POST"
        $req.ContentType = "multipart/form-data; boundary=$boundary"
        $ContentLength = 0
        $req.TimeOut = 50000
    
        $reqst = $req.getRequestStream()
    
        <#
        Any time you write a file to the request stream (for upload), you'll write:
            Two dashes.
            Your boundary.
            One CRLF (\r\n).
            A content-disposition header that tells the name of the form field corresponding to the file and the name of the file. That looks like:
            Content-Disposition: form-data; name="yourformfieldname"; filename="somefile.jpg" 
            One CRLF.
            A content-type header that says what the MIME type of the file is. That looks like:
            Content-Type: image/jpg
            Two CRLFs.
            The entire contents of the file, byte for byte. It's OK to include binary content here. Don't base-64 encode it or anything, just stream it on in.
            One CRLF.
        #>
    
        <# Upload #1: XFA #> 
        $xfabuffer = [System.IO.File]::ReadAllBytes("$path\P7-T.xml")
    
        <# part-header #>
        $header = "--$boundary`r`nContent-Disposition: form-data; name=`"xfa`"; filename=`"xfa`"`r`nContent-Type: text/xml`r`n`r`n"
        $buffer = [Text.Encoding]::ascii.getbytes($header)        
        $reqst.write($buffer, 0, $buffer.length)
        $ContentLength = $ContentLength + $buffer.length
    
        <# part-data #>
        $reqst.write($xfabuffer, 0, $xfabuffer.length)
        $ContentLength = $ContentLength + $xfabuffer.length
    
        <# part-separator "One CRLF" #>
        $terminal = "`r`n"
        $buffer = [Text.Encoding]::ascii.getbytes($terminal)        
        $reqst.write($buffer, 0, $buffer.length)
        $ContentLength = $ContentLength + $buffer.length
    
        <# Upload #1: PDF template #>
        $pdfbuffer = [System.IO.File]::ReadAllBytes("$path\P7-T.pdf")
    
        <# part-header #>
        $header = "--$boundary`r`nContent-Disposition: form-data; name=`"pdf`"; filename=`"pdf`"`r`nContent-Type: application/pdf`r`n`r`n"
        $buffer = [Text.Encoding]::ascii.getbytes($header)        
        $reqst.write($buffer, 0, $buffer.length)
        $ContentLength = $ContentLength + $buffer.length
    
        <# part-data #>
        $reqst.write($pdfbuffer, 0, $pdfbuffer.length)
        $ContentLength = $ContentLength + $pdfbuffer.length
    
        <# part-separator "One CRLF" #>
        $terminal = "`r`n"
        $buffer = [Text.Encoding]::ascii.getbytes($terminal)        
        $reqst.write($buffer, 0, $buffer.length)
        $ContentLength = $ContentLength + $buffer.length
    
        <#
        At the end of your request, after writing all of your fields and files to the request, you'll write:
    
        Two dashes.
        Your boundary.
        Two more dashes.
        #>
        $terminal = "--$boundary--"
        $buffer = [Text.Encoding]::ascii.getbytes($terminal)        
        $reqst.write($buffer, 0, $buffer.length)
        $ContentLength = $ContentLength + $buffer.length
    
        $reqst.flush()
        $reqst.close()
    
        # Dump request to console
        #$req
    
        [net.httpWebResponse] $res = $req.getResponse()
    
        # Dump result to console
        #$res
    
        # Dump result-body to filesystem
    <#    
        $resst = $res.getResponseStream()
        $sr = New-Object IO.StreamReader($resst)
        $result = $sr.ReadToEnd()
        $res.close()
    #>
    
        $null = New-Item -ItemType Directory -Force -Path "$path\result"
        $target = "$path\result\P7-T.pdf"
    
        # Create a stream to write to the file system.
        $targetfile = [System.IO.File]::Create($target)
    
        # Create the buffer for copying data.
        $buffer = New-Object Byte[] 1024
    
        # Get a reference to the response stream (System.IO.Stream).
        $resst = $res.GetResponseStream()
    
        # In an iteration...
        Do {
            # ...attemt to read one kilobyte of data from the web response stream.
            $read = $resst.Read($buffer, 0, $buffer.Length)
    
            # Write the just-read bytes to the target file.
            $targetfile.Write($buffer, 0, $read)
    
            # Iterate while there's still data on the web response stream.
        } While ($read -gt 0)
    
        # Close the stream.
        $resst.Close()
        $resst.Dispose()
    
        # Flush and close the writer.
        $targetfile.Flush()
        $targetfile.Close()
        $targetfile.Dispose()
    

提交回复
热议问题