Help us improve
Share bugs, ideas, or general feedback.
From kaseya-datto-rmm
Retrieves and analyzes Datto RMM audit data including hardware/software inventories, network interfaces, system info, ESXi hosts, printers, and freshness tracking.
npx claudepluginhub wyre-technology/msp-claude-plugins --plugin datto-rmmHow this skill is triggered — by the user, by Claude, or both
Slash command
/kaseya-datto-rmm:auditThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Audit data in Datto RMM provides detailed hardware and software inventory for managed devices. The agent periodically collects this information and reports it to the platform. This skill covers accessing audit data, understanding its structure, and common audit workflows.
Manages Datto RMM devices: lists, searches, monitors endpoints (workstations, servers, ESXi, networks). Covers UIDs, hostnames, MACs, statuses, UDFs, warranty info, operations.
Audits software inventory across devices using ZDX data. Lists installed software, filters by location/department/user, and drills into version details for compliance and vulnerability assessments.
Manage NinjaOne RMM devices: list, search, control services, view hardware inventory, schedule maintenance, monitor health and alerts on Windows, Mac, Linux endpoints.
Share bugs, ideas, or general feedback.
Audit data in Datto RMM provides detailed hardware and software inventory for managed devices. The agent periodically collects this information and reports it to the platform. This skill covers accessing audit data, understanding its structure, and common audit workflows.
| Category | Description | Examples |
|---|---|---|
| Hardware | Physical components | CPU, RAM, disks, motherboard |
| Software | Installed applications | Programs, versions, publishers |
| Network | Network configuration | Interfaces, IPs, MACs |
| Operating System | OS details | Version, build, architecture |
| ESXi | VMware hypervisor info | VMs, datastores, hosts |
| Printer | Network printers | Name, model, status |
Audit data is collected periodically:
interface HardwareAudit {
// Processor
processor: {
name: string; // "Intel Core i7-10700"
cores: number; // Physical cores
logicalProcessors: number; // Logical processors
speed: number; // Clock speed (MHz)
architecture: string; // "x64", "ARM64"
};
// Memory
memory: {
totalRam: number; // Total RAM (bytes)
availableRam: number; // Available RAM (bytes)
slots: MemorySlot[];
};
// Storage
disks: DiskInfo[];
// Motherboard
motherboard: {
manufacturer: string; // "Dell Inc."
product: string; // "0VNP2H"
serialNumber: string;
};
// BIOS
bios: {
manufacturer: string;
version: string;
releaseDate: string;
};
}
interface MemorySlot {
slot: string; // "DIMM1"
size: number; // Size (bytes)
speed: number; // Speed (MHz)
type: string; // "DDR4"
manufacturer: string;
}
interface DiskInfo {
name: string; // "Disk 0"
model: string; // "Samsung SSD 970 EVO"
serialNumber: string;
size: number; // Total size (bytes)
interface: string; // "NVMe", "SATA"
mediaType: string; // "SSD", "HDD"
partitions: PartitionInfo[];
}
interface PartitionInfo {
name: string; // "C:"
size: number; // Partition size
freeSpace: number; // Free space
fileSystem: string; // "NTFS", "exFAT"
}
interface SoftwareAudit {
applications: Application[];
totalCount: number;
lastScan: number; // Unix milliseconds
}
interface Application {
name: string; // "Microsoft Office Professional Plus 2019"
version: string; // "16.0.14430.20234"
publisher: string; // "Microsoft Corporation"
installDate: string; // "2024-01-15"
installLocation?: string; // "C:\\Program Files\\Microsoft Office"
size?: number; // Installed size (bytes)
uninstallString?: string; // Uninstall command
isUpdate: boolean; // Is Windows Update
architecture: string; // "x64", "x86"
}
interface NetworkAudit {
interfaces: NetworkInterface[];
dnsServers: string[];
defaultGateway: string;
domainName?: string;
workgroup?: string;
}
interface NetworkInterface {
name: string; // "Ethernet"
description: string; // "Intel I219-LM Gigabit"
macAddress: string; // "00:1A:2B:3C:4D:5E"
ipAddresses: IPAddress[];
speed: number; // Link speed (Mbps)
status: string; // "Up", "Down"
type: string; // "Ethernet", "Wi-Fi", "Virtual"
}
interface IPAddress {
address: string; // "192.168.1.100"
subnetMask: string; // "255.255.255.0"
type: string; // "IPv4", "IPv6"
}
interface ESXiAudit {
version: string; // "7.0.3"
build: string; // "19193900"
hostname: string;
// Hardware
cpuModel: string;
cpuCores: number;
totalMemory: number; // Bytes
// Virtual Machines
vms: VirtualMachine[];
// Datastores
datastores: Datastore[];
// Network
virtualSwitches: VSwitch[];
}
interface VirtualMachine {
name: string;
powerState: string; // "poweredOn", "poweredOff", "suspended"
guestOS: string;
cpuCount: number;
memoryMB: number;
diskSizeGB: number;
vmwareToolsStatus: string;
}
interface Datastore {
name: string;
type: string; // "VMFS", "NFS", "vSAN"
capacity: number; // Bytes
freeSpace: number;
vmCount: number;
}
GET /api/v2/device/{deviceUid}/audit
Authorization: Bearer {token}
Response:
{
"deviceUid": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a",
"lastAuditDate": 1707991200000,
"hardware": {
"processor": {
"name": "Intel Core i7-10700",
"cores": 8,
"logicalProcessors": 16,
"speed": 2900
},
"memory": {
"totalRam": 34359738368,
"availableRam": 17179869184,
"slots": [...]
},
"disks": [...]
},
"operatingSystem": {
"name": "Windows 11 Pro",
"version": "10.0.22631",
"architecture": "64-bit",
"installDate": "2023-10-15",
"lastBootTime": 1707800000000
},
"network": {
"interfaces": [...],
"dnsServers": ["192.168.1.1", "8.8.8.8"],
"defaultGateway": "192.168.1.1"
}
}
GET /api/v2/device/{deviceUid}/audit/software
Authorization: Bearer {token}
Response:
{
"deviceUid": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a",
"lastScan": 1707991200000,
"totalCount": 156,
"applications": [
{
"name": "Google Chrome",
"version": "121.0.6167.140",
"publisher": "Google LLC",
"installDate": "2024-01-20",
"architecture": "x64"
},
{
"name": "Microsoft 365 Apps",
"version": "16.0.17231.20182",
"publisher": "Microsoft Corporation",
"installDate": "2023-12-10",
"architecture": "x64"
}
]
}
GET /api/v2/device/{deviceUid}/audit/esxi
Authorization: Bearer {token}
GET /api/v2/device/{deviceUid}/audit/printers
Authorization: Bearer {token}
async function checkSoftwareCompliance(client, deviceUid, requirements) {
const audit = await client.request(`/api/v2/device/${deviceUid}/audit/software`);
const apps = audit.applications || [];
const results = requirements.map(req => {
const found = apps.find(app =>
app.name.toLowerCase().includes(req.name.toLowerCase())
);
if (!found) {
return {
requirement: req.name,
status: 'missing',
compliant: false
};
}
// Check version if specified
if (req.minVersion) {
const versionOk = compareVersions(found.version, req.minVersion) >= 0;
return {
requirement: req.name,
status: versionOk ? 'compliant' : 'outdated',
installedVersion: found.version,
requiredVersion: req.minVersion,
compliant: versionOk
};
}
return {
requirement: req.name,
status: 'installed',
installedVersion: found.version,
compliant: true
};
});
return {
deviceUid,
totalRequirements: requirements.length,
compliant: results.filter(r => r.compliant).length,
nonCompliant: results.filter(r => !r.compliant).length,
results
};
}
function compareVersions(a, b) {
const partsA = a.split('.').map(Number);
const partsB = b.split('.').map(Number);
for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
const numA = partsA[i] || 0;
const numB = partsB[i] || 0;
if (numA > numB) return 1;
if (numA < numB) return -1;
}
return 0;
}
async function generateHardwareReport(client, deviceUids) {
const reports = [];
for (const deviceUid of deviceUids) {
try {
const audit = await client.request(`/api/v2/device/${deviceUid}/audit`);
reports.push({
deviceUid,
hostname: audit.hostname,
cpu: audit.hardware?.processor?.name,
cores: audit.hardware?.processor?.cores,
ramGB: Math.round((audit.hardware?.memory?.totalRam || 0) / (1024 ** 3)),
diskType: audit.hardware?.disks?.[0]?.mediaType,
diskSizeGB: Math.round((audit.hardware?.disks?.[0]?.size || 0) / (1024 ** 3)),
os: audit.operatingSystem?.name,
osVersion: audit.operatingSystem?.version
});
} catch (error) {
reports.push({
deviceUid,
error: error.message
});
}
await sleep(100); // Rate limit
}
return reports;
}
async function findDevicesWithSoftware(client, softwareName) {
// Get all devices
const devicesResponse = await client.request('/api/v2/devices?max=250');
const devices = devicesResponse.devices || [];
const matches = [];
for (const device of devices) {
try {
const audit = await client.request(`/api/v2/device/${device.uid}/audit/software`);
const apps = audit.applications || [];
const found = apps.find(app =>
app.name.toLowerCase().includes(softwareName.toLowerCase())
);
if (found) {
matches.push({
hostname: device.hostname,
deviceUid: device.uid,
site: device.siteName,
software: found.name,
version: found.version
});
}
} catch (error) {
// Skip devices with audit errors
}
await sleep(100);
}
return matches;
}
async function analyzeDiskSpace(client, deviceUid) {
const audit = await client.request(`/api/v2/device/${deviceUid}/audit`);
const disks = audit.hardware?.disks || [];
return disks.flatMap(disk =>
(disk.partitions || []).map(partition => {
const usedSpace = partition.size - partition.freeSpace;
const usagePercent = Math.round((usedSpace / partition.size) * 100);
return {
disk: disk.name,
partition: partition.name,
fileSystem: partition.fileSystem,
totalGB: Math.round(partition.size / (1024 ** 3)),
usedGB: Math.round(usedSpace / (1024 ** 3)),
freeGB: Math.round(partition.freeSpace / (1024 ** 3)),
usagePercent,
status: usagePercent >= 90 ? 'critical' :
usagePercent >= 80 ? 'warning' : 'healthy'
};
})
);
}
async function generateESXiCapacityReport(client, deviceUid) {
const audit = await client.request(`/api/v2/device/${deviceUid}/audit/esxi`);
const vmSummary = {
total: audit.vms?.length || 0,
poweredOn: audit.vms?.filter(vm => vm.powerState === 'poweredOn').length || 0,
poweredOff: audit.vms?.filter(vm => vm.powerState === 'poweredOff').length || 0
};
const datastoreSummary = (audit.datastores || []).map(ds => ({
name: ds.name,
type: ds.type,
capacityTB: (ds.capacity / (1024 ** 4)).toFixed(2),
freeTB: (ds.freeSpace / (1024 ** 4)).toFixed(2),
usagePercent: Math.round(((ds.capacity - ds.freeSpace) / ds.capacity) * 100),
vmCount: ds.vmCount
}));
return {
host: audit.hostname,
version: audit.version,
cpuCores: audit.cpuCores,
memoryGB: Math.round(audit.totalMemory / (1024 ** 3)),
vms: vmSummary,
datastores: datastoreSummary
};
}
| Error | Status | Cause | Resolution |
|---|---|---|---|
| Device not found | 404 | Invalid deviceUid | Verify device exists |
| Audit not available | 404 | No audit data yet | Wait for agent collection |
| Device offline | - | Agent not reporting | Check device connectivity |
function validateAuditFreshness(audit, maxAgeHours = 48) {
const lastAudit = audit.lastAuditDate;
if (!lastAudit) {
return { fresh: false, reason: 'No audit date' };
}
const ageMs = Date.now() - lastAudit;
const ageHours = ageMs / (1000 * 60 * 60);
if (ageHours > maxAgeHours) {
return {
fresh: false,
reason: `Audit data is ${Math.round(ageHours)} hours old`,
lastAudit: new Date(lastAudit).toISOString()
};
}
return {
fresh: true,
ageHours: Math.round(ageHours),
lastAudit: new Date(lastAudit).toISOString()
};
}