Reputation: 379
I am using the SSRS PowerShell cmdlets to move over all of our SSRS reports to a new server. Right now I'm trying to recreate the file hierarchy that already exists on the reporting server in our new one.
In order to do this, I am recursing through a local copy of the report folders that I created on my PC. Using the New-RsFolder
function I am able to create the first level of folders, but the script starts to fail once it gets to any sort of sub directory.
Import-Module ReportingServicesTools
$ReportPath = 'C:\MyFiles\SSRS 2016 Upgrade\Reporting Server\'
$Folders = Get-ChildItem $ReportPath -Recurse -Directory
foreach($Folder in $Folders){
$SubFolderPath = ''
$arrSubFolders = $Folder.FullName.Replace($ReportPath, '').Split('\')
foreach($SubFolder in $arrSubFolders){
$SubFolderPath += '/'
try{
New-RsFolder -ReportServerUri $ReportServerURI -FolderName $SubFolder -RsFolder $SubFolderPath
Write-Host "Created folder $($SubFolderPath)/$($SubFolder)"
}
catch{
Write-Host "Folder $($SubFolderPath)/$($SubFolder) exists"
}
$SubFolderPath += $SubFolder
}
}
As soon as I get back around to accounting the script starts to catch that the folder exists already, as indicated here:
Created folder //Accounting
Created folder //Customer Service
Created folder //Dashlets
Created folder //Data Sources
Created folder //DataSets
Created folder //Forms
Created folder //Human Resources
Created folder //Information Technology
Created folder //Integrated
Created folder //Maintenance
Created folder //Management
Created folder //Old Reports
Created folder //Operations
Created folder //Owner Operator Settlements
Created folder //Report Parts
Created folder //Safety and Recruiting
Folder //Accounting exists
Folder /Accounting//PnG Proposal and Payment exists
Folder //Accounting exists
Folder /Accounting//PTI Logistics exists
Folder //Accounting exists
Folder /Accounting//Settlements exists
Folder //Accounting exists
Folder /Accounting//XRS exists
Folder //Accounting exists
Folder /Accounting//PTI Logistics exists
Folder /Accounting/PTI Logistics//PTI Logistics - Settlements exists
Folder //Accounting exists
Folder /Accounting//PTI Logistics exists
Folder /Accounting/PTI Logistics//PTI Logistics - Settlements exists
Folder /Accounting/PTI Logistics/PTI Logistics - Settlements//Drill-Through exists
Folder //Accounting exists
Folder /Accounting//Settlements exists
Folder /Accounting/Settlements//Drill-Through exists
Folder //Accounting exists
Folder /Accounting//Settlements exists
Folder /Accounting/Settlements//TMW Templates exists
Folder //Customer Service exists
Recursion was never my strong suit so if someone could shed some light on this I would appreciate it.
Upvotes: 3
Views: 2942
Reputation: 438273
Get-ChildItem -Recurse
enumerates the targeted directory tree with parent paths coming before their descendants.
Additionally, you can use the -Name
switch in order to output the directories' path strings, relative to the target directory.
That means that you can focus on just creating each folder one by one, relying on its ancestral path to have preexisted (in the case of /
) or to have been created in a previous iteration:
Import-Module ReportingServicesTools
$ReportPath = 'C:\MyFiles\SSRS 2016 Upgrade\Reporting Server'
Get-ChildItem $ReportPath -Recurse -Directory -Name | ForEach-Object {
# Split the relative input path into leaf (directory name)
# and parent path, and convert the parent path to the target parent path
# by prepending "/" and converting path-internal "\" instances to "/".
$SubFolderParentPath = '/' + ((Split-Path -Parent $_) -replace '\\', '/') #'
$SubFolderName = Split-Path -Leaf $_
try{
New-RsFolder -ReportServerUri $ReportServerURI -Path $SubFolderParentPath -FolderName $SubFolderName
Write-Host "Created folder ${SubFolderPath}/${SubFolder}"
}
catch {
# Report the specific error that occurred, accessible via $_
Write-Host "An error occurred for ${SubFolderPath}/${SubFolder}: $_"
}
}
This approach is not only more efficient than yours, it also avoids the attempts to create ancestral paths multiple times.
Note:
-Path
rather than -RsFolder
is used, because the version of New-RsFolder
available in the PowerShell Gallery as part of the ReportingServices
module only supports -Path
for specifying the target location (folder).
The catch
block now reports the actual error ($_
) that occurred, because the specific problem may something other than a preexisting folder.
Be sure to start the target path passed to -Path
with /
.
Upvotes: 3