title: Coinbase Exchange API with PowerShell
body: <p>I feel like I'm really close to being able to use the Coinbase Exchange API with PowerShell, but I'm having trouble creating a valid signature. Requests that don't require a signature, like /time and /products, work great.</p>
  
  <p>Here's what I have so far.</p>
  
  <pre><code>$api = @{
      "endpoint" = 'https://api.gdax.com'
      "url" = '/account'
      "method" = 'GET'
      "body" = ''
      "key" = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
      "secret" = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
      "passphrase" = 'xxxxxxxx'
  }
  
  # Base64 encoding/decoding functions derived from
  # http://vstepic.blogspot.com/2013/02/how-to-convert-string-to-base64-and.html 
  function Base64-Encode($string) {
      $conversion = [System.Text.Encoding]::ASCII.GetBytes($string)
      return [System.Convert]::ToBase64String($conversion)
  }
  
  function Base64-Decode($string) {
      $conversion = [System.Convert]::FromBase64String($string)
      return [System.Text.Encoding]::ASCII.GetString($conversion)
  }
  
  # HMAC SHA256 code derived from
  # http://www.jokecamp.com/blog/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/
  function hmac($message, $secret) {
      $hmacsha = New-Object System.Security.Cryptography.HMACSHA256
      $hmacsha.key = [Text.Encoding]::ASCII.GetBytes($secret)
      $signature = $hmacsha.ComputeHash([Text.Encoding]::ASCII.GetBytes($message))
      $signature = [Convert]::ToBase64String($signature)
      return $signature
  }
  
  function Submit-Request($request) {
      $unixEpochStart = Get-Date -Date "01/01/1970"
      $now = Get-Date
      $timestamp = (New-TimeSpan -Start $unixEpochStart -End $now.ToUniversalTime()).TotalSeconds.ToString()
      # create the prehash string by concatenating required parts
      $prehash = $timestamp + $request.method.ToUpper() + $request.url + $request.body
      $signature_b64 = hmac -message $prehash -secret (Base64-Decode $request.secret)
      $header = @{
          "CB-ACCESS-KEY" = $request.key
          "CB-ACCESS-SIGN" = $signature_b64
          "CB-ACCESS-TIMESTAMP" = $timestamp
          "CB-ACCESS-PASSPHRASE" = $request.passphrase
          "Content-Type" = 'application/json'
      }
      $uri = $request.endpoint + $request.url
      if ($request.method.ToUpper() -eq 'POST') {
          $response = Invoke-RestMethod -Method $request.method -Uri $uri -Headers $header -Body $request.body
      } else {
          $response = Invoke-RestMethod -Method $request.method -Uri $uri -Headers $header
      }
      return $response
  }
  
  $api.method = 'GET'
  $api.url = '/account'
  $response = Submit-Request $api
  Write-Output $response
  </code></pre>