Lab 047: Work IQ β Copilot Adoption AnalyticsΒΆ
What You'll LearnΒΆ
- What Work IQ is and why adoption analytics matters for AI rollouts
- How to read and interpret Copilot usage data from Viva Insights and the M365 Admin Center
- Analyze adoption rates by department using Python and pandas
- Identify adoption blockers: licensing gaps, enablement gaps, and low engagement
- Build a rollout scorecard that turns raw data into an executive summary
IntroductionΒΆ
Work IQ is Microsoft's framework for measuring and optimizing AI adoption across an organization. As companies move from deploying Microsoft 365 Copilot to proving ROI, the ability to analyze adoption data becomes a critical skill.
In 2025-2026, the question has shifted from "Did we deploy Copilot?" to "Is it actually being used? By whom? For what? And what value is it creating?"
The ScenarioΒΆ
You are the AI Adoption Lead at OutdoorGear Inc. The company deployed M365 Copilot to 52 employees across 7 departments three months ago. Leadership wants answers:
- Which departments are actually using Copilot?
- Where are licenses going unused β and why?
- What features are people using most?
- How much time has Copilot saved the organization?
You have a usage data export (similar to what Viva Insights and the M365 Admin Center provide). Your job: turn raw data into an actionable adoption scorecard.
Live vs. Mock Data
This lab uses a mock dataset (copilot_usage_data.csv) so anyone can follow along without an M365 Copilot license. The data structure mirrors what you'd see in Viva Insights exports. If you have a live M365 environment, you can substitute your own data.
PrerequisitesΒΆ
| Requirement | Why |
|---|---|
| Python 3.10+ | Run the analysis scripts |
pandas library |
Data manipulation |
| (Optional) M365 Copilot license + Viva Insights | For live data instead of mock |
π¦ Supporting FilesΒΆ
Download these files before starting the lab
Save all files to a lab-047/ folder in your working directory.
| File | Description | Download |
|---|---|---|
broken_scorecard.py |
Bug-fix exercise (3 bugs + self-tests) | π₯ Download |
copilot_usage_data.csv |
Dataset | π₯ Download |
scorecard_builder.py |
Starter script with TODOs | π₯ Download |
Step 1: Understand the Key MetricsΒΆ
Before touching data, you need to understand what Work IQ measures. These are the same metrics tracked by Viva Insights and the M365 Admin Center:
| Metric | What It Measures | Why It Matters |
|---|---|---|
| Licensed | User has an M365 Copilot license assigned | License β usage; tracks investment allocation |
| Enabled | Admin has activated Copilot for the user | Gap between licensed and enabled = wasted spend |
| Active Days | Days the user interacted with any Copilot feature | Measures engagement depth, not just one-time trial |
| Meetings Assisted | Meetings where Copilot generated summaries/actions | High-value use case for managers |
| Emails Drafted | Emails composed or refined with Copilot help | Measures writing productivity |
| Docs Summarized | Documents summarized or analyzed by Copilot | Measures knowledge work efficiency |
| Chats | Copilot Chat interactions (questions, brainstorming) | Measures exploration and daily utility |
| Time Saved (min) | Estimated minutes saved by Copilot | The ultimate ROI metric |
Key FormulasΒΆ
Adoption Rate = (Active Users Γ· Enabled Users) Γ 100
Enablement Gap = Licensed Users β Enabled Users
β Users with a paid license that admins haven't turned on
Licensing Gap = Total Users β Licensed Users
β Users without any Copilot license at all
Viva Insights Privacy
In production Viva Insights, a minimum group size of 5 users is enforced for all reports. You cannot drill into departments smaller than 5. Our mock data ignores this for learning purposes, but keep it in mind for real deployments.
Step 2: Load and Explore the DatasetΒΆ
The dataset has 52 user records across 7 departments. Start by loading it in Python:
import pandas as pd
df = pd.read_csv("lab-047/copilot_usage_data.csv")
# Convert string booleans to Python booleans
for col in ["licensed", "enabled"]:
df[col] = df[col].astype(str).str.strip().str.lower() == "true"
print(f"Total records: {len(df)}")
print(f"Departments: {df['department'].nunique()}")
print(f"\nColumn types:\n{df.dtypes}")
print(f"\nFirst 5 rows:\n{df.head()}")
Expected output:
Take a moment to explore:
# Quick summary by department
summary = df.groupby("department").agg(
total=("user_id", "count"),
licensed=("licensed", "sum"),
enabled=("enabled", "sum"),
).reset_index()
print(summary)
π€ Before you continue: Which department do you predict will have the highest adoption rate?
Think about it β then continue to Step 3 to find out if you're right!
Step 3: Calculate Adoption Rates by DepartmentΒΆ
Now compute the adoption rate for each department. Remember: adoption rate = active users Γ· enabled users Γ 100.
An "active" user is anyone with active_days > 0 (they used Copilot at least once during the month).
results = []
for dept, group in df.groupby("department"):
total = len(group)
licensed = group["licensed"].sum()
enabled = group["enabled"].sum()
active = len(group[(group["enabled"] == True) & (group["active_days"] > 0)])
rate = (active / enabled * 100) if enabled > 0 else 0
results.append({
"Department": dept,
"Total": total,
"Licensed": licensed,
"Enabled": enabled,
"Active": active,
"Adoption %": round(rate, 1),
})
adoption_df = pd.DataFrame(results).sort_values("Adoption %", ascending=False)
print(adoption_df.to_string(index=False))
Expected output:
| Department | Total | Licensed | Enabled | Active | Adoption % |
|---|---|---|---|---|---|
| Finance | 6 | 6 | 6 | 6 | 100.0 |
| Engineering | 12 | 11 | 10 | 9 | 90.0 |
| Marketing | 8 | 8 | 7 | 6 | 85.7 |
| Operations | 7 | 6 | 5 | 4 | 80.0 |
| Sales | 10 | 8 | 5 | 4 | 80.0 |
| HR | 5 | 3 | 3 | 2 | 66.7 |
| Legal | 4 | 3 | 2 | 1 | 50.0 |
Insight
Finance leads at 100% β every enabled user is active. Legal is at 50% β only 1 out of 2 enabled users has ever opened Copilot. But notice that Legal also has the fewest enabled users (2). Small sample sizes can be misleading β this is why Viva Insights enforces a minimum group size of 5.
Step 4: Identify Adoption BlockersΒΆ
Three types of blockers prevent Copilot adoption:
4a β Enablement Gap (Licensed but NOT Enabled)ΒΆ
gap = df[(df["licensed"] == True) & (df["enabled"] == False)]
print(f"Enablement gap: {len(gap)} users\n")
print(gap[["department", "user_id"]].to_string(index=False))
Expected output:
Enablement gap: 7 users
department user_id
Engineering ENG-011
Marketing MKT-008
Sales SLS-004
Sales SLS-005
Sales SLS-006
Legal LEG-003
Operations OPS-006
The Sales Problem
Sales has 3 licensed users stuck in the enablement gap β that's 37.5% of their licensed users! This is likely an admin oversight. One ticket to IT could unlock 3 more active users.
4b β Licensing Gap (No License at All)ΒΆ
unlicensed = df[df["licensed"] == False]
print(f"Unlicensed users: {len(unlicensed)}")
print(unlicensed.groupby("department")["user_id"].count())
4c β Zero-Usage Users (Enabled but Never Used)ΒΆ
zero_usage = df[(df["enabled"] == True) & (df["active_days"] == 0)]
print(f"Enabled but never used: {len(zero_usage)} users")
print(zero_usage[["department", "user_id"]].to_string(index=False))
These users have Copilot available but haven't touched it. They may need training, awareness campaigns, or a nudge from their manager.
Step 5: Feature Usage AnalysisΒΆ
Which Copilot features drive the most value at OutdoorGear?
active = df[df["active_days"] > 0]
features = {
"Meetings Assisted": active["meetings_assisted"].sum(),
"Emails Drafted": active["emails_drafted"].sum(),
"Docs Summarized": active["docs_summarized"].sum(),
"Chats": active["chats"].sum(),
}
print("Feature Usage (total interactions among active users):")
for feat, count in sorted(features.items(), key=lambda x: x[1], reverse=True):
pct = count / sum(features.values()) * 100
print(f" {feat:>20s}: {count:>5d} ({pct:.1f}%)")
Expected output:
| Feature | Total | Share |
|---|---|---|
| Chats | 400 | 32.8% |
| Meetings Assisted | 303 | 24.8% |
| Emails Drafted | 260 | 21.3% |
| Docs Summarized | 257 | 21.1% |
Insight
Chats dominate at 32.8% β users are primarily using Copilot for Q&A, brainstorming, and quick lookups. Meetings are the second most used feature, driven by Finance and Engineering where managers rely on meeting summaries.
Step 6: Build the ScorecardΒΆ
Now combine all your analysis into a single Adoption Scorecard for leadership:
total_time = int(active["time_saved_min"].sum())
scorecard = f"""# π OutdoorGear Inc. β Copilot Adoption Scorecard
**Reporting Period:** March 2026 (1-month snapshot)
## Overall Metrics
| Metric | Value |
|--------|-------|
| Total Users | {len(df)} |
| Licensed | {df['licensed'].sum()} |
| Enabled | {df['enabled'].sum()} |
| Active | {len(active)} |
| Overall Adoption Rate | {len(active) / df['enabled'].sum() * 100:.1f}% |
| Time Saved | {total_time} min ({total_time / 60:.1f} hours) |
| Enablement Gap | {len(gap)} users |
## Department Ranking
{adoption_df.to_markdown(index=False)}
## Top Actions
1. **Close the Sales enablement gap** β 3 licensed users not yet enabled
2. **Investigate Legal adoption** β only 1 of 2 enabled users is active
3. **Scale Finance's success** β 100% adoption; learn what they're doing right
4. **Run training for zero-usage users** β {len(zero_usage)} enabled users never opened Copilot
"""
print(scorecard)
with open("lab-047/scorecard_report.md", "w") as f:
f.write(scorecard)
print("πΎ Saved to lab-047/scorecard_report.md")
π Bug-Fix ExerciseΒΆ
The file lab-047/broken_scorecard.py contains 3 bugs that produce incorrect adoption metrics. Can you find and fix them all?
Run the self-tests to see which ones fail:
You should see 3 failed tests. Each test corresponds to one bug:
| Test | What it checks | Hint |
|---|---|---|
| Test 1 | Adoption rate denominator | Should use enabled users, not total users |
| Test 2 | Enablement gap filter logic | Check the boolean conditions |
| Test 3 | Time conversion factor | Minutes β hours conversion |
Fix all 3 bugs, then re-run. When you see π All 3 tests passed, you're done!
π§ Knowledge CheckΒΆ
Q1 (Multiple Choice): In Microsoft Viva Insights, what is the default minimum group size to protect employee privacy?
- A) 3 users
- B) 5 users
- C) 10 users
- D) 25 users
β Reveal Answer
Correct: B) 5 users
Viva Insights enforces a minimum group size of 5 by default. Reports for groups smaller than 5 are suppressed to prevent identifying individual usage patterns. Admins can increase (but not decrease) this threshold.
Q2 (Multiple Choice): Which metric best indicates that users are consistently using Copilot over time, rather than just trying it once?
- A) Total emails drafted
- B) Number of licensed users
- C) Monthly active days average
- D) Time saved in minutes
β Reveal Answer
Correct: C) Monthly active days average
A high active-days count means the user returns to Copilot day after day β this measures stickiness and habit formation, not just a one-time trial. Total emails or time saved can be inflated by a single heavy-use day.
Q3 (Run the Lab): Which department has the highest Copilot adoption rate (active Γ· enabled Γ 100)?
Run the Step 3 analysis on π₯ copilot_usage_data.csv and check the results.
β Reveal Answer
Finance β 100.0%
Finance has 6 licensed, 6 enabled, and 6 active users β every single enabled user is actively using Copilot. This makes Finance the model department for scaling adoption best practices to other teams.
Q4 (Run the Lab): How many users across the organization are in the 'enablement gap' (licensed = true, enabled = false)?
Run the Step 4a analysis to find out.
β Reveal Answer
7 users
The 7 users in the enablement gap are: ENG-011, MKT-008, SLS-004, SLS-005, SLS-006, LEG-003, and OPS-006. Sales alone accounts for 3 of these β the quickest win for improving overall adoption is to enable these users.
Q5 (Run the Lab): How many 'power users' are there (employees with active_days >= 20)?
Filter the dataset for users with 20+ active days and count them.
β Reveal Answer
10 power users
- Engineering: ENG-001 (22), ENG-002 (20), ENG-004 (21), ENG-007 (23), ENG-009 (20) β 5
- Marketing: MKT-003 (20) β 1
- Finance: FIN-001 (22), FIN-002 (21), FIN-003 (20), FIN-005 (23) β 4
- Total: 10 power users across Engineering, Marketing, and Finance
SummaryΒΆ
| Topic | What You Learned |
|---|---|
| Work IQ | Framework for measuring AI adoption and proving ROI |
| Adoption Rate | active Γ· enabled Γ 100 β the primary health metric |
| Enablement Gap | Licensed but not enabled β the quickest fix for low adoption |
| Feature Mix | Which Copilot features drive the most value |
| Time Saved | Converting minutes into business impact for leadership |
| Scorecard | Combining metrics into an executive-ready report |
Next StepsΒΆ
- Lab 048 (coming soon) β Build advanced Power BI dashboards with Viva Insights Advanced Reporting
- Lab 033 β Agent Observability with Application Insights (similar analytics mindset for custom agents)
- Lab 035 β Agent Evaluation with Azure AI Eval SDK (measuring agent quality, not just adoption)
- Lab 038 β AI Cost Optimization (the financial side of ROI)