Pipeline/ReleaseManagement/Folder/Pipeline_ReleaseManagement_Folder.ps1

Function Get-TfsReleaseDefinitionFolder
{
    [CmdletBinding()]
    [OutputType('Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Folder')]
    Param
    (
        # Specifies the folder path
        [Parameter(Position=0)]
        [Alias('Path')]
        [SupportsWildcards()]
        [object]
        $Folder = '**',

        # Query order
        [Parameter()]
        [Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.FolderPathQueryOrder]
        $QueryOrder = [Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.FolderPathQueryOrder]::None,

        [Parameter(ValueFromPipeline=$true)]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )
    
    Process
    {
        if ($Folder -is [Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Folder]) { _Log "Input item is of type Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Folder; returning input item immediately, without further processing."; return $Folder }

        $tp = Get-TfsTeamProject -Project $Project -Collection $Collection; if (-not $tp -or ($tp.Count -ne 1)) {throw "Invalid or non-existent team project $Project."}; $tpc = $tp.Store.TeamProjectCollection

        $client = _GetRestClient 'Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Clients.ReleaseHttpClient' -Collection $tpc

        if(_IsWildCard $Folder)
        {
            $task = $client.GetFoldersAsync($tp.Name, '\', $QueryOrder); $result = $task.Result; if($task.IsFaulted) { _throw  $task.Exception.InnerExceptions }
            $result = $result | Where-Object { ($_.Path -Like $Folder) -or ($_.Name -like $Folder) }
        }
        else
        {
            $task = $client.GetFoldersAsync($tp.Name, "\$($Folder.Trim('\'))", $QueryOrder); $result = $task.Result; if($task.IsFaulted) { _throw  "Error fetching build folders" $task.Exception.InnerExceptions }
        }
        
        return $result | Add-Member -Name Project -MemberType NoteProperty -PassThru -Value (New-Object 'Microsoft.TeamFoundation.Core.WebApi.TeamProjectReference' -Property @{
            Name = $tp.Name
        })
    }
}
Function New-TfsReleaseDefinitionFolder
{
    [CmdletBinding(ConfirmImpact='Medium', SupportsShouldProcess=$true)]
    [OutputType('Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Folder')]
    Param
    (
        # Specifies the folder path
        [Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [Alias('Path')]
        [object]
        $Folder,

        # Description of the new release folder
        [Parameter()]
        [string]
        $Description,

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection,

        [Parameter()]
        [switch]
        $Passthru
    )
    
    Process
    {
        $tp = Get-TfsTeamProject -Project $Project -Collection $Collection; if (-not $tp -or ($tp.Count -ne 1)) {throw "Invalid or non-existent team project $Project."}; $tpc = $tp.Store.TeamProjectCollection

        if(-not $PSCmdlet.ShouldProcess($tp.Name, "Create release folder '$Folder'"))
        {
            return
        }

        $client = _GetRestClient 'Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Clients.ReleaseHttpClient' -Collection $tpc

        $newFolder = New-Object 'Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Folder' -Property @{
            Description = $Description
            Path = "\$($Folder.ToString().Trim('\'))"
        }

        $task = $client.CreateFolderAsync($newFolder, $tp.Name); $result = $task.Result; if($task.IsFaulted) { _throw  "Error creating folder '$Folder'" $task.Exception.InnerExceptions }

        if($Passthru)
        {
            return $result
        }
    }
}
Function Remove-TfsReleaseDefinitionFolder
{
    [CmdletBinding(ConfirmImpact='High', SupportsShouldProcess=$true)]
    [OutputType('Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Folder')]
    Param
    (
        # Specifies the folder path
        [Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [Alias('Path')]
        [SupportsWildcards()]
        [object]
        $Folder,

        # Remove folders recursively
        [Parameter()]
        [switch]
        $Recurse,

        # Remove folder containing Releases
        [Parameter()]
        [switch]
        $Force,

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )
    
    Process
    {
        $folders = Get-TfsReleaseDefinitionFolder -Folder $Folder -Project $Project -Collection $Collection

        foreach($f in $folders)
        {
            if(-not $PSCmdlet.ShouldProcess($f.Project.Name, "Remove folder '$($f.Path)'"))
            {
                continue
            }

            if(-not $Recurse.IsPresent)
            {
                _Log "Recurse argument not set. Check if folder '$($f.Path)' has sub-folders"

                $path = "$($f.Path.TrimEnd('\'))\**"
                $subFolders = (Get-TfsReleaseDefinitionFolder -Folder $path -Project $Project -Collection $Collection)

                if($subFolders.Count -gt 0)
                {
                    _throw "Folder '$($f.Path)' has $($subFolders.Count) sub-folder(s). To delete it, use the -Recurse argument."
                }

                _Log "Folder '$($f.Path)' has no sub-folders"
            }

            if($f.Project.Name) {$Project = $f.Project.Name}; $tp = Get-TfsTeamProject -Project $Project -Collection $Collection; if (-not $tp -or ($tp.Count -ne 1)) {throw "Invalid or non-existent team project $Project."}; $tpc = $tp.Store.TeamProjectCollection

            $client = _GetRestClient 'Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Clients.ReleaseHttpClient' -Collection $tpc

            if(-not $Force.IsPresent)
            {
                _Log "Force argument not set. Check if folder '$($f.Path)' has release definitions"

                $task = $client.GetReleaseDefinitionsAsync($tp.Name, [string]$null, [Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Contracts.ReleaseDefinitionExpands]::None, [string]$null, $null, $null, $null, $null, $f.Path); $result = $task.Result; if($task.IsFaulted) { _throw  "Error fetching release definitions in folder '$($f.Path)'" $task.Exception.InnerExceptions }

                if($result.Count -gt 0)
                {
                    _throw "Folder '$($f.Path)' has $($result.Count) release definition(s). To delete it, use the -Force argument."
                }

                _Log "Folder '$($f.Path)' has no release definitions"
            }

            $task = $client.DeleteFolderAsync($tp.Name, $f.Path); $result = $task.Result; if($task.IsFaulted) { _throw  $task.Exception.InnerExceptions }
        }
    }
}