Powershell 2.0環境で、RESTインターフェースへ、データをPOSTする

シェアする

Powershell Ver2.0 の 制約

Powershellもバージョンがあがるにつれ、利用できるコマンドレットが増え、機能強化されています。特にVer2(Windows 7 標準)からVer3(Windows 8 標準)の間での進化が顕著です。

Powershell Version 2.0 3.0 4.0
Windows7 Windows 8 Windows 8.1
WS2008R2 WS2012 WS2012R2
Invoke-RestMethod

RESTインターフェースへ、JSONデータ等をPOSTする際にも、この差を感じます。 Ver3環境なら 標準コマンドレット Invoke-RestMethod がすべて良しなにやってくれますが、Ver2の環境ではちょっとしたコードが必要になります

前提

予め以下の変数に、パラメータを入れておきます。 $ServerURI => Post宛先のサーバーURI $Data => Postするデータ

例)
$ServerURI = 'http://localhost:8888/test.tag.here'
$Data = 'json={`action`:`login`,`user`:2}'

サンプルコード Powershell 3.0

Invoke-RestMethod -Method Post -Uri $ServerURI -Body $Data

サンプルコード Powershell 2.0

function Invoke-HttpPost {
    [CmdletBinding()]
    Param
    (
        [string] $URI,
        [string] $Body
    )
    
    #チェックフラグ
    [Bool] $MethodResult = $True

    [System.Net.HttpWebRequest]$HttpWebRequest = [System.Net.WebRequest]::Create($URI)
    $HttpWebRequest.ContentType = `application/x-www-form-urlencoded`
    $BodyStr = [System.Text.Encoding]::UTF8.GetBytes($Body)
    $HttpWebrequest.ContentLength = $BodyStr.Length
    $HttpWebRequest.ServicePoint.Expect100Continue = $false
    $HttpWebRequest.Timeout = 30
    $HttpwebRequest.Method = `POST`

    # [System.Net.WebRequest]::GetRequestStream()
    # [System.IO.Stream]::Write()
    Try
    {
        [System.IO.Stream] $RequestStream = $HttpWebRequest.GetRequestStream()
        $RequestStream.Write($BodyStr, 0, $BodyStr.length)
        $MethodResult = $True
    }
    Catch [System.Net.WebException]
    {
        $WebException = $_.Exception
        Write-Verbose (`{0}: {1}` -f $WebException.Status, $WebException.Message)
        $MethodResult = $False
    }
    Catch [Exception]
    {
        Write-Error $Error[0].Exception.ErrorRecord
        $MethodResult = $False
    } Finally {
        If ($RequestStream -ne $Null)
        {
            $RequestStream.Close()
        }
    }


    # [System.Net.WebRequest]::GetResponse()
    If($MethodResult)
    {
        Try
        {
            [System.Net.HttpWebResponse] $resp = $HttpWebRequest.GetResponse();
            Write-Verbose (`{0}: {1}` -f [int]$resp.StatusCode, $resp.StatusCode)
            $resp.Close()
            $MethodResult = $True
        }
        Catch [System.Net.WebException]
        {
            $ErrResp = $_.Exception.Response
            If ($ErrResp -ne $Null)
            {
                [System.Net.HttpWebResponse]$err = $ErrResp
                Write-Verbose (`{0}: {1}` -f [int]$err.StatusCode, $err.StatusCode)
                $ErrResp.Close()
            }
            $MethodResult = $False
        }
        Catch [Exception]
        {
            Write-Error $Error[0].Exception.ErrorRecord
            $MethodResult = $False
        }

        # 処理 成功・失敗を返す
        Write-Output $MethodResult
    }
}

Invoke-HttpPost -Uri $ServerURI -Body $Data
補足

文字コードは「UTF-8」でPOSTしています。 URLエンコードしていません。(受け付ける側はバイナリーセーフである前提です)