REST to GraphQL Example: Exporting All N-central Devices
Let’s walk through a real-world example using one of N-central’s recipes - exporting all devices. First, we’ll look at how this works using REST, and then we’ll show how GraphQL simplifies and streamlines the process.
Notes
- Ensure your network allows outbound HTTPS requests to
api.n-able.com. - Replace "
YOUR_TOKEN_HERE" with your actual API token. - Customise export paths or format as needed.
REST API Approach (PowerShell)
With REST, you need to:
-
- Call
/customersto get customer info.
- Call
-
- Call
/devicesto get device info.
- Call
-
- Manually join the data in PowerShell.
-
- Format and export the result.
function NCentral-Customers {
param ([string]$apiUrl, [string]$accessToken)
$uri = "$apiUrl/api/customers"
$headers = @{ "Authorization" = "Bearer $accessToken" }
$response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
return $response.data
}
function NCentral-Devices {
param ([string]$apiUrl, [string]$accessToken)
$uri = "$apiUrl/api/devices"
$headers = @{ "Authorization" = "Bearer $accessToken" }
$response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
return $response.data
}
$customers = NCentral-Customers -apiUrl $apiUrl -accessToken $accessToken
$devices = NCentral-Devices -apiUrl $apiUrl -accessToken $accessToken
$combinedTable = @()
foreach ($customer in $customers) {
$customerDevices = $devices | Where-Object { $_.customerId -eq $customer.customerId }
foreach ($device in $customerDevices) {
$combinedTable += [PSCustomObject]@{
"Customer ID" = $customer.customerId
"Customer Name" = $customer.customerName
"Site Name" = $device.siteName
"Device ID" = $device.deviceId
"Device Name" = $device.longName
"Device Class" = $device.deviceClass
}
}
}
$combinedTable | Format-Table -AutoSize
This method is effective, but it involves multiple API calls, manual data merging, and custom scripting - even though the query itself is relatively simple, accessing just two endpoints.
GraphQL Approach (Apollo Explorer)
With GraphQL, you can do all of this in one query to return a single response, already joined and structured
- Device ID, name, class, and site.
- Customer ID and name.
query GetAllNCentralDevices{
assetSearch {
nodes {
id
name
customer {
id
name
}
operatingSystemInfo {
name
architecture
type
}
}
}
}If you want to add or remove fields, simply alter the query and run it again. The response updates instantly with no need to change endpoints or reprocess data.
Bonus Features with GraphQL
Dynamic Field Selection
Choose only the fields you need - no overfetching.
Built-in Sorting
Want to sort the results based on a field? Just add orderBy the field: you want to use and direction:. For example, to sort by Customer Name and descending add:
query GetAllNCentralDevices{
assetSearch(orderBy: { field: CUSTOMER_NAME, direction: DESC }) {
...
}
}Switch to ascending with direction: ASC.
Simplified Automation
Once your query is ready, you can plug it directly into a PowerShell script. Instead of juggling multiple REST calls, you make one GraphQL request that returns exactly what you need.
PowerShell with GraphQL
You can also use this query directly in PowerShell to programmatically retrieve the information.
Prerequisites
- Ensure the
PSGraphQLmodule is installed and available in your PowerShell session.
Example PowerShell script
# Ensure the PSGraphQL module is available in the session.
# Without this step, PowerShell won’t recognise the commands defined in the module.
# If omitted, your script will fail with “command not found” errors.
Import-Module PSGraphQL
# Set the GraphQL API endpoint and define a placeholder for the authentication token.
$endpoint = "https://api.n-able.com/graphql"
$token = "YOUR_TOKEN_HERE"
# Prepare the HTTP headers using the bearer token for authentication.
$headers = @{
"Authorization" = "Bearer $token"
}
# Define a multi-line GraphQL query using a here-string: $query = @"..."@
# Enter the query to retrieve the device information including customer details, OS type, and chassis types.
$query = @"
query Query {
assetSearch(orderBy: [{
direction: DESC
field: NAME
}]) {
nodes {
customer {
id
name
}
operatingSystemInfo {
type
architecture
}
chassis {
types
}
}
}
}
"@Next Steps
Include the following command to send the GraphQL query to the N-able API and store the returned data in a $response.
$response = Invoke-RestMethod -Uri $endpoint -Method Post -Headers $headers -Body (@{ query = $query } | ConvertTo-Json -Depth 10)What to do with the data….
Once the data is stored in $response, you can:
View the data in the console
$response.data.assetSearch.nodes | Format-TableExport the data to CSV
$response.data.assetSearch.nodes | Export-Csv -Path "C:\Reports\DeviceReport.csv" -NoTypeInformationConvert to JSON and save
$response | ConvertTo-Json -Depth 10 | Out-File "C:\Reports\DeviceData.json"Generate HTML and save
$response.data.assetSearch.nodes | ForEach-Object {"$($_.customer.name) - $($_.operatingSystemInfo.type)"} | Out-File "C:\Reports\DeviceList.html"How to use the $response in a Script
$response = Invoke-RestMethod -Uri $endpoint -Method Post -Headers $headers -Body (@{ query = $query } | ConvertTo-Json -Depth 10)
$response.data.assetSearch.nodes | Export-Csv -Path "C:\Reports\DeviceReport.csv" -NoTypeInformationSend the Query
The first line sends your GraphQL query to the API endpoint using a POST request. It includes:
- The endpoint URL (
$endpoint) - Authentication headers (
$headers) - The query itself (
$query), converted to JSON
The response from the API is stored in the $response variable.
Export the Results
The second line accesses the specific part of the response that contains the data records - $response.data.assetSearch.nodes - and exports them to a CSV file.
How Do You Know What to Enter as the Object Path?
The object path (e.g. $response.data.assetSearch.nodes) is based on the structure of the GraphQL response, which in turn is defined by the structure of your query.
{
"data": {
"assetSearch": {
"nodes": [
{
"customer": {
"name": "Acme Corp"
}
}
]
}
}
}$responseis the full JSON response.$response.dataaccesses the "data" section.$response.data.assetSearchaccesses the "assetSearch" object.$response.data.assetSearch.nodesaccesses the array of results under "nodes".
PowerShell example including $response and Export-CSV
Import-Module PSGraphQL
$endpoint = "https://api.n-able.com/graphql"
$token = "YOUR_TOKEN_HERE"
$headers = @{
"Authorization" = "Bearer $token"
}
$query = @"
query Query {
assetSearch(orderBy: [{
direction: DESC
field: NAME
}]) {
nodes {
customer {
id
name
}
operatingSystemInfo {
type
architecture
}
chassis {
types
}
}
}
}
"@
# Send the GraphQL query using Invoke-RestMethod.
# The response is stored in the $response variable.
$response = Invoke-RestMethod -Uri $endpoint -Method Post -Headers $headers -Body (@{ query = $query } | ConvertTo-Json -Depth 10)
# Export the results to a CSV file for reporting.
$response.data.assetSearch.nodes | Export-Csv -Path "C:\Reports\DeviceReport.csv" -NoTypeInformationUpdated about 3 hours ago