Skip to main content

Microsoft Power BI Integration for Digital Signage

Displaying Power BI dashboards on digital signage brings real-time business intelligence to your teams, visitors, and operations floor. This guide covers all integration methods, from simple web embedding to enterprise-grade automated solutions.

Why Power BI on Digital Signage?

Use Cases

EnvironmentApplicationBenefit
Corporate LobbyCompany KPIs, stock price, sustainability metricsTransparency, culture
Sales FloorReal-time sales, leaderboards, targetsMotivation, awareness
Operations/NOCSystem status, alerts, performanceRapid response
ManufacturingProduction metrics, quality data, OEEProcess visibility
WarehouseInventory levels, shipping statusOperational efficiency
Call CenterQueue stats, SLA performance, agent metricsPerformance management
Executive SuiteFinancial dashboards, market dataDecision support

Benefits of Signage vs. Desktop

FactorDesktop ViewingDigital Signage
VisibilityIndividualTeam-wide
AttentionPull (user opens)Push (always visible)
Context switchingRequiredNone
Ambient awarenessLowHigh
Data culturePersonalOrganizational

Integration Methods Overview

┌─────────────────────────────────────────────────────────────────────────┐
│ POWER BI SIGNAGE INTEGRATION METHODS │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ METHOD 1: PUBLISH TO WEB (Simplest) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Power BI │───▶│ Public URL │───▶│ Signage │ │
│ │ Report │ │ (iframe) │ │ Player │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ✓ No authentication needed │
│ ✗ Data publicly accessible │
│ │
│ METHOD 2: EMBED WITH SERVICE PRINCIPAL (Secure) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Power BI │───▶│ Azure AD │───▶│ Signage │ │
│ │ Report │ │ App Token │ │ Player │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ✓ Secure, authenticated │
│ ✓ Row-level security │
│ ✗ More complex setup │
│ │
│ METHOD 3: FULL-SCREEN KIOSK (Native) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Windows │───▶│ Power BI │───▶│ Display │ │
│ │ Player │ │ Desktop │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ✓ Native app experience │
│ ✓ Offline capability │
│ ✗ Windows-only, license needed │
│ │
│ METHOD 4: SCREENSHOT/IMAGE EXPORT (Scheduled) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Power BI │───▶│ Image File │───▶│ Signage │ │
│ │ Report │ │ (PNG/JPG) │ │ CMS │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ✓ Works with any signage player │
│ ✓ Minimal bandwidth │
│ ✗ Not real-time │
│ │
└─────────────────────────────────────────────────────────────────────────┘

Method 1: Publish to Web (Public Embed)

The simplest method - creates a public URL anyone can access.

When to Use

  • ✅ Non-sensitive data only
  • ✅ Quick proof of concept
  • ✅ Public-facing dashboards
  • ❌ Not for confidential data
  • ❌ Not for internal financials

Setup Steps

  1. Open your Power BI report in Power BI Service

  2. Click File → Embed report → Publish to web

  3. Review the warning about public access

  4. Copy the embed code (iframe)

<iframe
title="Sales Dashboard"
width="1920"
height="1080"
src="https://app.powerbi.com/view?r=eyJrIjoiYWJj..."
frameborder="0"
allowFullScreen="true">
</iframe>
  1. Add to your signage CMS as a web component/URL

Best Practices

PracticeImplementation
Use full-screen URLAdd ?chromeless=true to hide toolbar
Set auto-refreshConfigure report refresh in Power BI
Optimize for display sizeDesign report at exact signage resolution
Test refresh behaviorEnsure page refresh doesn't show loading

Customizing the URL

ParameterPurposeExample
chromeless=trueHide navigation?chromeless=true
navContentPaneEnabled=falseHide page tabs&navContentPaneEnabled=false
filterPaneEnabled=falseHide filters&filterPaneEnabled=false

Full URL example:

https://app.powerbi.com/view?r=eyJrIjoiYWJj...&chromeless=true&navContentPaneEnabled=false

Method 2: Secure Embed with Service Principal

For sensitive data requiring authentication without user interaction.

Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│ SECURE EMBEDDING ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. SETUP PHASE (One-time) │
│ ┌──────────────┐ │
│ │ Azure AD │──── Register App ────▶ App ID + Secret │
│ │ Portal │ │
│ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Power BI │──── Add Service Principal to Workspace │
│ │ Admin Portal │ │
│ └──────────────┘ │
│ │
│ 2. RUNTIME FLOW │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Your Server │───▶│ Azure AD │───▶│ Access Token │ │
│ │ │ │ │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌──────────────┐ │
│ └──────────────────────────────▶│ Power BI API │ │
│ │ Embed Token │ │
│ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Signage │ │
│ │ Player │ │
│ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘

Step 1: Register Azure AD Application

  1. Go to Azure PortalAzure Active DirectoryApp registrations
  2. Click New registration
  3. Name: "Digital Signage Power BI"
  4. Supported account types: Single tenant
  5. Redirect URI: Leave blank for now
  6. Click Register

Record these values:

  • Application (client) ID
  • Directory (tenant) ID

Step 2: Create Client Secret

  1. In your app registration, go to Certificates & secrets
  2. Click New client secret
  3. Description: "Signage secret"
  4. Expiration: Choose appropriate (remember to rotate!)
  5. Copy the secret value immediately (shown only once)

Step 3: Grant API Permissions

  1. Go to API permissionsAdd a permission

  2. Select Power BI Service

  3. Choose Delegated permissions:

    • Dataset.Read.All
    • Report.Read.All
    • Dashboard.Read.All
    • Workspace.Read.All
  4. Click Grant admin consent

Step 4: Enable Service Principal in Power BI

  1. Go to Power BI Admin Portal (admin.powerbi.com)
  2. Tenant settingsDeveloper settings
  3. Enable Service principals can use Power BI APIs
  4. Specify security group or entire organization

Step 5: Add Service Principal to Workspace

  1. Open your Power BI workspace
  2. Click AccessAdd
  3. Search for your Azure AD app name
  4. Grant Member or Contributor role

Step 6: Generate Embed Token (Server-Side)

Node.js Example:

const axios = require('axios');
const qs = require('querystring');

// Configuration
const config = {
tenantId: 'your-tenant-id',
clientId: 'your-app-id',
clientSecret: 'your-client-secret',
workspaceId: 'your-workspace-id',
reportId: 'your-report-id'
};

// Get Azure AD token
async function getAzureToken() {
const url = `https://login.microsoftonline.com/${config.tenantId}/oauth2/v2.0/token`;

const response = await axios.post(url, qs.stringify({
grant_type: 'client_credentials',
client_id: config.clientId,
client_secret: config.clientSecret,
scope: 'https://analysis.windows.net/powerbi/api/.default'
}));

return response.data.access_token;
}

// Get embed token
async function getEmbedToken(azureToken) {
const url = `https://api.powerbi.com/v1.0/myorg/groups/${config.workspaceId}/reports/${config.reportId}/GenerateToken`;

const response = await axios.post(url,
{ accessLevel: 'View' },
{ headers: { Authorization: `Bearer ${azureToken}` }}
);

return response.data.token;
}

// Get embed URL
async function getEmbedUrl(azureToken) {
const url = `https://api.powerbi.com/v1.0/myorg/groups/${config.workspaceId}/reports/${config.reportId}`;

const response = await axios.get(url, {
headers: { Authorization: `Bearer ${azureToken}` }
});

return response.data.embedUrl;
}

// Main function
async function getEmbedConfig() {
const azureToken = await getAzureToken();
const embedToken = await getEmbedToken(azureToken);
const embedUrl = await getEmbedUrl(azureToken);

return {
embedToken,
embedUrl,
reportId: config.reportId
};
}

Step 7: Embed in Signage Player

HTML/JavaScript for signage player:

<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/powerbi-client@2.22.0/dist/powerbi.min.js"></script>
<style>
html, body, #reportContainer {
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="reportContainer"></div>

<script>
// Get embed config from your server
fetch('/api/powerbi-embed-config')
.then(response => response.json())
.then(config => {
const embedConfig = {
type: 'report',
tokenType: powerbi.models.TokenType.Embed,
accessToken: config.embedToken,
embedUrl: config.embedUrl,
id: config.reportId,
settings: {
panes: {
filters: { visible: false },
pageNavigation: { visible: false }
},
background: powerbi.models.BackgroundType.Transparent
}
};

const reportContainer = document.getElementById('reportContainer');
const report = powerbi.embed(reportContainer, embedConfig);

// Auto-refresh every 5 minutes
setInterval(() => {
report.refresh();
}, 300000);
});
</script>
</body>
</html>

Token Refresh Strategy

Embed tokens expire (default 1 hour). Implement automatic refresh:

// Token refresh handler
let tokenRefreshInterval;

function setupTokenRefresh(report) {
// Refresh token every 50 minutes (before 1-hour expiry)
tokenRefreshInterval = setInterval(async () => {
const newConfig = await fetch('/api/powerbi-embed-config').then(r => r.json());
report.setAccessToken(newConfig.embedToken);
}, 50 * 60 * 1000);
}

Method 3: Power BI Desktop Kiosk Mode

For Windows-based players with Power BI Desktop installed.

Setup

  1. Install Power BI Desktop on Windows signage player
  2. Sign in with a licensed account
  3. Open your report (.pbix file or from service)
  4. Press F11 for full-screen mode

Automation with Task Scheduler

Create a batch script to launch Power BI in kiosk mode:

@echo off
REM launch-powerbi-kiosk.bat

REM Kill any existing Power BI instance
taskkill /IM PBIDesktop.exe /F 2>nul

REM Wait a moment
timeout /t 5

REM Launch Power BI with your report
start "" "C:\Program Files\Microsoft Power BI Desktop\bin\PBIDesktop.exe" "C:\Reports\SalesDashboard.pbix"

REM Wait for Power BI to load
timeout /t 30

REM Send F11 to go full-screen (requires AutoHotkey or similar)
REM This part requires additional scripting

Considerations

AspectNotes
LicenseRequires Power BI Pro or Premium per User
UpdatesPower BI Desktop auto-updates may interrupt
AuthenticationUser must remain signed in
RefreshConfigure scheduled refresh in Desktop

Method 4: Screenshot/Image Export

Export dashboard as images on a schedule.

Using Power Automate

  1. Create a flow triggered on schedule (e.g., every 15 minutes)

  2. Add action: Power BI - Export to file

  3. Configure export:

    • Workspace
    • Report
    • Export format: PNG or PDF
  4. Save to location accessible by signage CMS

Using Power BI REST API

import requests
import time

def export_report_to_image(access_token, group_id, report_id):
# Initiate export
export_url = f"https://api.powerbi.com/v1.0/myorg/groups/{group_id}/reports/{report_id}/ExportTo"

headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}

body = {
"format": "PNG",
"powerBIReportConfiguration": {
"pages": [{"pageName": "ReportSection1"}]
}
}

response = requests.post(export_url, headers=headers, json=body)
export_id = response.json()["id"]

# Poll for completion
status_url = f"https://api.powerbi.com/v1.0/myorg/groups/{group_id}/reports/{report_id}/exports/{export_id}"

while True:
status = requests.get(status_url, headers=headers).json()
if status["status"] == "Succeeded":
return status["resourceLocation"]
elif status["status"] == "Failed":
raise Exception("Export failed")
time.sleep(5)

# Download the exported file
def download_export(file_url, access_token, save_path):
headers = {"Authorization": f"Bearer {access_token}"}
response = requests.get(file_url, headers=headers)

with open(save_path, 'wb') as f:
f.write(response.content)

Signage CMS Integration

Point your signage CMS to the exported image location:

  • Network share: \\server\powerbi-exports\dashboard.png
  • Web server: https://internal.company.com/exports/dashboard.png
  • Cloud storage: Azure Blob, S3, etc.

Design Best Practices for Signage

Resolution and Sizing

DisplayRecommended Report Size
1080p Landscape1920 × 1080 px
1080p Portrait1080 × 1920 px
4K Landscape3840 × 2160 px
Video Wall 2×23840 × 2160 px

In Power BI:

  1. Go to ViewPage size
  2. Select Custom
  3. Enter exact pixel dimensions

Typography for Distance Viewing

Viewing DistanceMinimum Font Size
6 feet (2m)24pt
12 feet (4m)48pt
20 feet (6m)72pt
30+ feet (10m)96pt+

Color and Contrast

ElementRecommendation
BackgroundDark for most environments (reduces glare)
TextWhite or high-contrast colors
Positive valuesGreen
Negative valuesRed
NeutralBlue or gray
Contrast ratioMinimum 4.5:1, prefer 7:1

Dashboard Layout

┌─────────────────────────────────────────────────────────────────┐
│ SIGNAGE DASHBOARD LAYOUT │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ HEADER / KPIs │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Revenue │ │ Orders │ │ Target │ │ % │ │ │
│ │ │ $1.2M │ │ 4,521 │ │ 95% │ │ +12% │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────┐ ┌────────────────────────┐ │
│ │ │ │ │ │
│ │ PRIMARY CHART │ │ SECONDARY │ │
│ │ (Line/Bar) │ │ VISUAL │ │
│ │ │ │ │ │
│ │ │ ├────────────────────────┤ │
│ │ │ │ │ │
│ │ │ │ TABLE/LIST │ │
│ │ │ │ │ │
│ └──────────────────────────────┘ └────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ FOOTER: Last updated: 2:45 PM | Data source: SAP │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘

Auto-Refresh Configuration

Report-Level Refresh

In Power BI Service:

  1. Open report settings
  2. Enable Automatic page refresh
  3. Set refresh interval (minimum depends on license)
LicenseMinimum Interval
Pro30 minutes
Premium1 second
Embedded1 second

Dataset Refresh

For underlying data:

  1. Go to dataset settings
  2. Scheduled refresh → Add times
  3. Up to 8 refreshes/day (Pro) or 48 (Premium)

Signage-Level Refresh

MethodImplementation
Page reloadSet CMS to reload URL every X minutes
JavaScriptCall report.refresh() API
Full restartSchedule player reboot daily

Troubleshooting

Common Issues

IssueCauseSolution
Blank screenToken expiredImplement token refresh
"Can't connect"Network/auth issueCheck firewall, credentials
Slow loadingLarge datasetOptimize report, use aggregations
Layout brokenResolution mismatchMatch report to display resolution
No refreshSchedule not setConfigure auto-refresh
Login promptSession timeoutUse service principal

Performance Optimization

  1. Use aggregations for large datasets
  2. Limit visuals to 6-8 per page
  3. Avoid complex DAX in real-time scenarios
  4. Pre-aggregate data where possible
  5. Use DirectQuery sparingly (Import preferred)

Frequently Asked Questions


Next Steps


This guide is maintained by MediaSignage, pioneers of digital signage technology since 2008.