NinjaOne API Scripts
NinjaOne API Examples

Export All End Users from NinjaOne to CSV

This script connects to the NinjaOne API, retrieves a full list of End Users, enriches the data with organization names, and exports the result to a CSV file.

PowerShell
# --------------------------------------------------
# Author: Gavin Stone (NinjaOne)
# Attribution: Luke Whitelock (NinjaOne) for his work on the Authentication Functions
# Date: 19th June 2024
# Description: Gets a list of all End Users in NinjaOne and exports them to a CSV file
# Version: 1.0
# --------------------------------------------------

# PRE REQUISITES --------------------------------------------------
# For API access you will need to generate a Client ID and Client Secret in NinjaOne
# Go to Administration > Apps > API and the Client App IDs tab. 
# Click the 'Add' button in the top right
# For application platform, select API Services (machine-to-machine)
# Name your token something you will recognize (e.g. Recurring Maintenance Mode Script API Token)
# Set Redirect URI to http://localhost
# Set the scopes to monitoring and management
# For allowed grant types, select client credentials only
# Click save in the top right, enter 2FA prompt if required.
# You will be presented with the client secret credential only once. Use the copy icon to copy this into the clipboard and store it somewhere secure. Enter this into the $NinjaOneClientSecret variable below
# Close this window, which will take you back to the Client App IDs tab. Click copy on the Client ID and store this somewhere secure. Enter this into the $NinjaOneClientId variable below

# User editable variables:
$NinjaOneInstance = '' # Please replace with the region instance you login to (app.ninjarmm.com, us2.ninjarmm.com, eu.ninjarmm.com, ca.ninjarmm.com, oc.ninjarmm.com)
$NinjaOneClientId = ''
$NinjaOneClientSecret = ''

# Functions for Authentication
function Get-NinjaOneToken {
    [CmdletBinding()]
    param()

    if ($Script:NinjaOneInstance -and $Script:NinjaOneClientID -and $Script:NinjaOneClientSecret ) {
        if ($Script:NinjaTokenExpiry -and (Get-Date) -lt $Script:NinjaTokenExpiry) {
            return $Script:NinjaToken
        }
        else {

            if ($Script:NinjaOneRefreshToken) {
                $Body = @{
                    'grant_type'    = 'refresh_token'
                    'client_id'     = $Script:NinjaOneClientID
                    'client_secret' = $Script:NinjaOneClientSecret
                    'refresh_token' = $Script:NinjaOneRefreshToken
                }
            }
            else {

                $body = @{
                    grant_type    = 'client_credentials'
                    client_id     = $Script:NinjaOneClientID
                    client_secret = $Script:NinjaOneClientSecret
                    scope         = 'monitoring management'
                }
            }

            $token = Invoke-RestMethod -Uri "https://$($Script:NinjaOneInstance -replace '/ws','')/ws/oauth/token" -Method Post -Body $body -ContentType 'application/x-www-form-urlencoded' -UseBasicParsing
    
            $Script:NinjaTokenExpiry = (Get-Date).AddSeconds($Token.expires_in)
            $Script:NinjaToken = $token
            
            Write-Host 'Fetched New Token'
            return $token
        }
        else {
            Throw 'Please run Connect-NinjaOne first'
        }
    }

}

function Connect-NinjaOne {
    [CmdletBinding()]
    param (
        [Parameter(mandatory = $true)]
        $NinjaOneInstance,
        [Parameter(mandatory = $true)]
        $NinjaOneClientID,
        [Parameter(mandatory = $true)]
        $NinjaOneClientSecret,
        $NinjaOneRefreshToken
    )

    $Script:NinjaOneInstance = $NinjaOneInstance
    $Script:NinjaOneClientID = $NinjaOneClientID
    $Script:NinjaOneClientSecret = $NinjaOneClientSecret
    $Script:NinjaOneRefreshToken = $NinjaOneRefreshToken
    

    try {
        $Null = Get-NinjaOneToken -ea Stop
    }
    catch {
        Throw "Failed to Connect to NinjaOne: $_"
    }

}

function Invoke-NinjaOneRequest {
    param(
        $Method,
        $Body,
        $InputObject,
        $Path,
        $QueryParams,
        [Switch]$Paginate,
        [Switch]$AsArray
    )

    $Token = Get-NinjaOneToken

    if ($InputObject) {
        if ($AsArray) {
            $Body = $InputObject | ConvertTo-Json -depth 100
            if (($InputObject | Measure-Object).count -eq 1 ) {
                $Body = '[' + $Body + ']'
            }
        }
        else {
            $Body = $InputObject | ConvertTo-Json -depth 100
        }
    }

    try {
        if ($Method -in @('GET', 'DELETE')) {
            if ($Paginate) {
            
                $After = 0
                $PageSize = 1000
                $NinjaResult = do {
                    $Result = Invoke-WebRequest -uri "https://$($Script:NinjaOneInstance)/api/v2/$($Path)?pageSize=$PageSize&after=$After$(if ($QueryParams){"&$QueryParams"})" -Method $Method -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json' -UseBasicParsing
                    $Result
                    $ResultCount = ($Result.id | Measure-Object -Maximum)
                    $After = $ResultCount.maximum
    
                } while ($ResultCount.count -eq $PageSize)
            }
            else {
                $NinjaResult = Invoke-WebRequest -uri "https://$($Script:NinjaOneInstance)/api/v2/$($Path)$(if ($QueryParams){"?$QueryParams"})" -Method $Method -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -UseBasicParsing
            }

        }
        elseif ($Method -in @('PATCH', 'PUT', 'POST')) {
            $NinjaResult = Invoke-WebRequest -uri "https://$($Script:NinjaOneInstance)/api/v2/$($Path)$(if ($QueryParams){"?$QueryParams"})" -Method $Method -Headers @{Authorization = "Bearer $($token.access_token)" } -Body $Body -ContentType 'application/json; charset=utf-8' -UseBasicParsing
        }
        else {
            Throw 'Unknown Method'
        }
    }
    catch {
        Throw "Error Occured: $_"
    }

    try {
        return $NinjaResult.content | ConvertFrom-Json -ea stop
    }
    catch {
        return $NinjaResult.content
    }

}

# Connect to NinjaOne API
try {
    Connect-NinjaOne -NinjaOneInstance $NinjaOneInstance -NinjaOneClientID $NinjaOneClientId -NinjaOneClientSecret $NinjaOneClientSecret
}
catch {
    Write-Output "Failed to connect to NinjaOne API: $_"
    exit 1
}

# Get all users in NinjaOne
$Users = Invoke-NinjaOneRequest -Method GET -Path 'users' -Paginate

if ($Users.Count -eq 0) {
    Write-Output 'No Users Found'
    exit
}

# Filters for the users where userType = END_USER
$EndUsers = $Users | Where-Object { $_.userType -eq 'END_USER' }

# Get a list of all organizations in NinjaOne
$Organizations = Invoke-NinjaOneRequest -Method GET -Path 'organizations' -Paginate

# Create a hashtable to map organizationId to organizationName for faster lookup
$OrgHashTable = @{}
$Organizations | ForEach-Object {
    $OrgHashTable[$_.id] = $_.name
}

# Process each End User: make deviceIds a comma-delimited string and add OrganizationName
$EndUsers | ForEach-Object {
    # Make deviceIds a comma-delimited string
    $DeviceIds = $_.deviceIds -join ','
    $_.deviceIds = $DeviceIds

    # Add OrganizationName property
    $OrganizationName = $OrgHashTable[$_.organizationId]
    $_ | Add-Member -MemberType NoteProperty -Name OrganizationName -Value $OrganizationName
}

# Export all End Users to a CSV
$PathToSaveCSV = "C:\Temp\NinjaOneEndUsers_" + (Get-Date -f "yyyyMMdd_HHmm") + ".csv"
$EndUsers | Export-Csv -Path $PathToSaveCSV -NoTypeInformation

Export All End Users from NinjaOne to CSV

Author: Gavin Stone (NinjaOne)
Attribution: Luke Whitelock (NinjaOne) — Authentication Functions
Date: 19th June 2024
Version: 1.0

📝 Description

This script connects to the NinjaOne API, retrieves a full list of End Users, enriches the data with organization names, and exports the result to a CSV file.

What Does It Look Like?

Screenshot of CSV

Steps to Generate API Credentials:

  1. Go to Administration > Apps > API > Client App IDs in NinjaOne.
  2. Click Add to create a new API token.
  3. Set the following:
    • Platform: API Services (machine-to-machine)
    • Name: Something recognizable (e.g. "End User Export Script")
    • Redirect URI: http://localhost
    • Scopes: monitoring, management
    • Grant Types: Client credentials only
  4. Save and copy the Client Secret when presented.
  5. Copy the Client ID.
  6. Update the following variables in the script:
$NinjaOneInstance = 'app.ninjarmm.com'  # Or eu.ninjarmm.com, ca.ninjarmm.com, etc.
$NinjaOneClientId = '<your-client-id>'
$NinjaOneClientSecret = '<your-client-secret>'