My workplace has moved away from Kaseya, I wrote about using their API here. Since moving over to Solarwinds MSP N-Central I have had the opportunity to work with their API as well
, with a little help from the GitHub repo here.
Edit: I have created a PowerShell module to interface with the N Central API. Check it out on GitHub here. Currently it enables you to return Service Org, Customer and Device details. It’s a work in progress, and I would really appreciate your feedback.
First off, let’s get the documentation out of the way. You can find it at http://mothership.n-able.com/dms/javadocei2/index.html. Here we go.
Getting ready
Before we go too far, I’ll need to gather a few things
- URL
- Custom namespace – This is necessary to be able to run the script multiple times without closing PowerShell. We’ll do this by taking the last 25 characters from a GUID object
- Username and Password – For simplicity here, I will store these in the script, but you may prefer to enter these when running the script using Read-Host. It is also important to note that at the time of writing, the API does not work if you have muti-factor authentication enabled for the user account. In my environment I have created a separate user with a strong password and no MFA.
$url = 'https://<your N-Central Server>/dms/services/ServerEI?wsdl'
$ncNameSpace = "NC" + ([guid]::NewGuid()).ToString().Substring(25)
$username = '[email protected]'
$secpass = (Convertto-securestring -string 'supersecretpassword' -asplaintext -force) # Used for Authentication. Alternatively use Read-Host -assecurestring
$plainpass = 'supersecretpassword' # Used for requests after authentication
Creating a Web Service Proxy
To access the API methods, we will need to create a Web Service Proxy which acts as an intermediary between our requests and the API. This is done with the New-WebServiceProxy cmdlet. We will pass into this the URL and a PSCredential Object for authentication, as well as the custom namespace.
$creds = New-object System.Management.Automation.PSCredential ("$username",$password)
$nws = New-WebServiceProxy -Uri $soapURL -Namespace ($ncNameSpace) -Credential $creds
If this is successful, you should be able to pipe $nws to Get-Member and see all of the methods available to you.
Building the request
One of the things you will notice if you look at the method documentation is the requirement for a T_KeyPair object to be sent as part of the request. This type of object is available to us through the namespace we created earlier. If we look closer at the object, we can see that it only has two properties, Key and Value.
So, now we know that we are dealing with Key-Value pairs we can start to create our T_KeyPair object. I’ll create one for the CustomerID 100.
$keypairs = @()
$keypair = New-object "$ncNameSpace.T_KeyPair"
$keypair.Key = "CustomerID"
$keypair.Value = "100"
$keypairs += $keypair
Making the request
To make the request, all we need to do is call the method we want and pass in the username, password and keypair(s).
$result = $nws.DeviceList("$username",$plainpass,$keypairs)
Display the results
Finally, we just need to make the output readable. There are a couple of ways to skin this cat, I will add each of the device properties to a hashtable, make a new object and then choose what we want to display
foreach($device in $result){
$props = @{}
foreach($item in $device.info){
$props.add($item.key.split('.')[1],$item.Value)
}
$obj = New-Object -TypeName psobject -Property $props
$obj | where deviceclass -match 'server' | Select-Object longname,supportedos| ft
}
Hi,
Thanks for the good explanation.
I’m trying to query all the active issues of a customer(ActiveIssuesList() ), but cant get results from it.
Can you put me in the right direction with an example code maybe ?
LikeLike
# ActiveIssuesList
# Uses CustomerID. Returned customerid=siteid.
$rc = $nws.activeIssuesList($username, $password, $KeyPairs)
$PairClass=”issue”
$OutObjects = @()
if ($rc -ne $null){
foreach ($InObject in $rc) {
# $ThisObject = New-Object PSCustomObject # Pre PowerShell 4
$ThisObject = New-Object PSObject
foreach ($item in $InObject.$PairClass) {
$Header = $item.key.split(“.”)[1]
$ThisObject | Add-Member -MemberType NoteProperty -Name $Header -Value $item.Value -Force
}
$Script:OutObjects += $ThisObject
}
}
#
# Select the output file
#
$CSVFile = “C:\Temp\ObjectList.csv”
## The header for Format-Table and Export-CSV is based on the first item in the array.
## If you output the item which has most columns (this works since you only add columns) first it will work.
$OutObjects = $OutObjects | Sort-Object {($_ | Get-Member -MemberType NoteProperty).Count} -Descending
$OutObjects |Export-Csv -Path $CSVFile -NoTypeInformation -Force -Encoding utf8
LikeLike