# 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