Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 146 additions & 58 deletions scripts/spo-add-dummy-folders-and-files/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -164,6 +249,9 @@ m365 logout
|-----------|
| [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)]

Expand Down
15 changes: 9 additions & 6 deletions scripts/spo-add-dummy-folders-and-files/assets/sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
],
Expand All @@ -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": [
Expand All @@ -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": [
Expand All @@ -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": [
Expand All @@ -74,4 +77,4 @@
}
]
}
]
]