Last active
October 24, 2019 08:03
-
-
Save russcam/7fbdbaa37e3dcb3fd3ee0aa54af3708c to your computer and use it in GitHub Desktop.
PowerShell module to provide a curl like experience interacting with Elasticsearch from PowerShell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
New-Module -Name ElasticShell -Scriptblock { | |
<# | |
.Synopsis | |
Execute REST API requests against Elasticsearch | |
.Description | |
Execute REST API requests against Elasticsearch. | |
Provides a curl-like experience for interacting with Elasticsearch, but with \m/ PowerShell \m/ | |
.Example | |
es _cat/indices | |
.Example | |
es twitter/tweet/1 -Pretty -Method PUT -Body @' | |
{ | |
"user" : "kimchy", | |
"post_date" : "2009-11-15T14:12:12", | |
"message" : "trying out Elasticsearch" | |
} | |
'@ | |
.Example | |
es posts/_search?pretty -u elastic:changeme -d @{ | |
query = @{ | |
match = @{ | |
user = "kimchy" | |
} | |
} | |
} | |
.Example | |
es posts/_bulk -ContentType application/x-ndjson -d C:\data.json | |
.Example | |
gc C:\data.json | es posts/_bulk -ContentType application/x-ndjson | |
.Parameter Method | |
the HTTP method to use. For requests with a body, will default to POST and without, GET. | |
.Parameter Uri | |
the Uri to request. A relative path will make a request to http://localhost:9200 | |
.Parameter User | |
the username for Authentication. the password may also be specified here using the format username:password | |
.Parameter Password | |
the password for Authentication. if username is specified but password is not, a prompt will be displayed to provide the password. | |
.Parameter Body | |
the request body. May be a JSON string literal, a HashTable, or a path to a file containing JSON | |
.Parameter ContentType | |
the Content-Type HTTP header. By default, uses "application/json" | |
.Parameter Headers | |
the HTTP headers to send | |
.Parameter Pretty | |
Pretty print (indent) the JSON response. May be supplied as a query string parameter on Uri with ?pretty or ?pretty=true | |
.Parameter ResponseVariable | |
The name of a variable to which the response will be assigned, with global scope. | |
The response can be inspected for response headers, status code, etc. | |
.Inputs | |
the request body. May be a JSON string literal, a HashTable, or a path to a file containing JSON | |
.Outputs | |
the response body | |
.Notes | |
Author: Russ Cam - forloop.co.uk | |
License: Apache-2.0 - https://www.apache.org/licenses/LICENSE-2.0.txt | |
.Link | |
https://forloop.co.uk | |
.Link | |
https://www.elastic.co/products/elasticsearch | |
#> | |
function Invoke-Elasticsearch { | |
[CmdletBinding()] | |
[OutputType([String])] | |
param ( | |
[string] | |
[ValidateSet("GET", "PUT", "POST", "DELETE", "HEAD")] | |
[Alias("X")] | |
$Method, | |
[string] | |
[Parameter(Mandatory=$true,Position=0)] | |
$Uri, | |
[string] | |
[Alias("u")] | |
$User, | |
[SecureString] | |
$Password, | |
[Alias("d")] | |
[Alias("data")] | |
[Parameter(ValueFromPipeline=$true)] | |
$Body, | |
[string] | |
$ContentType = "application/json", | |
[Alias("H")] | |
$Headers = @{}, | |
[switch] | |
$Pretty, | |
[Alias("r")] | |
[Alias("response")] | |
[string] | |
$ResponseVariable | |
) | |
Begin { | |
Add-Type -AssemblyName System.Web | |
} | |
Process { | |
if (-not $Method) { | |
if ($Body) { | |
$Method = "Post" | |
} else { | |
$Method = "Get" | |
} | |
} | |
if ($Uri) { | |
$parsedUri = $null | |
if ([Uri]::TryCreate($Uri, [UriKind]::RelativeOrAbsolute, [ref]$parsedUri) -and ` | |
-not $parsedUri.IsAbsoluteUri) { | |
$parsedUri = New-Object System.Uri "http://localhost:9200/$($parsedUri.OriginalString.TrimStart('/'))" | |
} | |
} | |
else { | |
$parsedUri = New-Object System.Uri "http://localhost:9200/" | |
} | |
# ParseQueryString does not respect keys without values, so test .Query directly | |
if ($Pretty -and (-not $parsedUri.Query -or $parsedUri.Query -match "[?|&]pretty(?=\=false)")) { | |
$queryString = [Web.HttpUtility]::ParseQueryString($parsedUri.Query) | |
if (-not $queryString) { | |
$queryString = New-Object System.Collections.Specialized.NameValueCollection | |
} | |
$queryString.Set("pretty","true") | |
$uriBuilder = New-Object System.UriBuilder $parsedUri | |
$uriBuilder.Query = $queryString.ToString(); | |
$parsedUri = $uriBuilder.Uri | |
} | |
if ($User) { | |
$userParts = $User.Split(':', 2) | |
if ($userParts.Length -eq 2) { | |
$User = $userParts[0] | |
$Password = $userParts[1] | ConvertTo-SecureString -AsPlainText -Force | |
} | |
while (-not $Password -or $Password.Length -eq 0) { | |
$Password = Read-Host -AsSecureString "Enter password for $($User):" | |
} | |
$credential = New-Object System.Management.Automation.PSCredential ($User, $Password) | |
} | |
$requestParameters = @{ | |
Uri = $parsedUri | |
ContentType = $ContentType | |
Headers = $Headers | |
Credential = $credential | |
Method = $Method | |
UseBasicParsing = $true | |
} | |
if ($Body -and $Body -is [string]) { | |
if (Test-Path $Body -PathType Leaf) { | |
$requestParameters.InFile = $Body | |
} else { | |
$requestParameters.Body = $Body | |
} | |
} else { | |
$requestParameters.Body = $Body = $Body | ConvertTo-Json | |
} | |
try { | |
$response = iwr @requestParameters | |
if ($ResponseVariable) { | |
Set-Variable -Name $ResponseVariable -Value $response -Scope Global | |
} | |
return $response.Content | |
} | |
catch { | |
$response = $_.Exception.Response | |
if ($ResponseVariable) { | |
Set-Variable -Name $ResponseVariable -Value $response -Scope Global | |
} | |
if ($response) { | |
$responseStream = $response.GetResponseStream() | |
$reader = New-Object System.IO.StreamReader($responseStream) | |
$reader.BaseStream.Position = 0 | |
$reader.DiscardBufferedData() | |
return $reader.ReadToEnd() | |
} else { | |
throw $_.Exception | |
} | |
} | |
} | |
} | |
Set-Alias -Name es -Value Invoke-Elasticsearch -Description "Sends a request to Elasticsearch" | |
Set-Alias -Name hash -Value ConvertFrom-Json -Description "Converts JSON into a dictionary/hashmap" | |
Export-ModuleMember -Function 'Invoke-Elasticsearch' -Alias 'es','hash' | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To install