Powershell 模块 - 如何基于输入递归地进行 Invoke-RestMethod 调用

Powershell Module - How to recursively make Invoke-RestMethod Calls based on Input

我正在开发一个与 REST 交互的 powershell 模块 API。

API 列出文件夹内容,根目录使用 '$Site/api/folders/' 模式,子文件夹使用 '$Site/api/folders/$FolderID/contents' 模式。

我在下面构建的用于根据提供的文件夹名称列出内容的函数适用于从根目录中提取文件夹列表,如果指定了 $Folder 并且它是根目录的子目录它通过拉取根文件夹列表来检索内容,使用 FindIndex 查找该名称文件夹的 ID,然后进行 REST 调用(第 48-65 行)。

我的问题是,无论层级数如何,我如何才能使它适用于嵌套文件夹?如果用户指定了 '-Folder /myfolder/subfolder/morefolders/ilovefolders',我如何让它遍历每一个以显示适当的结果?

在此先感谢您的帮助,我在这方面相对较新,一直在阅读直到我的眼睛受伤才能使所有这些工作顺利进行。

函数:

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
        }
    }
}

好吧,我不确定这是否是完成它的最优雅或最有效的方法,但我能够让它发挥作用。对于任何想要完成类似事情的人,代码的相关部分在下面更新。这将去除任何前导或尾部斜杠,然后计算斜杠的数量加一以确定要爬网的深度级别,然后遍历每个文件夹以找到其子 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
        }
    }
}