Reputation: 21
I am working on a powershell module to interact with a REST API.
The API lists folder contents using the pattern '$Site/api/folders/'
for the root and '$Site/api/folders/$FolderID/contents'
for subfolders.
The function I've built below for listing contents based on a supplied folder name works for pulling a list of folders from the root, and if a $Folder
is specified and it is a child of the root it retrieves the contents by pulling the list of root folders, using FindIndex
to find the the ID for the folder of that name, and then making the REST call (lines 48-65).
My question is how could I possibly make this work for nested folders regardless of the number of levels? If a user specified '-Folder /myfolder/subfolder/morefolders/ilovefolders'
, how can I have it go through each of those to display the appropriate results?
Thanks in advance for any help, I'm relatively new at this and have been reading until my eyes hurt to make all this work right so far.
Function:
function Get-SiteDir {
[CmdletBinding()]
PARAM
(
[string]$Site,
[string]$Email,
[string]$Password,
[string]$Folder,
[string]$FolderID
)
If ($Site.Length -eq 0) {
Try {
$Site = (Get-ItemProperty -Path HKCU:\SOFTWARE\Company\Site\config).Site
}
Catch [System.Management.Automation.ItemNotFoundException] {
Write-Host -ForegroundColor Red "No Site specified. Either configure using Set-SiteConfig or pass a site URI with the -Site key."
}
Catch {
Write-Host -ForegroundColor Red "Something went wrong, please check your configuration and connection and try again."
}
}
If ($Email.Length -eq 0) {
Try {
$Email = (Get-ItemProperty -Path HKCU:\SOFTWARE\Company\Site\config).Email
}
Catch [System.Management.Automation.ItemNotFoundException] {
Write-Host -ForegroundColor Red "No site login e-mail specified. Either configure using Set-SiteConfig or pass a site URI with the -Email key."
}
Catch {
Write-Host -ForegroundColor Red "Something went wrong, please check your configuration and connection and try again."
}
}
If ($Password.Length -eq 0) {
Try {
$Password = (Get-ItemProperty -Path HKCU:\SOFTWARE\Company\Site\config).Password | ConvertFrom-SecureString
}
Catch [System.Management.Automation.ItemNotFoundException] {
Write-Host -ForegroundColor Red "No site login password specified. Either configure using Set-SiteConfig or pass a site URI with the -Password key."
}
Catch {
Write-Host -ForegroundColor Red "Something went wrong, please check your configuration and connection and try again."
}
}
If (!(Test-Path Variable:Global:$SiteSession) -or ($Global:SiteSession.Cookies.GetCookies("$Site/api/account/login").Expired -eq $true)) {
Write-Host "New-SiteSession -Site $Site -Email $Email -Password $Password"
}
$RootFolders = Invoke-RestMethod -Uri "$Site/api/folders/" -WebSession $Global:SiteSession
$RootFolderList = [Collections.Generic.List[Object]]($Folders)
If (($Folder.Length -eq 0) -And ($FolderID.Length -eq 0)) {
Return $RootFolders | Sort-Object -Property name | Select-Object -Property name, id, userPermissions | Format-Table -AutoSize
}
Else {
If ($Folder.Length -eq 0) {
$FolderContents = Invoke-RestMethod -Uri "$Site/api/folders/$FolderID/contents" -WebSession $Global:SiteSession
Return $FolderContents | Sort-Object -Property name | Select-Object -Property name, id, userPermissions | Format-Table -AutoSize
}
Else {
$RootFolderIndex = $FolderList.FindIndex( {$args[0].name -eq "$Folder"} )
$FolderId = $RootFolderList.id[$RootFolderIndex]
$FolderContents = Invoke-RestMethod -Uri "$Site/api/folders/$FolderID/contents" -WebSession $Global:SiteSession
Return $FolderContents | Sort-Object -Property name | Select-Object -Property name, id, userPermissions | Format-Table -AutoSize
}
}
}
Upvotes: 0
Views: 714
Reputation: 21
Well, I'm not sure if this is the most elegant or efficient way to accomplish it, but I was able to make it work. For anyone looking to accomplish something similar, the relevant part of the code is updated below. This will strip out any leading or tailing slashes, then count the number of slashes plus one to determine how many levels deep to crawl, and then loop through each folder to find its child ID.
$RootFolders = Invoke-RestMethod -Uri "$Site/api/folders/" -WebSession $Global:SiteSession
$RootFolderList = [Collections.Generic.List[Object]]($RootFolders)
If (([string]::IsNullOrWhiteSpace($Folder)) -And ([string]::IsNullOrWhiteSpace($FolderID))) {
Return $RootFolders | Sort-Object -Property name | Select-Object -Property name, id, userPermissions | Format-Table -AutoSize
}
Else {
If ([string]::IsNullOrWhiteSpace($Folder)) {
$FolderContents = Invoke-RestMethod -Uri "$Site/api/folders/$FolderID/contents" -WebSession $Global:SiteSession
Return $FolderContents | Sort-Object -Property name | Select-Object -Property name, id, userPermissions | Format-Table -AutoSize
}
Else {
$Folder = $Folder.Trim("\")
$FolderDepth = ([regex]::Matches($Folder, "\\")).count + 1
$FolderTree = $Folder -split '\\'
If ($FolderDepth -eq 1) {
$RootFolderIndex = $RootFolderList.FindIndex( {$args[0].name -eq "$Folder"} )
If ($RootFolderIndex -eq -1) {
Write-Error "A folder `"$Folder`" does not exist. Please check your spelling and try again." -ErrorAction Stop
}
$FolderId = $RootFolderList.id[$RootFolderIndex]
$FolderContents = Invoke-RestMethod -Uri "$Site/api/folders/$FolderID/contents" -WebSession $Global:SiteSession
Return $FolderContents | Sort-Object -Property name | Select-Object -Property name, id, userPermissions | Format-Table -AutoSize
}
Else {
for ($i=0; $i -lt $FolderDepth; $i++) {
If ($i -eq 0) {
$FolderIndex = $RootFolderList.FindIndex( {$args[0].name -eq $FolderTree[$i] } )
If ($FolderIndex -eq -1) {
Write-Error "A folder `"$Folder`" does not exist. Please check your spelling and try again." -ErrorAction Stop
}
$FolderId = $RootFolderList.id[$FolderIndex]
$FolderContents = Invoke-RestMethod -Uri "$Site/api/folders/$FolderID/contents" -WebSession $Global:SiteSession
$FolderList = [Collections.Generic.List[Object]]($FolderContents)
}
Else {
$FolderIndex = $FolderList.FindIndex( {$args[0].name -eq $FolderTree[$i]} )
If ($FolderIndex -eq -1) {
Write-Error "A folder `"$Folder`" does not exist. Please check your spelling and try again." -ErrorAction Stop
}
$FolderId = $FolderList.id[$FolderIndex]
$FolderContents = Invoke-RestMethod -Uri "$Site/api/folders/$FolderID/contents" -WebSession $Global:SiteSession
$FolderList = [Collections.Generic.List[Object]]($FolderContents)
}
}
Return $FolderContents | Sort-Object -Property name | Select-Object -Property name, id, userPermissions | Format-Table -AutoSize
}
}
}
Upvotes: 1