DEV Community

LaTerral Williams
LaTerral Williams

Posted on

🔐 Building an IAM Security Dashboard with Power BI (Beginner-Friendly Walkthrough)

Goal: Build a leadership-ready IAM security dashboard in Power BI Desktop using a simulated IAM dataset you generate yourself.

Audience: Beginners transitioning into security analytics

What you’ll end with:

  • A working Power BI dashboard (.pbix)
  • A CSV dataset + Python generator script
  • A GitHub repo with clear structure + screenshots
  • A documented “enterprise-style” workflow (Linux + Windows)

✅ What This Dashboard Answers

This dashboard is designed to help a security analyst answer:

  • Are failed logins trending up?
  • Which users have the highest risk?
  • What’s the MFA posture?
  • Where should we investigate first (user + location)?

This is security reporting maturity not just “here are logs.”


🧾 Table of Contents


1. Project Overview

Output files you’ll have by the end:

  • data/iam_security_events.csv (dataset)
  • data/generate_data.py (generator)
  • data/IAM_Security_Dashboard.pbix (Power BI dashboard)
  • screenshots/ (images of final dashboard)

2. Tools You Need

Linux (Ubuntu)

  • Python 3
  • Git
  • (Optional) OneDrive sync client or manual upload via browser

Windows (VM)

  • Power BI Desktop (free)
  • OneDrive (optional but easy)

Note: You can likely accomplish all of this using Windows. I was already working on my linux machine when structuring this project. This made it easier for me to work with python and push to github. My steps are not law to complete this project.


3. Professional Setup

This is the setup many analysts use:

Linux for:

  • dataset generation (Python)
  • validation
  • GitHub version control
  • writing documentation

Windows for:

  • Power BI Desktop
  • visuals + DAX
  • exporting .pbix + screenshots

4. Install VirtualBox on Ubuntu

4.1 Install dependencies

sudo apt update
sudo apt install -y build-essential dkms linux-headers-$(uname -r)
Enter fullscreen mode Exit fullscreen mode

4.2 Install VirtualBox

Install VirtualBox from Ubuntu repos (beginner friendly):

sudo apt install -y virtualbox
Enter fullscreen mode Exit fullscreen mode

4.3 Fix common VirtualBox kernel module errors

If you see errors like “Kernel driver not installed”:

sudo /sbin/vboxconfig
Enter fullscreen mode Exit fullscreen mode

If it still fails, Secure Boot may be blocking modules. Disable Secure Boot in BIOS/UEFI for lab use.

4.4 Fix VMX/KVM conflict (if VirtualBox says VMX root mode error)

Check KVM modules:

lsmod | grep kvm
Enter fullscreen mode Exit fullscreen mode

Temporarily unload (Intel):

sudo modprobe -r kvm_intel
sudo modprobe -r kvm
Enter fullscreen mode Exit fullscreen mode

(AMD systems use kvm_amd.)


5. Create the Windows 11 VM

Recommended VM settings (good balance)

  • Name: Windows11
  • Type: Microsoft Windows
  • Version: Windows 11 (64-bit)
  • RAM: 8 GB (minimum 4 GB)
  • CPU: 2 cores (4 if available)
  • Virtual disk: 60 GB, dynamically allocated (recommended)

5.1 Attach the Windows 11 ISO

If the VM won’t boot, it usually means you forgot to attach the ISO:

  • Settings → Storage → Empty → Choose ISO

5.2 Install Windows

  • Choose “I don’t have a product key” (fine for labs)
  • Complete setup

6. Install Power BI Desktop in Windows

Inside the Windows VM:

  1. Open browser
  2. Install Power BI Desktop
  3. Confirm it opens successfully

7. Create the Project Folder Structure

On Linux, create a clean repo structure:

mkdir -p ~/Projects/powerbi-security-dashboard/{data,screenshots}
cd ~/Projects/powerbi-security-dashboard
Enter fullscreen mode Exit fullscreen mode

8. Generate the IAM Dataset (Python)

8.1 Create a generator script

Create data/generate_data.py:

import random
import csv
from datetime import datetime, timedelta

random.seed(7)

USERS = [
    "alex.lee@company.com",
    "jane.doe@company.com",
    "sam.taylor@company.com",
    "morgan.chan@company.com",
    "devon.king@company.com",
]

LOCATIONS = ["US-TX", "US-CA", "US-NY", "GB-LON", "ZA-JHB"]
EVENT_TYPES = ["LoginSuccess", "LoginFailure", "MFAChallenge"]
AUTH_METHODS = ["Password", "MFA"]

def risk_for_event(event_type: str, mfa_enabled: bool) -> str:
    # Simple rules to make data feel realistic
    if event_type == "LoginFailure" and not mfa_enabled:
        return random.choices(["Medium", "High"], weights=[60, 40])[0]
    if event_type == "LoginFailure":
        return random.choices(["Low", "Medium"], weights=[40, 60])[0]
    if event_type == "MFAChallenge":
        return "Low"
    return "Low"

def generate_rows(days: int = 14, rows_per_day: int = 80):
    start = datetime.now().date() - timedelta(days=days)
    for d in range(days):
        day = start + timedelta(days=d)
        for _ in range(rows_per_day):
            user = random.choice(USERS)
            mfa_enabled = random.choice([True, True, True, False])  # mostly enabled
            event_type = random.choices(EVENT_TYPES, weights=[70, 25, 5])[0]
            auth_method = "MFA" if (mfa_enabled and event_type != "LoginFailure") else "Password"
            location = random.choice(LOCATIONS)
            risk = risk_for_event(event_type, mfa_enabled)

            yield {
                "EventDate": day.isoformat(),
                "UserPrincipalName": user,
                "EventType": event_type,
                "AuthMethod": auth_method,
                "MFAEnabled": mfa_enabled,
                "Location": location,
                "RiskLevel": risk,
            }

def main():
    out_path = "data/iam_security_events.csv"
    fieldnames = ["EventDate", "UserPrincipalName", "EventType", "AuthMethod", "MFAEnabled", "Location", "RiskLevel"]

    with open(out_path, "w", newline="", encoding="utf-8") as f:
        w = csv.DictWriter(f, fieldnames=fieldnames)
        w.writeheader()
        for row in generate_rows():
            w.writerow(row)

    print(f"Wrote dataset to {out_path}")

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

8.2 Run it

python3 data/generate_data.py
Enter fullscreen mode Exit fullscreen mode

8.3 Sanity check the CSV

head -n 5 data/iam_security_events.csv
Enter fullscreen mode Exit fullscreen mode

9. Move the CSV to Windows (OneDrive Method)

Because Power BI Desktop runs on Windows, you need your CSV accessible in the VM.

Option A (Recommended): OneDrive

  1. Upload data/iam_security_events.csv to OneDrive (from Linux browser)
  2. In Windows VM, open OneDrive folder
  3. Confirm the CSV is synced locally

This is common in real environments: Linux generates data; Windows consumes it for reporting.


10. Import Data into Power BI

In Power BI Desktop (Windows VM):

  1. Home → Get DataText/CSV
  2. Select iam_security_events.csv
  3. Click Transform Data
  4. Confirm types:
    • EventDate = Date
    • MFAEnabled = True/False (or Boolean)
  5. Close & Apply

11. Create DAX Measures

Right-click your table in the Fields pane (example: IAMSecurityEvents) → New measure

11.1 Total Login Attempts

Total Login Attempts =
COUNT(IAMSecurityEvents[EventType])
Enter fullscreen mode Exit fullscreen mode

11.2 Failed Logins

Failed Logins =
CALCULATE(
    COUNT(IAMSecurityEvents[EventType]),
    IAMSecurityEvents[EventType] = "LoginFailure"
)
Enter fullscreen mode Exit fullscreen mode

11.3 High Risk Events

High Risk Events =
CALCULATE(
    COUNT(IAMSecurityEvents[RiskLevel]),
    IAMSecurityEvents[RiskLevel] = "High"
)
Enter fullscreen mode Exit fullscreen mode

11.4 MFA Coverage % (optional but strong)

MFA Coverage % =
DIVIDE(
    CALCULATE(
        COUNT(IAMSecurityEvents[UserPrincipalName]),
        IAMSecurityEvents[MFAEnabled] = TRUE()
    ),
    COUNT(IAMSecurityEvents[UserPrincipalName]),
    0
)
Enter fullscreen mode Exit fullscreen mode

Format it as Percentage (Measure tools → Format → Percentage).


12. Build the Dashboard Visuals

12.1 KPI Cards (use Card visual)

Add 4 Card visuals and drop in:

  • Total Login Attempts
  • Failed Logins
  • High Risk Events
  • MFA Coverage %

Note: Power BI has a “KPI” visual, but for beginner dashboards, Card visuals are simpler and more reliable.

12.2 Line chart (Failed Logins over time)

Use a Line chart:

  • X-axis: EventDate
  • Y-axis: Failed Logins

12.3 Bar chart (High risk by location)

Use a Clustered bar chart:

  • Axis: Location
  • Values: High Risk Events

Sort descending by High Risk Events.


13. Build Risk by User Table (and Fix MFA Count)

13.1 Create the table

Add a Table visual and add these fields:

  • UserPrincipalName
  • Failed Logins (measure)
  • High Risk Events (measure)
  • MFAEnabled (column)

13.2 Fix: MFAEnabled shows as “Count”

This happens because Power BI auto-aggregates fields.

In the table visual:

  • In the Values well, click the dropdown next to MFAEnabled
  • Change from CountFirst (or Max)

Now it will show TRUE/FALSE per user instead of a number.

Note: If you have difficulty finding this, like I did... you may also create another measure.

MFA Enabled Status =
FIRSTNONBLANK(
    IAMSecurityEvents[MFAEnabled],
    1
)
Enter fullscreen mode Exit fullscreen mode

13.3 Sort the table for triage

Sort by:

  • High Risk Events descending Then by:
  • Failed Logins descending

This makes the table investigation-ready.


14. Export Screenshots and Save the PBIX

14.1 Save the dashboard

Save the Power BI file as:

  • data/IAM_Security_Dashboard.pbix

14.2 Take screenshots (Windows VM)

Capture:

  • Full dashboard view
  • Risk by User table close-up
  • High risk by location chart

Save them into your repo folder:

  • screenshots/

Tip: name your files so they are easy to locate.

Example:

  • 01-dashboard-overview.png
  • 02-risk-by-user.png
  • 03-high-risk-by-location.png

15. Push to GitHub (Tokens + Common Errors)

15.1 Initialize repo

git init
git add .
git commit -m "Initial commit: Power BI IAM security dashboard"
Enter fullscreen mode Exit fullscreen mode

15.2 Add remote

git remote add origin https://github.com/<your-username>/powerbi-security-dashboard.git
Enter fullscreen mode Exit fullscreen mode

15.3 Push

git push -u origin main
Enter fullscreen mode Exit fullscreen mode

Token permissions

Your GitHub token needs:

  • repo scope (classic token)

Common error: “fetch first”

If GitHub repo already has commits (like a README):

git pull origin main --rebase
git push -u origin main
Enter fullscreen mode Exit fullscreen mode

16. Automation Note (Why We Documented It)

Power BI alerts + Power Automate typically require a work/school tenant and licensing.

For this project:

  • We built the dashboard in Power BI Desktop
  • We documented automation as a “production extension”

This is realistic: many portfolio builds don’t have enterprise tenancy.


17. Final Checklist

✅ CSV generated and committed

✅ Power BI report built and saved as .pbix

✅ Measures working (cards update with filters)

✅ Risk by user table sorted and MFA fixed

✅ Screenshots captured and saved

✅ Repo pushed to GitHub


🤝 Connect

If you enjoyed this article or you’re also learning DevOps, Linux, Security, or Cloud automation, I’d love to connect, share ideas, and learn.

💬 Feel free to reach out or follow my journey on 👉 LinkedIn

Top comments (0)