API - Get records in bulk (Powershell)

Document created by Sam Buccieri-Gillett on Nov 28, 2017Last modified by Sam Buccieri-Gillett on Nov 30, 2017
Version 2Show Document
  • View in full screen mode

Here's a handy PS function I wrote to pull lots of stuff from the API en-masse. Note I've only tested this on Incidents, Users, Roles, and Sites so far I think, so of course use with caution and YMMV.  If you want token-based auth that would be easy to add.

function Get-SamanageRecords() {
   
    param (
        [Parameter(Mandatory=$True)]
        [ValidateNotNullOrEmpty()]
        [String]$ApiUri,

        [Parameter(Mandatory=$True)]
        [ValidateNotNullOrEmpty()]
        [PSCredential]$Credential,

        [Parameter(Mandatory=$True)]
        [ValidateNotNullOrEmpty()]
        [String]$RecordType,

        [Parameter(Mandatory=$False)]
        [ValidateNotNullOrEmpty()]
        [String]$outFile,

        #To filter lists at time of query, e.g. set to "requested_by=2595353" for /incidents?requested_by=2595353
        [Parameter(Mandatory=$false)]
        [ValidateNotNullOrEmpty()]
        [String]$SamanageUrlFilterParameters
    )

    #API is case-sensitive
    $ApiUri = $ApiUri.ToLower()
    $RecordType = $RecordType.ToLower()
    #Headers
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $headers.Add("Accept", 'application/vnd.samanage.v1.3+xml')

    #Get size of full dataset so we can know how many pages to page through
    $tempResult = Invoke-RestMethod -Uri "$($ApiUri)/$($RecordType).xml?per_page=100&page=1&$SamanageUrlFilterParameters" -Credential $Credential -Headers $headers -ContentType "text/xml" -Method Get -ErrorAction Stop
    $results = $tempResult.$RecordType
    if (!$results) { Write-Warning "No results found!"; return $null; }

    #Cycle through paginated results and output
    $totalPages = [math]::ceiling($results.total_entries/$results.per_page)
    $result = @()
    if ($totalPages -gt 20) {
        if (!$outFile) {
            Write-Error 'OutFile parameter was not specified. A large dataset must be exported to a file'
            Return $null
        } else {
            #Remove old results file if it exists
            Write-Warning "This is a large dataset and will be exported to $outFile"
            if (Test-Path $outFile) {
                try { Remove-Item $outFile -force }
                catch { Write-Error "Could not delete existing log file" }
            }
        }
    }

    for($i=1; $i -le $totalPages; $i++) {
        if ($totalPages -gt 20) {
            (Invoke-RestMethod -Uri "$ApiUri/$($RecordType).json?per_page=100&page=$i&$SamanageUrlFilterParameters" -Credential $Credential -Headers $headers -ContentType "application/json" -Method Get).SyncRoot | Export-Csv $outFile -Append
        } else {
            $response = Invoke-RestMethod -Uri "$ApiUri/$($RecordType).json?per_page=100&page=$i&$SamanageUrlFilterParameters" -Credential $Credential -Headers $headers -ContentType "application/json" -Method Get
            $result += $response
        }
        Write-Progress -Activity "Getting $RecordType" -PercentComplete ($i/$totalPages*100)
    }
   
    Return $result
}

An example of how you would use this:

$creds = Get-Credential
$apiAddr = "https://api.samanage.com" #or use https://apieu.samanage.com depending on your tenant affinity

$CompanyXUsers= Get-SamanageRecords -ApiUri $apiAddr -Credential $creds -RecordType "Users" -SamanageUrlFilterParameters "email[]=*company.com"

Hope this helps someone!

2 people found this helpful

Attachments

    Outcomes