From ef92eecfa77fd76ee3e5517f1e328beb9058fd3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3jcik?= Date: Mon, 17 Nov 2025 22:35:24 +0000 Subject: [PATCH 1/4] refactors script spo-add-dummy-folders-and-files --- .../spo-add-dummy-folders-and-files/README.md | 201 +++++++++++++----- .../assets/sample.json | 15 +- 2 files changed, 152 insertions(+), 64 deletions(-) diff --git a/scripts/spo-add-dummy-folders-and-files/README.md b/scripts/spo-add-dummy-folders-and-files/README.md index 488f0b43e..5f245bb65 100644 --- a/scripts/spo-add-dummy-folders-and-files/README.md +++ b/scripts/spo-add-dummy-folders-and-files/README.md @@ -84,74 +84,159 @@ Catch { # [CLI for Microsoft 365](#tab/cli-m365-ps) ```powershell -# SharePoint online site URL -$SiteURL = Read-Host -Prompt "Enter your SharePoint site URL (e.g https://contoso.sharepoint.com/sites/Company311)" +function Add-DummySharePointContent { + [CmdletBinding(SupportsShouldProcess)] + param( + [Parameter(Mandatory, HelpMessage = "URL of the SharePoint site (e.g. https://contoso.sharepoint.com/sites/Company311)")] + [ValidateNotNullOrEmpty()] + [string] + $SiteUrl, + + [Parameter(Mandatory, HelpMessage = "Site-relative URL of the document library (e.g. /Shared Documents)")] + [ValidateNotNullOrEmpty()] + [string] + $LibraryServerRelativeUrl, + + [Parameter(Mandatory, HelpMessage = "Path to the local seed file that will be uploaded")] + [ValidateScript({ Test-Path $_ -PathType Leaf })] + [string] + $LocalSeedFile, + + [Parameter(HelpMessage = "Number of folders to create")] + [ValidateRange(1, 2000)] + [int] + $FolderCount = 50, + + [Parameter(HelpMessage = "Number of files to create within each folder")] + [ValidateRange(1, 500)] + [int] + $FilesPerFolder = 10, + + [Parameter(HelpMessage = "Folder name prefix")] + [ValidateNotNullOrEmpty()] + [string] + $FolderPrefix = "Folder" + ) + + begin { + Write-Host "Ensuring Microsoft 365 CLI session..." -ForegroundColor Cyan + $loginOutput = m365 login --ensure 2>&1 + if ($LASTEXITCODE -ne 0) { + throw "Failed to ensure CLI login. CLI output: $loginOutput" + } -# Document library URL where you want to create the dummy folders and files -$LibraryName = Read-Host -Prompt "Enter site-relative URL of your Document library (e.g '/Shared Documents')" + $seedFile = Get-Item -LiteralPath $LocalSeedFile -ErrorAction Stop -# Location of the dummy file -$LocalFile= "D:\dtemp\TestDoc.docx" + $script:Summary = [ordered]@{ + FoldersRequested = $FolderCount + FilesRequested = $FolderCount * $FilesPerFolder + FoldersCreated = 0 + FoldersSkipped = 0 + FilesUploaded = 0 + FilesSkipped = 0 + Failures = 0 + } -# Number of files to create within each folder -$MaxFilesCount = 20 + $script:Report = New-Object System.Collections.Generic.List[object] + $script:ReportPath = Join-Path -Path (Get-Location) -ChildPath ("dummy-content-report-{0}.csv" -f (Get-Date -Format 'yyyyMMdd-HHmmss')) + } + + process { + for ($folderIndex = 1; $folderIndex -le $FolderCount; $folderIndex++) { + $folderName = "{0}_{1}" -f $FolderPrefix, $folderIndex + $folderDisplayPath = "$LibraryServerRelativeUrl/$folderName" + + if (-not $PSCmdlet.ShouldProcess($folderDisplayPath, "Create folder")) { + $script:Summary.FoldersSkipped++ + $script:Report.Add([pscustomobject]@{ + ItemType = 'Folder' + Name = $folderName + Path = $folderDisplayPath + Status = 'Skipped' + Note = 'WhatIf' + }) + continue + } -# Number of folders to create in the libraru -$MaxFolderCount = 500 + $folderOutput = m365 spo folder add --webUrl $SiteUrl --parentFolderUrl $LibraryServerRelativeUrl --name $folderName --output json 2>&1 + if ($LASTEXITCODE -ne 0) { + $script:Summary.Failures++ + Write-Warning "Failed to create folder '$folderName'. CLI output: $folderOutput" + } + else { + $script:Summary.FoldersCreated++ + } -# The name of the folder to be created -$FolderName = "Folder" + $script:Report.Add([pscustomobject]@{ + ItemType = 'Folder' + Name = $folderName + Path = $folderDisplayPath + Status = if ($LASTEXITCODE -eq 0) { 'Created' } else { 'Failed' } + Note = if ($LASTEXITCODE -eq 0) { '' } else { $folderOutput } + }) + + for ($fileIndex = 1; $fileIndex -le $FilesPerFolder; $fileIndex++) { + $newFileName = "{0}_{1}{2}" -f $seedFile.BaseName, $fileIndex, $seedFile.Extension + $targetFolder = "$LibraryServerRelativeUrl/$folderName" + + if (-not $PSCmdlet.ShouldProcess("$targetFolder/$newFileName", "Upload file")) { + $script:Summary.FilesSkipped++ + $script:Report.Add([pscustomobject]@{ + ItemType = 'File' + Name = $newFileName + Path = "$targetFolder/$newFileName" + Status = 'Skipped' + Note = 'WhatIf' + }) + continue + } -# Get Credentials to connect -$m365Status = m365 status -if ($m365Status -match "Logged Out") { - m365 login -} + $fileOutput = m365 spo file add --webUrl $SiteUrl --folder $targetFolder --path $seedFile.FullName --fileName $newFileName --output json 2>&1 + if ($LASTEXITCODE -ne 0) { + $script:Summary.Failures++ + Write-Warning "Failed to upload file '$newFileName'. CLI output: $fileOutput" + } + else { + $script:Summary.FilesUploaded++ + } -Try { - # Get the File from file server - $File = Get-ChildItem $LocalFile + $script:Report.Add([pscustomobject]@{ + ItemType = 'File' + Name = $newFileName + Path = "$targetFolder/$newFileName" + Status = if ($LASTEXITCODE -eq 0) { 'Uploaded' } else { 'Failed' } + Note = if ($LASTEXITCODE -eq 0) { '' } else { $fileOutput } + }) + } + } + } - # Initialize folder counter - $FolderCounter = 1 - - While($FolderCounter -le $MaxFolderCount) - { - $newFolderName = $FolderName + "_" + $FolderCounter - Try { - # Add new folder in the library - m365 spo folder add --webUrl $SiteURL --parentFolderUrl $LibraryName --name $newFolderName - Write-Host -f Green "New Folder '$newFolderName' Created ($FolderCounter of $MaxFolderCount)!" - - # Initialize file counter - $FileCounter = 1 - - While($FileCounter -le $MaxFilesCount) - { - $NewFileName = $File.BaseName + "_" + $FileCounter + ".docx" - Try { - # Add new file in the folder - m365 spo file add --webUrl $SiteURL --folder "$($LibraryName)/$newFolderName" --path $File --FileLeafRef $NewFileName - } - Catch { - Write-Host "Error while creating a new file: $($_.Exception.Message)" -ForegroundColor Red - } - Write-Host -f Green "New File '$NewFileName' Created ($FileCounter of $MaxFilesCount)!" - $FileCounter++ - } - } - Catch { - Write-Host "Error while creating a new folder: $($_.Exception.Message)" -ForegroundColor Red - } - $FolderCounter++; - } -} -Catch { - write-host -f Red "Error Uploading File:"$_.Exception.Message + end { + try { + $script:Report | Export-Csv -Path $script:ReportPath -NoTypeInformation -Encoding UTF8 + Write-Host "Report saved to $($script:ReportPath)." -ForegroundColor Green + } + catch { + $script:Summary.Failures++ + Write-Error "Failed to write report: $($_.Exception.Message)" + } + + Write-Host "----- Summary -----" -ForegroundColor Cyan + Write-Host "Folders requested : $($script:Summary.FoldersRequested)" + Write-Host "Folders created : $($script:Summary.FoldersCreated)" + Write-Host "Folders skipped : $($script:Summary.FoldersSkipped)" + Write-Host "Files requested : $($script:Summary.FilesRequested)" + Write-Host "Files uploaded : $($script:Summary.FilesUploaded)" + Write-Host "Files skipped : $($script:Summary.FilesSkipped)" + Write-Host "Failures : $($script:Summary.Failures)" + + if ($script:Summary.Failures -gt 0) { + Write-Warning "Some operations failed. Review the report for details." + } + } } -# Disconnect SharePoint online connection -m365 logout +Add-DummySharePointContent -SiteUrl "https://contoso.sharepoint.com/sites/Company311" -LibraryServerRelativeUrl "/Shared Documents" -LocalSeedFile "D:\dtemp\TestDoc.docx" -FolderCount 100 -FilesPerFolder 10 ``` [!INCLUDE [More about CLI for Microsoft 365](../../docfx/includes/MORE-CLIM365.md)] diff --git a/scripts/spo-add-dummy-folders-and-files/assets/sample.json b/scripts/spo-add-dummy-folders-and-files/assets/sample.json index b45082066..6737c5ee7 100644 --- a/scripts/spo-add-dummy-folders-and-files/assets/sample.json +++ b/scripts/spo-add-dummy-folders-and-files/assets/sample.json @@ -9,7 +9,7 @@ "This sample shows how to add dummy folders and files into a SharePoint document library. The script was used to generate files within folders to perform some testing." ], "creationDateTime": "2022-11-13", - "updateDateTime": "2024-01-24", + "updateDateTime": "2025-11-16", "products": [ "SharePoint" ], @@ -19,8 +19,8 @@ "value": "1.12.0" }, { - "key":"CLI-FOR-MICROSOFT365", - "value":"7.3.0" + "key": "CLI-FOR-MICROSOFT365", + "value": "11.0.0" } ], "categories": [ @@ -32,11 +32,9 @@ "Connect-PnPOnline", "Add-PnPFolder", "Add-PnPFile", - "m365 status", "m365 login", "m365 spo folder add", "m365 spo file add", - "m365 logout", "Get-ChildItem" ], "thumbnails": [ @@ -59,6 +57,11 @@ "gitHubAccount": "reshmee011", "company": "PPF", "pictureUrl": "https://avatars.githubusercontent.com/u/7693852?v=4" + }, + { + "gitHubAccount": "Adam-it", + "pictureUrl": "https://avatars.githubusercontent.com/u/37133813?v=4", + "name": "Adam Wójcik" } ], "references": [ @@ -74,4 +77,4 @@ } ] } -] \ No newline at end of file +] From ff281c904edfce19c287418a2ede74289a658053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3jcik?= <58668583+Adam-it@users.noreply.github.com> Date: Mon, 8 Dec 2025 00:01:23 +0100 Subject: [PATCH 2/4] Apply suggestion from @Adam-it --- scripts/spo-add-dummy-folders-and-files/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/spo-add-dummy-folders-and-files/README.md b/scripts/spo-add-dummy-folders-and-files/README.md index 5f245bb65..06bda26aa 100644 --- a/scripts/spo-add-dummy-folders-and-files/README.md +++ b/scripts/spo-add-dummy-folders-and-files/README.md @@ -249,6 +249,9 @@ Add-DummySharePointContent -SiteUrl "https://contoso.sharepoint.com/sites/Compan |-----------| | [Reshmee Auckloo](https://github.com/reshmee011)| | [Ganesh Sanap](https://ganeshsanapblogs.wordpress.com/about) | +| [Reshmee Auckloo](https://github.com/reshmee011)| +| [Ganesh Sanap](https://ganeshsanapblogs.wordpress.com/about) | +| Adam Wójcik | [!INCLUDE [DISCLAIMER](../../docfx/includes/DISCLAIMER.md)] From a1f4aed62aba5b1fe7d28fa177e01ac09ab31fa4 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Sat, 13 Dec 2025 15:55:14 +0000 Subject: [PATCH 3/4] Fixed adam picture --- scripts/spo-add-dummy-folders-and-files/assets/sample.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/spo-add-dummy-folders-and-files/assets/sample.json b/scripts/spo-add-dummy-folders-and-files/assets/sample.json index 6737c5ee7..7e4924a18 100644 --- a/scripts/spo-add-dummy-folders-and-files/assets/sample.json +++ b/scripts/spo-add-dummy-folders-and-files/assets/sample.json @@ -60,7 +60,7 @@ }, { "gitHubAccount": "Adam-it", - "pictureUrl": "https://avatars.githubusercontent.com/u/37133813?v=4", + "pictureUrl": "https://github.com/Adam-it.png", "name": "Adam Wójcik" } ], From f8b53fc77d722355c85134ce5972875fd1191e4f Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Sat, 13 Dec 2025 15:55:32 +0000 Subject: [PATCH 4/4] Dedup the contributors. --- scripts/spo-add-dummy-folders-and-files/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/spo-add-dummy-folders-and-files/README.md b/scripts/spo-add-dummy-folders-and-files/README.md index 06bda26aa..e2c3d8aec 100644 --- a/scripts/spo-add-dummy-folders-and-files/README.md +++ b/scripts/spo-add-dummy-folders-and-files/README.md @@ -249,8 +249,6 @@ Add-DummySharePointContent -SiteUrl "https://contoso.sharepoint.com/sites/Compan |-----------| | [Reshmee Auckloo](https://github.com/reshmee011)| | [Ganesh Sanap](https://ganeshsanapblogs.wordpress.com/about) | -| [Reshmee Auckloo](https://github.com/reshmee011)| -| [Ganesh Sanap](https://ganeshsanapblogs.wordpress.com/about) | | Adam Wójcik | [!INCLUDE [DISCLAIMER](../../docfx/includes/DISCLAIMER.md)]