Pipeline/Build/Folder/Pipeline_Build_Folder.ps1

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

        # Query order
        [Parameter()]
        [Microsoft.TeamFoundation.Build.WebApi.FolderQueryOrder]
        $QueryOrder = [Microsoft.TeamFoundation.Build.WebApi.FolderQueryOrder]::None,

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

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

        if($Folder.Project.Name) {$Project = $Folder.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.TeamFoundation.Build.WebApi.BuildHttpClient' -Collection $tpc

        if(_IsWildCard $Folder)
        {
            $task = $client.GetFoldersAsync($tp.Name, '\', $QueryOrder); $result = $task.Result; if($task.IsFaulted) { _throw  $task.Exception.InnerExceptions }
            return $result | Where-Object { ($_.Path -Like $Folder) -or ($_.Name -like $Folder) }
        }

        
        $task = $client.GetFoldersAsync($tp.Name, "\$($Folder.Trim('\'))", $QueryOrder); $result = $task.Result; if($task.IsFaulted) { _throw  "Error fetching build folders" $task.Exception.InnerExceptions }
        
        return $result
    }
}
Function New-TfsBuildDefinitionFolder
{
    [CmdletBinding(ConfirmImpact='Medium', SupportsShouldProcess=$true)]
    [OutputType('Microsoft.TeamFoundation.Build.WebApi.Folder')]
    Param
    (
        # Specifies the folder path
        [Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [Alias('Path')]
        [object]
        $Folder,

        # Description of the new build 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 build folder '$Folder'"))
        {
            return
        }

        $client = _GetRestClient 'Microsoft.TeamFoundation.Build.WebApi.BuildHttpClient' -Collection $tpc

        $newFolder = New-Object 'Microsoft.TeamFoundation.Build.WebApi.Folder' -Property @{
            Description = $Description
        }

        $Folder = $Folder.ToString().Trim('\')

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

        if($Passthru)
        {
            return $result
        }
    }
}
Function Remove-TfsBuildDefinitionFolder
{
    [CmdletBinding(ConfirmImpact='High', SupportsShouldProcess=$true)]
    [OutputType('Microsoft.TeamFoundation.Build.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 builds
        [Parameter()]
        [switch]
        $Force,

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )
    
    Process
    {
        $folders = Get-TfsBuildFolder -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-TfsBuildFolder -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.TeamFoundation.Build.WebApi.BuildHttpClient' -Collection $tpc

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

                $task = $client.GetDefinitionsAsync2($tp.Name, [string]$null, [string]$null, [string]$null, [Microsoft.TeamFoundation.Build.WebApi.DefinitionQueryOrder]::None, $null, $null, $null, $null, $f.Path); $result = $task.Result; if($task.IsFaulted) { _throw  "Error fetching build definitions in folder '$($f.Path)'" $task.Exception.InnerExceptions }

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

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

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