Back

Quick Guide to Realtime Data in Microsoft Intune without Webhooks

Aug 8, 20248 minute read

Hey there, fellow JavaScript devs! Ready to dive into the world of real-time data with Microsoft Intune? Let's skip the webhooks and go straight for the good stuff - polling. Trust me, it's not as daunting as it sounds, and I'll show you how to make it work like a charm.

Setting the Stage

First things first, let's get our ducks in a row. You'll need:

  1. An Azure AD app registration (I know, I know, but it's worth it)
  2. The right permissions (we're talking Graph API here)
  3. Node.js on your machine
  4. A couple of packages: axios for HTTP requests and dotenv for environment variables

Got all that? Great! Let's roll up our sleeves and get coding.

Authentication: Your Golden Ticket

Before we start polling, we need to get our hands on an access token. It's like a VIP pass to the Intune API party. Here's how you snag one:

require('dotenv').config(); const axios = require('axios'); async function getAccessToken() { const tokenEndpoint = `https://login.microsoftonline.com/${process.env.TENANT_ID}/oauth2/v2.0/token`; const params = new URLSearchParams({ client_id: process.env.CLIENT_ID, client_secret: process.env.CLIENT_SECRET, scope: 'https://graph.microsoft.com/.default', grant_type: 'client_credentials' }); try { const response = await axios.post(tokenEndpoint, params); return response.data.access_token; } catch (error) { console.error('Error getting access token:', error); throw error; } }

Polling: The Heart of the Matter

Now, let's talk polling. It's like repeatedly asking, "Are we there yet?" but in a way that doesn't drive everyone crazy. Here's a basic polling function to get you started:

async function pollIntuneData(interval = 60000) { while (true) { try { const token = await getAccessToken(); const data = await fetchIntuneData(token); processData(data); } catch (error) { console.error('Polling error:', error); } await new Promise(resolve => setTimeout(resolve, interval)); } }

Fetching the Goods

Time to actually grab that Intune data. Let's say we're interested in device status changes:

async function fetchIntuneData(token) { const endpoint = 'https://graph.microsoft.com/v1.0/deviceManagement/managedDevices'; try { const response = await axios.get(endpoint, { headers: { Authorization: `Bearer ${token}` } }); return response.data.value; } catch (error) { console.error('Error fetching Intune data:', error); throw error; } }

Optimizing: Because We're Not Savages

Let's make our polling a bit smarter with some exponential backoff:

async function pollWithBackoff(initialInterval = 60000, maxInterval = 3600000) { let interval = initialInterval; while (true) { try { const token = await getAccessToken(); const data = await fetchIntuneData(token); processData(data); interval = initialInterval; // Reset on success } catch (error) { console.error('Polling error:', error); interval = Math.min(interval * 2, maxInterval); // Exponential backoff } await new Promise(resolve => setTimeout(resolve, interval)); } }

Handling the Data

Now that we've got our data, let's do something useful with it:

function processData(devices) { devices.forEach(device => { updateUI(device); if (device.complianceState !== 'compliant') { notifyAdmin(device); } }); } function updateUI(device) { // Update your UI here console.log(`Device ${device.deviceName} status: ${device.complianceState}`); } function notifyAdmin(device) { // Send notification to admin console.log(`Alert: Device ${device.deviceName} is non-compliant!`); }

Error Handling: Because Stuff Happens

Let's add some resilience to our polling function:

async function robustPolling(interval = 60000) { while (true) { try { const token = await getAccessToken(); const data = await fetchIntuneData(token); processData(data); } catch (error) { if (error.response && error.response.status === 429) { console.log('Rate limited. Waiting before next request.'); await new Promise(resolve => setTimeout(resolve, 60000)); // Wait a minute } else { console.error('Polling error:', error); } } await new Promise(resolve => setTimeout(resolve, interval)); } }

Performance Boost: Caching for the Win

Let's implement a simple cache to reduce unnecessary API calls:

const deviceCache = new Map(); async function fetchAndCacheIntuneData(token) { const endpoint = 'https://graph.microsoft.com/v1.0/deviceManagement/managedDevices'; try { const response = await axios.get(endpoint, { headers: { Authorization: `Bearer ${token}` } }); response.data.value.forEach(device => { deviceCache.set(device.id, device); }); return response.data.value; } catch (error) { console.error('Error fetching Intune data:', error); throw error; } } function getDeviceFromCache(deviceId) { return deviceCache.get(deviceId); }

Wrapping Up

And there you have it! You're now equipped to fetch real-time(ish) data from Microsoft Intune using polling. It's not as instant as webhooks, but it's simpler to set up and can be just as effective with the right optimizations.

Remember, polling is all about finding the right balance between staying up-to-date and not overwhelming the API. Play around with the intervals, implement smart error handling, and cache when you can.

Want to dive deeper? Check out the Microsoft Graph API documentation for more Intune endpoints and data you can work with.

Now go forth and poll responsibly!