Receber por email
← Voltar para o catálogo

Datto RMM Sites

Use this skill when working with Datto RMM sites - listing, managing, and configuring client locations. Covers site structure, site settings, proxy configuration, site-level variables, device assignment, and site-scoped operations.

31estrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: Apache-2.0

Como adicionar

/plugin marketplace add wyre-technology/msp-claude-plugins

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/datto-rmm-sites/svg)](https://www.skillteca.com.br/skills/datto-rmm-sites)

Skills relacionadas

Ver todas de Documentos →

Alerta por categoria

Receba novas skills de Documentos toda segunda

1 email curto, só com as skills novas de Documentos. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Datto RMM Site Management

Overview

Sites in Datto RMM represent client organizations or locations. Each site contains devices, has its own settings, and can have site-level variables. Sites provide organizational hierarchy and enable scoped operations - alerts, jobs, and reports can all be filtered by site.

Key Concepts

Site Hierarchy

Account
└── Sites (many)
    └── Devices (many per site)
        └── Alerts, Jobs, Audit Data

Site Types

Sites can represent:

  • Client companies - External customers
  • Internal locations - Your own offices
  • Projects - Temporary groupings
  • Departments - Internal divisions

Site Identifiers

| Identifier | Type | Description | |------------|------|-------------| | siteUid | string | Globally unique identifier | | siteId | integer | Legacy numeric ID | | name | string | Display name |

Field Reference

Site Object

interface Site {
  // Identifiers
  uid: string;                    // Unique site ID
  siteId: number;                 // Legacy numeric ID
  name: string;                   // Site display name
  description?: string;           // Site description

  // Configuration
  onDemand: boolean;              // On-demand site (no scheduled tasks)
  splapiEnabled: boolean;         // Service Provider Level API enabled
  proxySettings?: ProxySettings;  // HTTP proxy configuration

  // Counts
  devicesCount: number;           // Number of devices
  openAlertsCount: number;        // Active alerts

  // Timestamps (Unix milliseconds)
  createdAt: number;              // When site was created
  modifiedAt: number;             // Last modification

  // Settings
  settings: SiteSettings;
}

interface ProxySettings {
  enabled: boolean;
  host: string;
  port: number;
  username?: string;
  bypassList?: string[];          // Hosts to bypass proxy
}

interface SiteSettings {
  autoPatchApproval: boolean;
  patchWindow: PatchWindow;
  notificationEmail?: string;
  timezone: string;
}

interface PatchWindow {
  dayOfWeek: number;              // 0=Sunday, 6=Saturday
  startHour: number;              // 0-23
  durationHours: number;
}

API Patterns

List All Sites

GET /api/v2/sites?max=250
Authorization: Bearer {token}

Response:

{
  "sites": [
    {
      "uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "Acme Corporation",
      "description": "Main office",
      "devicesCount": 45,
      "openAlertsCount": 3,
      "onDemand": false
    }
  ],
  "pageDetails": {
    "count": 1,
    "nextPageUrl": null
  }
}

Get Single Site

GET /api/v2/site/{siteUid}
Authorization: Bearer {token}

Response:

{
  "uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "siteId": 12345,
  "name": "Acme Corporation",
  "description": "Main office - Downtown",
  "devicesCount": 45,
  "openAlertsCount": 3,
  "onDemand": false,
  "splapiEnabled": true,
  "createdAt": 1680000000000,
  "modifiedAt": 1707991200000,
  "proxySettings": {
    "enabled": false
  },
  "settings": {
    "autoPatchApproval": false,
    "timezone": "America/New_York"
  }
}

Get Devices for Site

GET /api/v2/site/{siteUid}/devices?max=250
Authorization: Bearer {token}

Get Alerts for Site

GET /api/v2/site/{siteUid}/alerts/open
Authorization: Bearer {token}

Get Resolved Alerts for Site

GET /api/v2/site/{siteUid}/alerts/resolved?max=250
Authorization: Bearer {token}

Create Site

POST /api/v2/sites
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "New Client Site",
  "description": "Client headquarters",
  "onDemand": false
}

Update Site

POST /api/v2/site/{siteUid}
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "Updated Site Name",
  "description": "Updated description"
}

Delete Site

DELETE /api/v2/site/{siteUid}
Authorization: Bearer {token}

Warning: Deleting a site does not delete devices - they become unassigned.

Workflows

Site Lookup by Name

async function findSiteByName(client, name) {
  const response = await client.request('/api/v2/sites?max=250');
  const sites = response.sites || [];

  // Exact match first
  const exact = sites.find(s =>
    s.name.toLowerCase() === name.toLowerCase()
  );
  if (exact) return { found: true, site: exact };

  // Partial match
  const matches = sites.filter(s =>
    s.name.toLowerCase().includes(name.toLowerCase())
  );

  if (matches.length === 0) {
    return { found: false, suggestions: [] };
  }

  if (matches.length === 1) {
    return { found: true, site: matches[0] };
  }

  return {
    found: false,
    ambiguous: true,
    suggestions: matches.map(s => ({
      name: s.name,
      uid: s.uid,
      deviceCount: s.devicesCount
    }))
  };
}

Site Health Overview

async function getSiteHealth(client, siteUid) {
  const [site, devices, alerts] = await Promise.all([
    client.request(`/api/v2/site/${siteUid}`),
    client.request(`/api/v2/site/${siteUid}/devices?max=250`),
    client.request(`/api/v2/site/${siteUid}/alerts/open`)
  ]);

  const deviceList = devices.devices || [];
  const alertList = alerts.alerts || [];

  // Device status breakdown
  const deviceStatus = {
    online: deviceList.filter(d => d.status === 'online').length,
    offline: deviceList.filter(d => d.status === 'offline').length,
    total: deviceList.length
  };

  // Alert priority breakdown
  const alertsByPriority = {
    Critical: alertList.filter(a => a.priority === 'Critical').length,
    High: alertList.filter(a => a.priority === 'High').length,
    Moderate: alertList.filter(a => a.priority === 'Moderate').length,
    Low: alertList.filter(a => a.priority === 'Low').length
  };

  // Calculate health score
  const healthScore = calculateSiteHealthScore(deviceStatus, alertsByPriority);

  return {
    site: {
      name: site.name,
      uid: site.uid
    },
    devices: deviceStatus,
    alerts: {
      total: alertList.length,
      byPriority: alertsByPriority
    },
    healthScore,
    status: healthScore >= 80 ? 'healthy' : healthScore >= 50 ? 'warning' : 'critical'
  };
}

function calculateSiteHealthScore(devices, alerts) {
  let score = 100;

  // Deduct for offline devices
  const offlinePercent = (devices.offline / devices.total) * 100;
  score -= offlinePercent * 0.5;

  // Deduct for alerts
  score -= alerts.Critical * 15;
  score -= alerts.High * 5;
  score -= alerts.Moderate * 2;
  score -= alerts.Low * 0.5;

  return Math.max(0, Math.round(score));
}

Multi-Site Summary

async function getAllSitesSummary(client) {
  const response = await client.request('/api/v2/sites?max=250');
  const sites = response.sites || [];

  return sites.map(site => ({
    name: site.name,
    uid: site.uid,
    devices: site.devicesCount,
    openAlerts: site.openAlertsCount,
    status: site.openAlertsCount === 0 ? 'healthy' :
            site.openAlertsCount <= 5 ? 'warning' : 'critical'
  })).sort((a, b) => b.openAlerts - a.openAlerts);
}

Site Onboarding Checklist

async function validateSiteSetup(client, siteUid) {
  const site = await client.request(`/api/v2/site/${siteUid}`);
  const devices = await client.request(`/api/v2/site/${siteUid}/devices?max=250`);
  const variables = await client.request(`/api/v2/site/${siteUid}/variables`);

  const checks = [];

  // Check site has description
  checks.push({
    item: 'Site description',
    status: site.description ? 'pass' : 'fail',
    message: site.description || 'No description set'
  });

  // Check site has devices
  checks.push({
    item: 'Devices enrolled',
    status: devices.devices?.length > 0 ? 'pass' : 'fail',
    message: `${devices.devices?.length || 0} devices`
  });

  // Check critical variables are set
  const requiredVars = ['BACKUP_PATH', 'ADMIN_EMAIL'];
  requiredVars.forEac
Compartilhar X LinkedIn