Skip to content

Commit

Permalink
Merge pull request KelvinTegelaar#2 from KelvinTegelaar/master
Browse files Browse the repository at this point in the history
re-sync
  • Loading branch information
robgilbreath authored Oct 15, 2020
2 parents 993f8b7 + 2c5d6af commit 3707086
Show file tree
Hide file tree
Showing 10 changed files with 535 additions and 501 deletions.
Binary file modified AutoTaskAPI.psd1
Binary file not shown.
511 changes: 10 additions & 501 deletions AutotaskAPI.psm1

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions Private/New-ResourceDynamicParameter.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<#
.SYNOPSIS
Creates a new dynamic parameter for either the resource list or definitionslist inside of v1.json.
.DESCRIPTION
Creates a new dynamic parameter for either the resource list or definitionslist inside of v1.json by opening the file, reading the contents and converting a custom object.
this returns the used array. Definitons might be removed in future releases.
.EXAMPLE
PS C:\> New-ResourceDynamicParameter -Parametertype "Resource"
Creates
.INPUTS
-Parametertype: Resource or Definitions
.OUTPUTS
none
.NOTES
Function might be changed at release of new API.
#>
function New-ResourceDynamicParameter
(
[Parameter(Mandatory = $true)][string]$ParameterType
) {
$ParameterName = "Resource"
$RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
$ParameterAttribute.Mandatory = $true
$AttributeCollection.Add($ParameterAttribute)
if (!$Script:Swagger) { $Script:Swagger = get-content "$($MyInvocation.MyCommand.Module.ModuleBase)\v1.json" -raw | ConvertFrom-Json }
$Script:Queries = foreach ($Path in $Script:Swagger.paths.psobject.Properties) {
[PSCustomObject]@{
Name = $path.Name
Get = $Path.value.get.tags
Post = $Path.value.post.tags
Patch = $Path.value.patch.tags
Delete = $Path.value.delete.tags

}
}
$ResourceList = foreach ($query in $Queries | where-object { $null -ne $_."$ParameterType" } ) {
$resource = $query."$ParameterType" | Select-Object -last 1
$resource
}

$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ResourceList)
$AttributeCollection.Add($ValidateSetAttribute)
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
$RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
return $RuntimeParameterDictionary
}
41 changes: 41 additions & 0 deletions Public/Add-AutotaskAPIAuth.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<#
.SYNOPSIS
Sets the API authentication information.
.DESCRIPTION
Sets the API Authentication headers, and automatically tries to find the correct URL based on your username.
.EXAMPLE
PS C:\> Add-AutotaskAPIAuth -ApiIntegrationcode 'ABCDEFGH00100244MMEEE333' -credentials $Creds
Creates header information for Autotask API.
.INPUTS
-ApiIntegrationcode: The API Integration code found in Autotask
-Credentials : The API user credentials
.OUTPUTS
none
.NOTES
Function might be changed at release of new API.
#>
function Add-AutotaskAPIAuth (
[Parameter(Mandatory = $true)]$ApiIntegrationcode,
[Parameter(Mandatory = $true)][PSCredential]$credentials
) {
#We convert the securestring...back to a normal string :'( Why basic auth AT? why?!
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($credentials.Password)
$Secret = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($BSTR)
$Script:AutotaskAuthHeader = @{
'ApiIntegrationcode' = $ApiIntegrationcode
'UserName' = $credentials.UserName
'Secret' = $secret
'Content-Type' = 'application/json'
}
write-host "Retrieving webservices URI based on username" -ForegroundColor Green
try {
$Version = (Invoke-RestMethod -Uri "https://webservices2.autotask.net/atservicesrest/versioninformation").apiversions | select-object -last 1
$AutotaskBaseURI = Invoke-RestMethod -Uri "https://webservices2.autotask.net/atservicesrest/$($Version)/zoneInformation?user=$($Script:AutotaskAuthHeader.UserName)"
write-host "Setting AutotaskBaseURI to $($AutotaskBaseURI.url) using version $Version" -ForegroundColor green
Add-AutotaskBaseURI -BaseURI $AutotaskBaseURI.url.Trim('/')
}
catch {
write-host "Could not Retrieve baseuri. E-mail address might be incorrect. You can manually add the baseuri via the Add-AutotaskBaseURI cmdlet. $($_.Exception.Message)" -ForegroundColor red
}

}
58 changes: 58 additions & 0 deletions Public/Add-AutotaskBaseURI.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<#
.SYNOPSIS
Sets the current API URL
.DESCRIPTION
Sets the API URL to the selected URL. URLs parameters can be tab-completed.
.EXAMPLE
PS C:\> Add-AutotaskBaseURI -BaseURI https://webservices2.autotask.net/atservicesrest
Sets the autotask BaseURI to https://webservices2.autotask.net/atservicesrest
.INPUTS
-BaseURI: one of the following list:
"https://webservices2.autotask.net/atservicesrest",
"https://webservices11.autotask.net/atservicesrest",
"https://webservices1.autotask.net/atservicesrest",
"https://webservices17.autotask.net/atservicesrest",
"https://webservices3.autotask.net/atservicesrest",
"https://webservices14.autotask.net/atservicesrest",
"https://webservices5.autotask.net/atservicesrest",
"https://webservices15.autotask.net/atservicesrest",
"https://webservices4.autotask.net/atservicesrest",
"https://webservices16.autotask.net/atservicesrest",
"https://webservices6.autotask.net/atservicesrest",
"https://prde.autotask.net/atservicesrest",
"https://pres.autotask.net/atservicesrest",
"https://webservices18.autotask.net/atservicesrest",
"https://webservices19.autotask.net/atservicesrest",
"https://webservices12.autotask.net/atservicesrest"
.OUTPUTS
none
.NOTES
To-do:
#>
function Add-AutotaskBaseURI (
[ValidateSet(
"https://webservices2.autotask.net/atservicesrest",
"https://webservices11.autotask.net/atservicesrest",
"https://webservices1.autotask.net/atservicesrest",
"https://webservices17.autotask.net/atservicesrest",
"https://webservices3.autotask.net/atservicesrest",
"https://webservices14.autotask.net/atservicesrest",
"https://webservices5.autotask.net/atservicesrest",
"https://webservices15.autotask.net/atservicesrest",
"https://webservices4.autotask.net/atservicesrest",
"https://webservices16.autotask.net/atservicesrest",
"https://webservices6.autotask.net/atservicesrest",
"https://prde.autotask.net/atservicesrest",
"https://pres.autotask.net/atservicesrest",
"https://webservices18.autotask.net/atservicesrest",
"https://webservices19.autotask.net/atservicesrest",
"https://webservices12.autotask.net/atservicesrest")]
[Parameter(Mandatory = $true)]$BaseURI
) {
$Script:AutotaskBaseURI = "$($BaseURI)"
write-host "Setting API resource parameters. This may take a moment." -ForegroundColor green
$Script:GetParameter = New-ResourceDynamicParameter -Parametertype "Get"
$Script:PatchParameter = New-ResourceDynamicParameter -Parametertype "Patch"
$Script:DeleteParameter = New-ResourceDynamicParameter -Parametertype "Delete"
$Script:POSTParameter = New-ResourceDynamicParameter -Parametertype "Post"
}
112 changes: 112 additions & 0 deletions Public/Get-AutotaskAPIResource.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<#
.SYNOPSIS
Gets a specified resource in the API.
.DESCRIPTION
Gets a specified resource in the API. retrieves data based either on ID or specific JSON query.
.EXAMPLE
PS C:\> Get-AutotaskAPIResource -resource Companies -id 1234 -verbose
Gets the company with ID 1234
Get-AutotaskAPIResource -resource Companies -SearchQuery "{filter='active -eq True'}"
Gets all companies with the filter "Active = true"
.INPUTS
-ID: Search by Autotask ID. Accept pipeline input.
-SearchQuery: JSON search filter.
-SimpleSearch: a simple search filter, e.g. name eq Lime
.OUTPUTS
none
.NOTES
TODO: Turns out some items have child URLS. figure that out.
#>
function Get-AutotaskAPIResource {
[CmdletBinding()]
Param(
[Parameter(ParameterSetName = 'ID', Mandatory = $true)]
[Parameter(ValueFromPipelineByPropertyName = $true)]
[String]$ID,
[Parameter(ParameterSetName = 'ID', Mandatory = $false)]
[String]$ChildID,
[Parameter(ParameterSetName = 'SearchQuery', Mandatory = $true)]
[String]$SearchQuery,
[Parameter(ParameterSetName = 'SimpleSearch', Mandatory = $true)]
[String]$SimpleSearch
)
DynamicParam {
$Script:GetParameter
}
begin {
if (!$Script:AutotaskAuthHeader -or !$Script:AutotaskBaseURI) {
Write-Warning "You must first run Add-AutotaskAPIAuth before calling any other cmdlets"
break
}
$resource = $PSBoundParameters.resource
$headers = $Script:AutotaskAuthHeader
$ResourceURL = (($Script:Queries | Where-Object { $_.GET -eq $Resource }).Name | Select-Object -first 1) -replace '/query', '/{PARENTID}' | Select-Object -first 1
if ($SimpleSearch) {
$SearchOps = $SimpleSearch -split ' '
$SearchQuery = convertto-json @{
filter = @(@{
field = $SearchOps[0]
op = $SearchOps[1]
value = $SearchOps | select-object -skip 2
})
} -Compress

}
}

process {
if ($resource -like "*child*" -and $SearchQuery) {
write-warning "You cannot perform a JSON Search on child items. To find child items, use the parent ID."
break
}
if ($ID) {
$ResourceURL = ("$($ResourceURL)" -replace '{parentid}', "$($ID)")
}
if ($ChildID) {
$ResourceURL = ("$($ResourceURL)/$ChildID")
}
if ($SearchQuery) {
$ResourceURL = ("$($ResourceURL)/query?search=$SearchQuery" -replace '{PARENTID}', '')
}
$SetURI = "$($Script:AutotaskBaseURI)/$($ResourceURL)"
try {
do {
$items = Invoke-RestMethod -Uri $SetURI -headers $Headers -Method Get
$SetURI = $items.PageDetails.NextPageUrl
#[System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([datetime]::UtcNow, (get-timezone).id)

if ($items.items) {
foreach ($item in $items.items) {

$item
}
}
if ($items.item) {
foreach ($item in $items.item) {

$item
}

}
} while ($null -ne $SetURI)
}
catch {
if ($psversiontable.psversion.major -lt 6) {
$streamReader = [System.IO.StreamReader]::new($_.Exception.Response.GetResponseStream())
$streamReader.BaseStream.Position = 0
if ($streamReader.ReadToEnd() -like '*{*') { $ErrResp = $streamReader.ReadToEnd() | ConvertFrom-Json }
$streamReader.Close()
}
if ($ErrResp.errors) {
write-error "API Error: $($ErrResp.errors)"
}
else {
write-error "Connecting to the Autotask API failed. $($_.Exception.Message)"
}
}

}
}
59 changes: 59 additions & 0 deletions Public/New-AutotaskAPIResource.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

<#
.SYNOPSIS
Creates a new resource in the API to the supplied object.
.DESCRIPTION
Creates resource in the API to the supplied object. Uses the Post method. Null values will not be published.
.EXAMPLE
PS C:\> New-AutotaskAPIResource -resource companies -body $body
Creates a new company using the body $body
.INPUTS
-Resource: Which resource to find. Tab completion is available.
-Body: Body created based on the model of the API. Accepts pipeline input.
.OUTPUTS
none
.NOTES
So the API actually contains a method to get the fields for a body. Thinking of using that instead.
/atservicesrest/v1.0/EntityName/entityInformation/field
#>
function New-AutotaskAPIResource {
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]$Body
)
DynamicParam {
$Script:POSTParameter
}
begin {
if (!$Script:AutotaskAuthHeader -or !$Script:AutotaskBaseURI) {
Write-Warning "You must first run Add-AutotaskAPIAuth before calling any other cmdlets"
break
}
$resource = $PSBoundParameters.resource
$headers = $Script:AutotaskAuthHeader
$ResourceURL = (($Script:Queries | Where-Object { $_.'Post' -eq $Resource }).Name | Select-Object -first 1) -replace '/query', '' | Select-Object -first 1
}

process {
$SendingBody = $body | ConvertTo-Json -Depth 10
try {
Invoke-RestMethod -Uri "$($Script:AutotaskBaseURI)/$($resourceurl)" -headers $Headers -Method post -Body $SendingBody
}
catch {
if ($psversiontable.psversion.major -lt 6) {
$streamReader = [System.IO.StreamReader]::new($_.Exception.Response.GetResponseStream())
$streamReader.BaseStream.Position = 0
if ($streamReader.ReadToEnd() -like '*{*') { $ErrResp = $streamReader.ReadToEnd() | ConvertFrom-Json }
$streamReader.Close()
}
if ($ErrResp.errors) {
write-error "API Error: $($ErrResp.errors)"
}
else {
write-error "Connecting to the Autotask API failed. $($_.Exception.Message)"
}
}
}
}
72 changes: 72 additions & 0 deletions Public/New-AutotaskBody.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<#
.SYNOPSIS
Creates a pscustomobject to send to api
.DESCRIPTION
Creates a pscustomobject to send to api. Uses Models in V1.JSON
.EXAMPLE
PS C:\> $body = New-AutotaskBody -Resource CompanyModel
Creates a new object in $Body with the companymodel, filled with expected content(e.g. int, string, boolean)
PS C:\> $body = New-AutotaskBody -Resource CompanyModel -NoContent
Creates a new, empty object in $Body with the companymodel,
.INPUTS
-NoContent Creates an empty object.
-Resource tab completed model to use.
.OUTPUTS
none
.NOTES
Function might be changed at release of new API.
#>
function New-AutotaskBody {
[CmdletBinding()]
Param(
[Parameter(Mandatory = $false)][switch]$NoContent
)
DynamicParam {
$Script:PatchParameter
}
begin {
if (!$Script:AutotaskAuthHeader -or !$Script:AutotaskBaseURI) {
Write-Warning "You must first run Add-AutotaskAPIAuth before calling any other cmdlets"
break
}
$resource = $PSBoundParameters.resource
$Headers = $Script:AutotaskAuthHeader
}
process {
$ResourceURL = (($Script:Queries | Where-Object { $_.'Patch' -eq $Resource }).Name | Select-Object -first 1) -replace '/query', '' | Select-Object -first 1
try {
$resource = $PSBoundParameters.resource
$ObjectTemplate = (Invoke-RestMethod -Uri "$($Script:AutotaskBaseURI)/$($resourceURL)/entityInformation/fields" -headers $Headers -Method Get).fields
$UDFs = (Invoke-RestMethod -Uri "$($Script:AutotaskBaseURI)/$($resourceURL)/entityInformation/userdefinedfields" -headers $Headers -Method Get).fields | select-object name, value
if (!$ObjectTemplate) {
Write-Warning "Could not retrieve example body for $($Resource)"
}
else {
if ($NoContent) {
$ReturnedDef = [pscustomobject]
foreach ($prop in $ObjectTemplate.Name) {
$ReturnedDef | Add-Member -NotePropertyName $prop -NotePropertyValue $null -Force
}

}
if (!$NoContent) {
$ReturnedDef = [pscustomobject]
$ReturnedDef | Add-Member -NotePropertyName 'UserdefinedFields' -NotePropertyValue $UDFs -Force
foreach ($prop in $ObjectTemplate) {
$ExpectedValue = if ($prop.picklistValues) { $prop.picklistValues | select-object Label, Value, IsActive } else { $($prop.datatype) }
$ReturnedDef | Add-Member -NotePropertyName $prop.name -NotePropertyValue $ExpectedValue -Force
}
}
}
$Names = if ($UDFS) { $ObjectTemplate.name + "UserDefinedFields" } else { $ObjectTemplate.name }
return $ReturnedDef | select-object $Names

}
catch {
write-error "Getting object failed: $($_.Exception.Message)"
}

}
}
Loading

0 comments on commit 3707086

Please sign in to comment.