Skip to content

Commit 1584a5d

Browse files
authored
Merge pull request #912 from Adam-it/new-script-spo-apply-site-theme
New script spo apply site theme
2 parents fbb1ce4 + f664a86 commit 1584a5d

File tree

4 files changed

+105
-4
lines changed

4 files changed

+105
-4
lines changed

scripts/spo-apply-site-theme/README.md

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
## Summary
66

7-
Apply a theme to a specific SharePoint site without adding a tenant theme that would be available for all sites through the "Change the look" menu.
7+
Apply a theme to a specific SharePoint site without adding a tenant theme that would be available for all sites through the "Change the look" menu. This sample is available in both PnP PowerShell and CLI for Microsoft 365.
88

9-
![Example Screenshot](assets/preview.png)
9+
Example of applying a custom theme to a SharePoint site using CLI for Microsoft 365:
10+
11+
![Example Screenshot of CLI for Microsoft 365](assets/preview.png)
1012

1113

1214
# [PnP PowerShell](#tab/pnpps)
@@ -71,6 +73,86 @@ Disconnect-PnPOnline
7173
```
7274
[!INCLUDE [More about PnP PowerShell](../../docfx/includes/MORE-PNPPS.md)]
7375

76+
# [CLI for Microsoft 365](#tab/cli-m365-ps)
77+
78+
```powershell
79+
[CmdletBinding(SupportsShouldProcess = $true)]
80+
param(
81+
[Parameter(Mandatory, HelpMessage = "SharePoint site URL to apply the theme")]
82+
[string]$SiteUrl,
83+
84+
[Parameter(Mandatory, HelpMessage = "Path to theme JSON file or inline JSON string")]
85+
[string]$ThemeJson,
86+
87+
[Parameter(HelpMessage = "Unique name for the temporary theme")]
88+
[string]$ThemeName = "TempTheme-$(Get-Date -Format 'yyyyMMddHHmmss')",
89+
90+
[Parameter(HelpMessage = "Keep the theme registered in tenant after applying")]
91+
[switch]$KeepTheme
92+
)
93+
94+
begin {
95+
m365 login --ensure
96+
if ($LASTEXITCODE -ne 0) {
97+
throw "Failed to verify login status"
98+
}
99+
100+
$themeContent = if ($ThemeJson.StartsWith('@')) {
101+
$filePath = $ThemeJson.Substring(1)
102+
if (-not (Test-Path $filePath)) {
103+
throw "Theme file not found: $filePath"
104+
}
105+
Get-Content $filePath -Raw
106+
} else {
107+
$ThemeJson
108+
}
109+
}
110+
111+
process {
112+
if (-not $PSCmdlet.ShouldProcess($SiteUrl, "Apply theme '$ThemeName'")) {
113+
return
114+
}
115+
116+
Write-Host "Registering theme '$ThemeName'..." -ForegroundColor Cyan
117+
$setResult = m365 spo theme set --name $ThemeName --theme $themeContent 2>&1
118+
if ($LASTEXITCODE -ne 0) {
119+
throw "Failed to register theme: $setResult"
120+
}
121+
122+
Write-Host "Applying theme to: $SiteUrl" -ForegroundColor Cyan
123+
$applyResult = m365 spo theme apply --name $ThemeName --webUrl $SiteUrl --output json 2>&1
124+
if ($LASTEXITCODE -ne 0) {
125+
throw "Failed to apply theme: $applyResult"
126+
}
127+
128+
Write-Host "Theme applied successfully!" -ForegroundColor Green
129+
Write-Host "Catalog path: $applyResult" -ForegroundColor Gray
130+
131+
if (-not $KeepTheme) {
132+
$removeResult = m365 spo theme remove --name $ThemeName --force 2>&1
133+
if ($LASTEXITCODE -ne 0) {
134+
Write-Warning "Failed to remove temporary theme. You may need to remove it manually."
135+
}
136+
} else {
137+
Write-Host "Theme kept in tenant gallery" -ForegroundColor Yellow
138+
}
139+
}
140+
141+
# Example 1: Apply theme from JSON file
142+
# .\Apply-SiteTheme.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ProjectX" -ThemeJson "@C:\themes\custom-theme.json"
143+
144+
# Example 2: Apply theme from inline JSON and keep it in tenant
145+
# .\Apply-SiteTheme.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ProjectX" -ThemeJson '{"themePrimary":"#d81e05","themeLighterAlt":"#fdf5f4","themeLighter":"#f9d6d2","themeLight":"#f4b4ac","themeTertiary":"#e87060","themeSecondary":"#dd351e","themeDarkAlt":"#c31a04","themeDark":"#a51603","themeDarker":"#791002","neutralLighterAlt":"#eeeeee","neutralLighter":"#f5f5f5","neutralLight":"#e1e1e1","neutralQuaternaryAlt":"#d1d1d1","neutralQuaternary":"#c8c8c8","neutralTertiaryAlt":"#c0c0c0","neutralTertiary":"#c2c2c2","neutralSecondary":"#858585","neutralPrimaryAlt":"#4b4b4b","neutralPrimary":"#333333","neutralDark":"#272727","black":"#1d1d1d","white":"#f5f5f5"}' -KeepTheme
146+
147+
# Example 3: Test with WhatIf before applying
148+
# .\Apply-SiteTheme.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ProjectX" -ThemeJson "@theme.json" -WhatIf
149+
150+
# Example 4: Apply with verbose output
151+
# .\Apply-SiteTheme.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ProjectX" -ThemeJson "@theme.json" -Verbose
152+
153+
```
154+
155+
[!INCLUDE [More about CLI for Microsoft 365](../../docfx/includes/MORE-CLIM365.md)]
74156

75157
***
76158

@@ -79,6 +161,7 @@ Disconnect-PnPOnline
79161
| Author(s) |
80162
|-----------|
81163
| [Aimery Thomas](https://github.com/a1mery)|
164+
| Adam Wójcik [@Adam-it](https://github.com/Adam-it)|
82165

83166
[!INCLUDE [DISCLAIMER](../../docfx/includes/DISCLAIMER.md)]
84167
<img src="https://m365-visitor-stats.azurewebsites.net/script-samples/scripts/spo-apply-site-theme" aria-hidden="true" />
432 KB
Loading
642 KB
Loading

scripts/spo-apply-site-theme/assets/sample.json

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@
99
"Apply a theme to a specific SharePoint site without adding a tenant theme that would be available for all sites through the 'Change the look' menu."
1010
],
1111
"creationDateTime": "2025-10-22",
12-
"updateDateTime": "2025-10-22",
12+
"updateDateTime": "2026-01-10",
1313
"products": [
1414
"SharePoint"
1515
],
1616
"metadata": [
1717
{
1818
"key": "PNP-POWERSHELL",
1919
"value": "3.1.0"
20+
},
21+
{
22+
"key": "CLI-FOR-MICROSOFT365",
23+
"value": "11.3.0"
2024
}
2125
],
2226
"categories": [
@@ -26,7 +30,11 @@
2630
"Connect-PnPOnline",
2731
"Get-PnPAccessToken",
2832
"Invoke-RestMethod",
29-
"Disconnect-PnPOnline"
33+
"Disconnect-PnPOnline",
34+
"m365 login",
35+
"m365 spo theme set",
36+
"m365 spo theme apply",
37+
"m365 spo theme remove"
3038
],
3139
"thumbnails": [
3240
{
@@ -41,13 +49,23 @@
4149
"gitHubAccount": "a1mery",
4250
"pictureUrl": "https://github.com/a1mery.png",
4351
"name": "Aimery Thomas"
52+
},
53+
{
54+
"gitHubAccount": "Adam-it",
55+
"pictureUrl": "https://avatars.githubusercontent.com/u/58668583?v=4",
56+
"name": "Adam Wójcik"
4457
}
4558
],
4659
"references": [
4760
{
4861
"name": "Want to learn more about PnP PowerShell and the cmdlets",
4962
"description": "Check out the PnP PowerShell site to get started and for the reference to the cmdlets.",
5063
"url": "https://aka.ms/pnp/powershell"
64+
},
65+
{
66+
"name": "Want to learn more about CLI for Microsoft 365 and the commands",
67+
"description": "Check out the CLI for Microsoft 365 site to get started and for the reference to the commands.",
68+
"url": "https://aka.ms/cli-m365"
5169
}
5270
]
5371
}

0 commit comments

Comments
 (0)