Skip to content

Commit 1ceae1b

Browse files
authored
Merge pull request #913 from Adam-it/new-script-spo-compare-files
New script spo compare files
2 parents 1584a5d + 54d9cc2 commit 1ceae1b

File tree

3 files changed

+138
-4
lines changed

3 files changed

+138
-4
lines changed

scripts/spo-compare-files/README.md

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

55
## Summary
66

7-
This script first connects to the first tenant using the Connect-PnPOnline cmdlet, then uses the Get-PnPFile cmdlet to retrieve the file in question. It then connects to the second tenant and retrieves the same file. The script then uses the Get-FileHash cmdlet to retrieve the hash of the file in both tenants. Finally, it compares the hashes of the two files and outputs the results to the console.
7+
This script compares files from two different SharePoint tenants by calculating and comparing their hash values. This is useful for verifying file integrity after migrations or ensuring files are identical across tenants. This sample is available in both PnP PowerShell and CLI for Microsoft 365.
88

9+
Example of script output of the CLI for Microsoft 365 version:
10+
11+
![preview CLI for Microsoft 365 output](assets/preview.png)
912

1013
# [PnP PowerShell](#tab/pnpps)
1114

@@ -32,13 +35,127 @@ if ($hash1 -eq $hash2) {
3235
3336
```
3437
[!INCLUDE [More about PnP PowerShell](../../docfx/includes/MORE-PNPPS.md)]
38+
39+
# [CLI for Microsoft 365](#tab/cli-m365-ps)
40+
41+
```powershell
42+
[CmdletBinding()]
43+
param(
44+
[Parameter(Mandatory, HelpMessage = "URL of the site in first tenant")]
45+
[string]$WebUrl1,
46+
47+
[Parameter(Mandatory, HelpMessage = "Server-relative URL of the file in first tenant")]
48+
[string]$FileUrl1,
49+
50+
[Parameter(Mandatory, HelpMessage = "URL of the site in second tenant")]
51+
[string]$WebUrl2,
52+
53+
[Parameter(HelpMessage = "Server-relative URL of the file in second tenant (defaults to same as FileUrl1)")]
54+
[string]$FileUrl2,
55+
56+
[Parameter(HelpMessage = "Name for the first tenant connection (defaults to 'tenant1')")]
57+
[string]$Connection1Name = "tenant1",
58+
59+
[Parameter(HelpMessage = "Name for the second tenant connection (defaults to 'tenant2')")]
60+
[string]$Connection2Name = "tenant2"
61+
)
62+
63+
begin {
64+
if ([string]::IsNullOrEmpty($FileUrl2)) {
65+
$FileUrl2 = $FileUrl1
66+
}
67+
68+
Write-Host "Setting up connections to both tenants..." -ForegroundColor Cyan
69+
70+
Write-Host "Logging in to first tenant ($WebUrl1)..." -ForegroundColor Cyan
71+
m365 login --connectionName $Connection1Name
72+
if ($LASTEXITCODE -ne 0) {
73+
throw "Failed to login to first tenant"
74+
}
75+
76+
Write-Host "Logging in to second tenant ($WebUrl2)..." -ForegroundColor Cyan
77+
m365 login --connectionName $Connection2Name
78+
if ($LASTEXITCODE -ne 0) {
79+
throw "Failed to login to second tenant"
80+
}
81+
82+
$tempDir = Join-Path $env:TEMP "CompareFiles-$(Get-Date -Format 'yyyyMMddHHmmss')"
83+
New-Item -ItemType Directory -Path $tempDir -Force | Out-Null
84+
$tempFile1 = Join-Path $tempDir "file1.tmp"
85+
$tempFile2 = Join-Path $tempDir "file2.tmp"
86+
}
87+
88+
process {
89+
try {
90+
Write-Host "`nSwitching to first tenant connection..." -ForegroundColor Cyan
91+
m365 connection use --name $Connection1Name | Out-Null
92+
if ($LASTEXITCODE -ne 0) {
93+
throw "Failed to switch to first tenant connection"
94+
}
95+
96+
Write-Host "Downloading file from first tenant: $FileUrl1" -ForegroundColor Cyan
97+
$result1 = m365 spo file get --webUrl $WebUrl1 --url $FileUrl1 --asFile --path $tempFile1 2>&1
98+
if ($LASTEXITCODE -ne 0) {
99+
throw "Failed to download file from first tenant: $result1"
100+
}
101+
102+
Write-Host "`nSwitching to second tenant connection..." -ForegroundColor Cyan
103+
m365 connection use --name $Connection2Name | Out-Null
104+
if ($LASTEXITCODE -ne 0) {
105+
throw "Failed to switch to second tenant connection"
106+
}
107+
108+
Write-Host "Downloading file from second tenant: $FileUrl2" -ForegroundColor Cyan
109+
$result2 = m365 spo file get --webUrl $WebUrl2 --url $FileUrl2 --asFile --path $tempFile2 2>&1
110+
if ($LASTEXITCODE -ne 0) {
111+
throw "Failed to download file from second tenant: $result2"
112+
}
113+
114+
Write-Host "`nCalculating file hashes..." -ForegroundColor Cyan
115+
$hash1 = (Get-FileHash -Path $tempFile1 -Algorithm SHA256).Hash
116+
$hash2 = (Get-FileHash -Path $tempFile2 -Algorithm SHA256).Hash
117+
118+
Write-Host "`nComparison Results:" -ForegroundColor White
119+
Write-Host "==================" -ForegroundColor White
120+
Write-Host "File 1 ($Connection1Name): $FileUrl1" -ForegroundColor Gray
121+
Write-Host "Hash 1: $hash1" -ForegroundColor Gray
122+
Write-Host "`nFile 2 ($Connection2Name): $FileUrl2" -ForegroundColor Gray
123+
Write-Host "Hash 2: $hash2" -ForegroundColor Gray
124+
125+
Write-Host "`nResult: " -NoNewline
126+
if ($hash1 -eq $hash2) {
127+
Write-Host "Files are IDENTICAL" -ForegroundColor Green
128+
} else {
129+
Write-Host "Files are DIFFERENT" -ForegroundColor Red
130+
}
131+
} finally {
132+
if (Test-Path $tempDir) {
133+
Remove-Item -Path $tempDir -Recurse -Force
134+
}
135+
}
136+
}
137+
138+
# Example 1: Compare same file across two tenants
139+
# .\Compare-Files.ps1 -WebUrl1 "https://contoso.sharepoint.com/sites/Site1" -FileUrl1 "/Shared Documents/document.docx" -WebUrl2 "https://fabrikam.sharepoint.com/sites/Site2" -Connection1Name "contoso" -Connection2Name "fabrikam"
140+
141+
# Example 2: Compare different file paths
142+
# .\Compare-Files.ps1 -WebUrl1 "https://contoso.sharepoint.com/sites/Site1" -FileUrl1 "/Shared Documents/doc1.pdf" -WebUrl2 "https://fabrikam.sharepoint.com/sites/Site2" -FileUrl2 "/Documents/doc2.pdf"
143+
144+
# Example 3: Compare with default connection names (tenant1, tenant2)
145+
# .\Compare-Files.ps1 -WebUrl1 "https://contoso.sharepoint.com/sites/Site1" -FileUrl1 "/Shared Documents/report.xlsx" -WebUrl2 "https://fabrikam.sharepoint.com/sites/Site2"
146+
147+
```
148+
149+
[!INCLUDE [More about CLI for Microsoft 365](../../docfx/includes/MORE-CLIM365.md)]
150+
35151
***
36152

37153
## Contributors
38154

39155
| Author(s) |
40156
|-----------|
41157
| [Valeras Narbutas](https://github.com/ValerasNarbutas)|
158+
| Adam Wójcik [@Adam-it](https://github.com/Adam-it)|
42159

43160
[!INCLUDE [DISCLAIMER](../../docfx/includes/DISCLAIMER.md)]
44-
<img src="https://m365-visitor-stats.azurewebsites.net/script-samples/scripts/spo-compare-files" aria-hidden="true" />
161+
<img src="https://m365-visitor-stats.azurewebsites.net/script-samples/scripts/spo-compare-files" aria-hidden="true" />
314 KB
Loading

scripts/spo-compare-files/assets/sample.json

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@
99
""
1010
],
1111
"creationDateTime": "2023-01-27",
12-
"updateDateTime": "2023-01-27",
12+
"updateDateTime": "2026-01-10",
1313
"products": [
1414
"SharePoint"
1515
],
1616
"metadata": [
1717
{
1818
"key": "PNP-POWERSHELL",
1919
"value": "1.5.0"
20+
},
21+
{
22+
"key": "CLI-FOR-MICROSOFT365",
23+
"value": "11.3.0"
2024
}
2125
],
2226
"categories": [
@@ -26,7 +30,10 @@
2630
"hash",
2731
"Connect-PnPOnline",
2832
"Get-PnPFile",
29-
"Get-FileHash"
33+
"Get-FileHash",
34+
"m365 login",
35+
"m365 spo file get",
36+
"m365 connection use"
3037
],
3138
"thumbnails": [
3239
{
@@ -42,13 +49,23 @@
4249
"company": "Macaw",
4350
"pictureUrl": "https://avatars.githubusercontent.com/u/16476453?v=4",
4451
"name": "Valeras Narbutas"
52+
},
53+
{
54+
"gitHubAccount": "Adam-it",
55+
"pictureUrl": "https://avatars.githubusercontent.com/u/58668583?v=4",
56+
"name": "Adam Wójcik"
4557
}
4658
],
4759
"references": [
4860
{
4961
"name": "Want to learn more about PnP PowerShell and the cmdlets",
5062
"description": "Check out the PnP PowerShell site to get started and for the reference to the cmdlets.",
5163
"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"
5269
}
5370
]
5471
}

0 commit comments

Comments
 (0)