web-dev-qa-db-ja.com

powershell invoke-restmethod multipart / form-data

現在、REST APIを使用してWebサーバーにファイルをアップロードしようとしています。前述のように、PowerShellを使用しています。curlでは問題ありません。呼び出しは次のようになります。 :

curl -H "Auth_token:"$AUTH_TOKEN -H "Content-Type:multipart/form-data" -X POST -F appInfo='{"name": "test","description": "test"}' -F uploadFile=@/test/test.test https://server/api/

しかし、これをInvoke-Restmethodコマンドを使用してpowershellにエクスポートすることに関しては、私は完全に無力です。私が検索した限りでは、これにInvoke-Restメソッドを使用することはできません。 https://www.snip2code.com/Snippet/396726/PowerShell-V3-Multipart-formdata-example しかし、Snippedを使用しても、私はこれを機能させるのに十分スマートではありません。 2つのファイルをアップロードしたいが、代わりに1つのファイルといくつかの引数。

誰かがこれで私をトラックに戻すことができたら私は非常に感謝します:oありがとうございます!

9
maigelnight

それはかなり簡単なはずです。 この答え から:

_$Uri = 'https://server/api/';
$Headers = @{'Auth_token'=$AUTH_TOKEN};
$FileContent = [IO.File]::ReadAllText('C:\test\test.test');
$Fields = @{'appInfo'='{"name": "test","description": "test"}';'uploadFile'=$FileContent};

Invoke-RestMethod -Uri $Uri -ContentType 'multipart/form-data' -Method Post -Headers $Headers -Body $Fields;
_

ファイルがテキストファイルでない場合は、[IO.File]::ReadAllBytes()を使用できます。

巨大なファイルをアップロードする場合も、これはうまく機能しない可能性があります。

11
Bacon Bits

@ベーコンビットの答えは私にはうまくいかなかったようです。私のサーバーは、潜在的に不正な形式のデータ本体でそれを拒否しました:

私は---(this Gist を見つけて、私の目的のために少し切り詰めました。これが私の最終結果です:

$FilePath = 'c:\temp\temp.txt';
$URL = 'http://your.url.here';

$fileBytes = [System.IO.File]::ReadAllBytes($FilePath);
$fileEnc = [System.Text.Encoding]::GetEncoding('UTF-8').GetString($fileBytes);
$boundary = [System.Guid]::NewGuid().ToString(); 
$LF = "`r`n";

$bodyLines = ( 
    "--$boundary",
    "Content-Disposition: form-data; name=`"file`"; filename=`"temp.txt`"",
    "Content-Type: application/octet-stream$LF",
    $fileEnc,
    "--$boundary--$LF" 
) -join $LF

Invoke-RestMethod -Uri $URL -Method Post -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $bodyLines
16
jklemmack

だから、私は最近これとかなり戦いましたが、実際にカール機能を一致させることが可能であることを発見しましたが、マルチパート/フォームデータを正しく行う方法はすぐにはわかりません。上記のすべての応答はパズルの重要な部分をカバーしていますが、ネイティブPowershellにカール機能を実装しようとしている次の申し訳ないフェローのために、ここですべてをまとめて結びます。

@ jklemmack's ソリューションは、私を正しい軌道に乗せたものであり、フォームデータコンテンツを具体的に構築し、両方の境界とデータの方法を制御できるため、最も柔軟ですその中でフォーマットされます。

これを行おうとする人にとっては、Fiddler(.net)やBurp Suite(Java)などの適切なWebデバッグプロキシを用意して、RESTの各呼び出しを詳細に検査できるようにすることが重要だと思いますAPIに渡されるデータの特定の形式を理解する。

私の特定のケースでは、curlがフォームデータの各部分の上に空白行を挿入していることに気付きました。@ jklemmackの例を拡張すると、次のようになります。

    $bodyLines = (
        "--$boundary",
        "Content-Disposition: form-data; name=`"formfield1`"",
        '',
        $formdata1,
        "--$boundary",
        "Content-Disposition: form-data; name=`"formfield2`"",
        '',
        $formdata2,
        "--$boundary",
        "Content-Disposition: form-data; name=`"formfield3`"; filename=`"$name_of_file_being_uploaded`"",
        "Content-Type: application/json",
        '',
        $content_of_file_being_uploaded,
        "--$boundary--"
    ) -join $LF

これにより、将来的に多くの時間を節約できることを願っています!

また、これを最初から行う必要があり、curlネイティブバイナリを直接使用するオプションがある場合(セキュリティとコンプライアンスに関するデューデリジェンスを確保しながら)、その成熟度と便利さを利用することに同意します。カールを使用します。このマルチパートロジックは、内部の開発チームまたは運用チームに責任があるのではなく、curlコミュニティ全体で精力的にテストおよび保守することをお勧めします。

1
jbobbylopez

PowerShell Coreでは、これは新しい-Formパラメータ。

参照: https://docs.Microsoft.com/en-us/powershell/module/Microsoft.powershell.utility/invoke-restmethod?view=powershell-7

$Uri = 'https://api.contoso.com/v2/profile'
$Form = @{
    firstName  = 'John'
    lastName   = 'Doe'
    email      = '[email protected]'
    avatar     = Get-Item -Path 'c:\Pictures\jdoe.png'
    birthday   = '1980-10-15'
    hobbies    = 'Hiking','Fishing','Jogging'
}
$Result = Invoke-RestMethod -Uri $Uri -Method Post -Form $Form
0
grafbumsdi

Invoke-RestMethod を使用して次のcurlコマンドを実行しようとして問題が発生しました:

curl --request POST \
  --url https://example.com/upload_endpoint/ \
  --header 'content-type: multipart/form-data' \
  --form '[email protected]'
  -v

私の場合、Powershell内で直接curlを使用する方がはるかに簡単であることがわかりました。

$FilePath = "C:\example.csv"
$CurlExecutable = "C:\curl-7.54.1-win64-mingw\bin\curl.exe"

Write-Host "CurlFile" $CurlFile
$CurlArguments = '--request', 'POST', 
                'https://example.com/upload_endpoint/',
                '--header', "'content-type: multipart/form-data'",
                '--form', "file=@$FilePath"
                '-v',

& $CurlExecutable @CurlArguments

curlのWebサイト でOSの実行可能ファイルを取得してください。

なぜcurlを使用する必要があるのですか?

Curlは無料のオープンソースソフトウェアであり、デバッグが簡単で、多くのオペレーティングシステムをサポートしています。コマンドラインで直接使用でき、多くのプロトコルをサポートしています。そこにあるツールの多くは、curlコマンドを生成できます。

0
GabLeRoux