Power BI Core Visuals team led by Miguel Myers published a huge update last week : Organizational Themes. It’s been a long standing ask by the users. It allows Power BI admins to manage and distribute centrally stored themes to all developers in the organization. Read the blog post for details. Currently, as the above blog explains, org themes don’t update existing reports automatically, which makes sense. But what if you want to bulk update many published reports with the org themes? The latest version of Semantic Link Labs to the rescue (v 0.11.0) !!!
💡
Before you proceed, please note that Organizational Theme is a
Preview feature and is available only to admins. Semantic Link Labs needs the report to be in
PBIR format for below function to work. You can read about PBIR, its use cases & limitations
here. Also, Semantic Link Labs currently uses an internal API which will be updated when the public API for org themes is available.
Organizational Theme
I have three report themes published in the tenant.

Semantic Link Labs
Using Semantic Link Labs, I want to apply one of the themes (the Sales Dark Theme for illustration purposes) to be applied to all reports in a workspace. To show that this works for reports in Pro workspaces as well, I published three reports to a Pro workspace. Using Semantic Link Labs, I will:
Install SLL version >= 0.11.0
Get the JSON of the Sales Dark Theme from the org themes
Get a list of all the reports in the workspace
If the report theme is different from the org theme, apply the theme to each report

The base code is very simple - get org theme, apply the theme:
theme_json = theme.get_org_theme_json(theme='MyTheme')
with connect_report(report=report, workspace=workspace,readonly=False) as rpt:
rpt.set_theme(theme_json=theme_json)
Below, I make it a bit more robust with error handling, catch a few edge cases and do some comparison etc:
%pip install semantic-link-labs --q
from sempy_labs.report import connect_report
from sempy_labs.theme import list_org_themes, get_org_theme_json
import sempy.fabric as fabric
import json
def theme_content(theme_dict):
return {k: v for k, v in theme_dict.items() if k != "name"}
def apply_org_theme(workspace, org_theme_name=None):
"""
For each report in the workspace, applies the org theme if not already set or if only the name is different.
"""
org_themes = list_org_themes()
if org_themes.empty:
raise ValueError("org themes nt found.")
if org_theme_name:
row = org_themes[org_themes["Theme Name"] == org_theme_name]
if row.empty:
raise ValueError(f"Org theme '{org_theme_name}' not found.")
theme_id = row["Theme Id"].iloc[0]
else:
theme_id = org_themes["Theme Id"].iloc[0]
org_theme_name = org_themes["Theme Name"].iloc[0]
org_theme_json = get_org_theme_json(theme_id)
if isinstance(org_theme_json, str):
org_theme_json = json.loads(org_theme_json)
org_theme_content = theme_content(org_theme_json)
org_theme_name_val = org_theme_json.get("name", org_theme_name)
reports = fabric.list_reports(workspace=workspace)
updated = []
for ix, row in reports.iterrows():
report_id = row["Id"]
report_name = row["Name"]
try:
with connect_report(report=report_id, workspace=workspace, readonly=False, show_diffs=False) as rpt:
try:
report_theme = rpt.get_theme("customTheme")
except Exception:
try:
report_theme = rpt.get_theme("baseTheme")
except Exception:
report_theme = {}
if isinstance(report_theme, str):
report_theme = json.loads(report_theme)
report_theme_content = theme_content(report_theme)
report_theme_name_val = report_theme.get("name", "")
content_match = json.dumps(report_theme_content, sort_keys=True) == json.dumps(org_theme_content, sort_keys=True)
name_match = report_theme_name_val == org_theme_name_val
if content_match and name_match:
print(f"Report '{report_name}' already has the '{org_theme_name}' org theme.")
continue
elif content_match and not name_match:
print(f"Report theme details are the same but the theme name is different. Updated the report with the new theme '{org_theme_name}'.")
rpt.set_theme(theme_json=org_theme_json)
updated.append(report_name)
else:
print(f"Applying org theme '{org_theme_name}' to '{report_name}'...")
rpt.set_theme(theme_json=org_theme_json)
updated.append(report_name)
except Exception as err:
print(f"failed to update '{report_name}': {err}")
return updated
Example:

There is no API, yet, to update the Org theme but I am sure it will be made available in the future.
Note again that I executed the notebook in a Fabric workspace but the reports are in a Pro workspace ! Michael Kovalsky and other contributors have been adding many new functions to the ReportWrapper class, you should take a look at it for all the possibilities.