# In order to run script for SharePoint 2019 OnPremise set $SharePointVersion = "2019".
$SharePointVersion = "Online" #Possible options: Online, 2019
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
function New-Folder-Name( [Microsoft.SharePoint.Client.ListItem]$mainItem, [Microsoft.SharePoint.Client.ListItem]$folder ){
$newFolderName = $mainItem["Title"] + "-" + $mainItem.Id
#Replaces special symbols that are not allowed to be used in folder name
$newFolderName = $newFolderName -replace '[:*"?|%#<>\\/]|^~|(_vti_)|^(?:aux|con|clock\$|nul|prn|com[1-9]|lpt[1-9]|forms)$/gi', '_'
return $newFolderName
}
function Install-PnP-Module{
if($SharePointVersion -eq "Online"){
Write-Host "Checking for PnP.Powershell module..."
if (-not (Get-Module -ListAvailable -Name PnP.Powershell))
{
Write-Host "Installing PnP.Powershell module..."
Install-Module -Name PnP.Powershell -Scope CurrentUser -Repository PSGallery -AllowClobber
Write-Host "PnP.Powershell module has been installed"
}
else{
Write-Host "PnP.Powershell module is installed"
}
Import-Module -Name PnP.Powershell
}
else{
Write-Host "Checking for SharePointPnPPowerShell2019 module..."
if (-not (Get-Module -ListAvailable -Name SharePointPnPPowerShell2019))
{
Write-Host "Installing SharePointPnPPowerShell2019 module..."
Install-Module -Name SharePointPnPPowerShell2019 -Scope CurrentUser -Repository PSGallery -AllowClobber
Write-Host "SharePointPnPPowerShell2019 module has been installed"
}
else{
Write-Host "SharePointPnPPowerShell2019 module is installed"
}
Import-Module -Name SharePointPnPPowerShell2019
}
}
function Connect-SharePoint-Site{
$SiteURL = Read-Host 'Enter Site URL' # Site URL which contains main list and sub-library
Write-Host ("connecting to '"+$SiteURL+"' site")
if($SharePointVersion -eq "Online"){
$connection = Connect-PnPOnline -Url $SiteURL -ReturnConnection -Interactive -ForceAuthentication
}
else{
$cred = Get-Credential -Message "Enter credentials to SharePoint site"
$connection = Connect-PnPOnline -Url $SiteURL -ReturnConnection -Credentials $cred
}
if( !$connection ){
Write-Error -Message "Failed to connect to SharePoint site." -ErrorAction Continue
Read-Host -Prompt "Press Enter to quit..."
exit 0
}
}
function Process-Folders($folders){
$filterByIDs = $folders | ForEach-Object {''+$_[$LookupFieldName].LookupId+''}
$camlFilter = "
"+$filterByIDs+"
"
$mainitems = Get-PnPListItem -List $mainList.Id -Query $camlFilter
if($SharePointVersion -eq "Online"){
$batch = New-PnPBatch
foreach ($folder in $folders) {
[Microsoft.SharePoint.Client.ListItem]$mainItem = $mainitems | Where-Object -FilterScript { $_.Id -eq $folder[$LookupFieldName].LookupId }
if(!$mainitem){
Write-Error -Message ("Cannot load main item for '"+$folder.FileLeafRef+"' folder. Main Item ID: " + $folder[$LookupFieldName].LookupId ) -ErrorAction Continue
}
else{
[String]$folderName = New-Folder-Name -mainItem $mainItem -folder $folder
Write-Host $folder["FileLeafRef"] --> $folderName
Set-PnPListItem -List $lib.Id -Identity $folder.Id -Values @{ "FileLeafRef" = $folderName } -UpdateType SystemUpdate -Batch $batch
}
}
Invoke-PnPBatch -Batch $batch
}
else{
foreach ($folder in $folders) {
[Microsoft.SharePoint.Client.ListItem]$mainItem = $mainitems | Where-Object -FilterScript { $_.Id -eq $folder[$LookupFieldName].LookupId }
if(!$mainitem){
Write-Error -Message ("Cannot load main item for '"+$folder.FileLeafRef+"' folder. Main Item ID: " + $folder[$LookupFieldName].LookupId ) -ErrorAction Continue
}
else{
[String]$folderName = New-Folder-Name -mainItem $mainItem -folder $folder
Write-Host $folder["FileLeafRef"] --> $folderName
Set-PnPListItem -List $lib.Id -Identity $folder.Id -Values @{ "FileLeafRef" = $folderName }
}
}
}
}
#------------------------------------------------------------------------------------------------------------------------------------
Install-PnP-Module
Write-Host "-------------------------------------------------------------------" -ForegroundColor White
Connect-SharePoint-Site
$LibraryName = Read-Host "Enter sub-library ID or Name"
$lib = Get-PnPList -Identity $LibraryName
if( !$lib ){
Write-Error -Message "Cannot load the library." -ErrorAction Continue
Read-Host -Prompt "Press Enter to quit..."
exit 0
}
$LookupFieldName = Read-Host ("Enter Internal name of lookup column from '"+$lib.Title+"' library") # Lookup column in sub-library
$lookupfield = Get-PnPField -List $lib.Id -Identity $LookupFieldName
if( !$lookupfield ){
Write-Error -Message ("Cannot load find '"+$LookupFieldName+"' lookup column in '"+$lib.Title+"' the library.") -ErrorAction Continue
Read-Host -Prompt "Press Enter to quit..."
exit 0
}
[xml]$schemaXml=$lookupField.SchemaXml
$mainListId = $schemaXml.Field.Attributes["List"].Value
$mainList = Get-PnPList -Identity $mainListId
if( !$mainList ){
Write-Error -Message "Cannot load main list." -ErrorAction Continue
Read-Host -Prompt "Press Enter to quit..."
exit 0
}
Write-Host ("Loading main folders from '" + $lib.Title + "' library...")
$queryMainFolders= "
1
"
[Microsoft.SharePoint.Client.ListItem[]]$mainfolders = Get-PnPListItem -List $LibraryName -PageSize 500 -Query $queryMainFolders | Where-Object {$_[$LookupFieldName] -ne $null}
$choices = '&Yes', '&No'
$decision = $Host.UI.PromptForChoice('Confirmation', "'"+$lib.Title+" library contains "+$mainfolders.Count+" main folders. Are you sure you want to rename them?", $choices, 1)
if ($decision -eq 1) {
Write-Error -Message "The process has been cancelled." -ErrorAction Continue
Read-Host -Prompt "Press Enter to quit..."
exit 0
}
Write-Host "Renaming folders...."
$batchsize = 100;
$folderscount = $mainfolders.Count
$mainItemIDs = [System.Collections.ArrayList]::new()
for( $idx = 0; $idx -lt $folderscount / $batchsize; $idx++)
{
$idxStart = $idx * $batchsize
$idxEnd = [math]::Min( ($idx + 1 )*$batchsize - 1, $folderscount - 1 )
$folders = $mainfolders[$idxStart..$idxEnd]
Process-Folders -folders $folders
}
Write-Host "The process has been finished."
Read-Host -Prompt "Press Enter to quit..."
exit 0