SnipeitPS/SnipeitPS/Private/Invoke-SnipeitMethod.ps1

200 lines
7.8 KiB
PowerShell
Raw Normal View History

2021-08-02 08:12:53 +03:00
<#
2017-11-16 11:32:17 +00:00
.SYNOPSIS
2021-08-02 08:12:53 +03:00
Make api request to Snipe it
.PARAMETER Api
Api part of url. prefix with slash ie. "/api/v1/hardware"
.PARAMETER Method
Method of the invokation, one of following "GET", "POST", "PUT", "PATCH" or "DELETE"
.PARAMETER Body
Request body as hashtable. Needed for post, put and patch
.PARAMETER GetParameters
Get-Parameters as hastable.
#>
function Invoke-SnipeitMethod {
2017-11-16 11:32:17 +00:00
[OutputType(
[PSObject]
)]
2021-08-02 08:12:53 +03:00
2017-11-16 11:32:17 +00:00
param (
2021-08-02 08:12:53 +03:00
2017-11-16 11:32:17 +00:00
[Parameter(Mandatory = $true)]
2021-08-02 08:12:53 +03:00
[string]$Api,
2017-11-16 11:32:17 +00:00
[ValidateSet("GET", "POST", "PUT", "PATCH", "DELETE")]
[string]$Method = "GET",
[Hashtable]$Body,
2017-11-16 11:32:17 +00:00
2017-11-18 22:28:44 +00:00
[Hashtable]$GetParameters
2017-11-16 11:32:17 +00:00
)
BEGIN {
#use legacy per command based url and apikey
if ( $null -ne $SnipeitPSSession.legacyUrl -and $null -ne $SnipeitPSSession.legacyApiKey ) {
2021-08-23 18:01:09 +03:00
[string]$Url = $SnipeitPSSession.legacyUrl
Write-Debug "Invoke-SnipeitMethod url: $Url"
2021-09-03 19:44:43 +03:00
if($PSVersionTable.PSVersion -ge '7.0'){
$Token = ConvertFrom-SecureString -AsPlainText -SecureString $SnipeitPSSession.legacyApiKey
} else {
#convert to plaintext via credential
$Token = (New-Object PSCredential "user",$SnipeitPSSession.legacyApiKey).GetNetworkCredential().Password
}
} elseif ($null -ne $SnipeitPSSession.url -and $null -ne $SnipeitPSSession.apiKey) {
[string]$Url = $SnipeitPSSession.url
Write-Debug "Invoke-SnipeitMethod url: $Url"
2021-09-03 19:44:43 +03:00
if($PSVersionTable.PSVersion -ge '7.0'){
$Token = ConvertFrom-SecureString -AsPlainText -SecureString $SnipeitPSSession.apiKey
} else {
#convert to plaintext via credential
$Token = (New-Object PSCredential "user",$SnipeitPSSession.apiKey).GetNetworkCredential().Password
}
2021-08-23 18:01:09 +03:00
} else {
throw "Please use Connect-SnipeitPS to setup connection before any other commands."
2021-08-22 22:23:08 +03:00
}
2017-11-16 11:32:17 +00:00
# Validation of parameters
if (($Method -in ("POST", "PUT", "PATCH")) -and (!($Body))) {
$message = "The following parameters are required when using the ${Method} parameter: Body."
$exception = New-Object -TypeName System.ArgumentException -ArgumentList $message
Throw $exception
}
2021-08-02 08:12:53 +03:00
#Build request uri
$apiUri = "$Url$Api"
#To support images "image" property have be handled before this
2017-11-16 11:32:17 +00:00
$_headers = @{
2021-08-02 08:12:53 +03:00
"Authorization" = "Bearer $($Token)"
2017-11-16 11:32:17 +00:00
'Content-Type' = 'application/json; charset=utf-8'
"Accept" = "application/json"
}
}
Process {
2021-08-02 08:12:53 +03:00
# This can be done using $Body, maybe some day - PetriAsi
if ($GetParameters -and ($apiUri -notlike "*\?*")){
2017-11-18 22:28:44 +00:00
Write-Debug "Using `$GetParameters: $($GetParameters | Out-String)"
2021-08-23 18:39:32 +03:00
[string]$apiUri = $apiUri + (ConvertTo-GetParameter $GetParameters)
2017-11-18 22:28:44 +00:00
# Prevent recursive appends
$GetParameters = $null
}
2017-11-16 11:32:17 +00:00
# set mandatory parameters
$splatParameters = @{
2021-08-02 08:12:53 +03:00
Uri = $apiUri
2017-11-16 11:32:17 +00:00
Method = $Method
Headers = $_headers
UseBasicParsing = $true
ErrorAction = 'SilentlyContinue'
}
2021-08-02 08:12:53 +03:00
# Send image requests as multipart/form-data if supported
if($null -ne $body -and $Body.Keys -contains 'image' ){
2021-07-08 23:59:31 +03:00
if($PSVersionTable.PSVersion -ge '7.0'){
$Body['image'] = get-item $body['image']
# As multipart/form-data is always POST we need add
# requested method for laravel named as '_method'
$Body['_method'] = $Method
$splatParameters["Method"] = 'POST'
$splatParameters["Form"] = $Body
} else {
2021-08-02 08:12:53 +03:00
# use base64 encoded images for powershell version < 7
Add-Type -AssemblyName "System.Web"
$mimetype = [System.Web.MimeMapping]::GetMimeMapping($body['image'])
$Body['image'] = 'data:@'+$mimetype+';base64,'+[Convert]::ToBase64String([IO.File]::ReadAllBytes($Body['image']))
}
}
if ($Body -and $splatParameters.Keys -notcontains 'Form') {
2021-09-03 15:54:55 +03:00
$splatParameters["Body"] = [System.Text.Encoding]::UTF8.GetBytes(($Body | Convertto-Json))
}
2017-11-16 11:32:17 +00:00
$script:PSDefaultParameterValues = $global:PSDefaultParameterValues
2021-06-16 00:52:32 +03:00
Write-Debug "$($Body | ConvertTo-Json)"
2017-11-16 11:32:17 +00:00
# Invoke the API
try {
Write-Verbose "[$($MyInvocation.MyCommand.Name)] Invoking method $Method to URI $URi"
Write-Debug "[$($MyInvocation.MyCommand.Name)] Invoke-WebRequest with: $($splatParameters | Out-String)"
$webResponse = Invoke-RestMethod @splatParameters
2017-11-16 11:32:17 +00:00
}
catch {
Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed to get an answer from the server"
$webResponse = $_.Exception.Response
2017-11-16 11:32:17 +00:00
}
Write-Debug "[$($MyInvocation.MyCommand.Name)] Executed WebRequest. Access $webResponse to see details"
if ($webResponse) {
Write-Verbose "[$($MyInvocation.MyCommand.Name)] Status code: $($webResponse.StatusCode)"
if ($webResponse) {
Write-Verbose $webResponse
2017-11-16 11:32:17 +00:00
2021-08-02 08:12:53 +03:00
# API returned a Content: lets work with it
2021-05-25 23:24:36 +03:00
try{
if ($webResponse.status -eq "error") {
2021-08-02 08:12:53 +03:00
Write-Verbose "[$($MyInvocation.MyCommand.Name)] An error response was received ... resolving"
2021-05-25 23:24:36 +03:00
# This could be handled nicely in an function such as:
# ResolveError $response -WriteError
Write-Error $($webResponse.messages | Out-String)
2021-08-02 08:12:53 +03:00
} else {
2021-06-21 10:42:00 +03:00
#update operations return payload
2021-08-02 08:12:53 +03:00
if ($webResponse.payload) {
$result = $webResponse.payload
2021-05-25 23:24:36 +03:00
}
2021-06-21 10:42:00 +03:00
#Search operations return rows
elseif ($webResponse.rows) {
$result = $webResponse.rows
2021-06-21 10:42:00 +03:00
}
#Remove operations returns status and message
2021-08-02 08:12:53 +03:00
elseif ($webResponse.status -eq 'success') {
2021-06-21 10:42:00 +03:00
$result = $webResponse.payload
}
2021-08-18 10:13:11 +03:00
#Search and query result with no results
elseif ($webResponse.total -eq 0){
$result = $null
}
2021-06-21 10:42:00 +03:00
#get operations with id returns just one object
else {
$result = $webResponse
2021-05-25 23:24:36 +03:00
}
2021-06-21 10:42:00 +03:00
Write-Verbose "Status: $($webResponse.status)"
Write-Verbose "Messages: $($webResponse.messages)"
2021-05-25 23:24:36 +03:00
$result
2017-11-16 11:32:17 +00:00
}
}
2021-05-25 23:24:36 +03:00
catch {
Write-Warning "Cannot parse server response. To debug try to add -Verbose with command."
}
2017-11-16 11:32:17 +00:00
}
elseif ($webResponse.StatusCode -eq "Unauthorized") {
2021-08-02 08:12:53 +03:00
Write-Error "[$($MyInvocation.MyCommand.Name)] You are not Authorized to access the resource, check your apiKey is correct"
}
2017-11-16 11:32:17 +00:00
else {
# No content, although statusCode < 400
# This could be wanted behavior of the API
Write-Verbose "[$($MyInvocation.MyCommand.Name)] No content was returned from."
}
2017-11-20 09:15:11 +00:00
2017-11-16 11:32:17 +00:00
}
else {
Write-Verbose "[$($MyInvocation.MyCommand.Name)] No Web result object was returned from. This is unusual!"
}
}
END {
Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function ended"
}
2017-11-20 09:15:11 +00:00
}
2021-08-02 08:12:53 +03:00