AreaIteration/AreaIteration.psm1

<#
.SYNOPSIS
    Gets one or more Areas ("Area Paths") from a given Team Project.

.PARAMETER Area
    
    Specifies the name, URI or path of an Area. Wildcards are permitted. If omitted, all Areas in the given Team Project are returned.

    To supply a path, use a backslash ("\") between the path segments. Leading and trailing backslashes are optional.

    When supplying a URI, use URIs in the form of "vstfs:///Classification/Node/<GUID>" (where <GUID> is the unique identifier of the given node)


.PARAMETER Project
    
    Specifies either the name of the Team Project or a previously initialized Microsoft.TeamFoundation.WorkItemTracking.Client.Project object to connect to. If omitted, it defaults to the connection opened by Connect-TfsTeamProject (if any).

    For more details, see the Get-TfsTeamProject cmdlet.


.PARAMETER Collection
    
    Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object.

    When using a URL, it must be fully qualified. The format of this string is as follows:

    http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName>

    Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS.

    To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet.

    For more details, see the Get-TfsTeamProjectCollection cmdlet.


#>

Function Get-TfsArea
{
    [CmdletBinding()]
    [OutputType([Microsoft.TeamFoundation.Server.NodeInfo])]
    Param
    (
        [Parameter(Position=0)]
        [Alias("Path")]
        [ValidateScript({($_ -is [string]) -or ($_ -is [uri]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [SupportsWildcards()]
        [object]
        $Area = '\**',

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

        [Parameter()]
        [object]
        $Collection
    )

    Process
    {
        return _GetCssNodes -Node $Area -Scope Area -Project $Project -Collection $Collection
    }
}
<#
.SYNOPSIS
    Gets one or more Iterations ("Iteration Paths") from a given Team Project.

.PARAMETER Iteration
    
    Specifies the name, URI or path of an Iteration. Wildcards are permitted. If omitted, all Iterations in the given Team Project are returned.

    To supply a path, use a backslash ("\") between the path segments. Leading and trailing backslashes are optional.

    When supplying a URI, use URIs in the form of "vstfs:///Classification/Node/<GUID>" (where <GUID> is the unique identifier of the given node)


.PARAMETER Project
    
    Specifies either the name of the Team Project or a previously initialized Microsoft.TeamFoundation.WorkItemTracking.Client.Project object to connect to. If omitted, it defaults to the connection opened by Connect-TfsTeamProject (if any).

    For more details, see the Get-TfsTeamProject cmdlet.


.PARAMETER Collection
    
    Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object.

    When using a URL, it must be fully qualified. The format of this string is as follows:

    http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName>

    Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS.

    To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet.

    For more details, see the Get-TfsTeamProjectCollection cmdlet.


#>

Function Get-TfsIteration
{
    [CmdletBinding()]
    [OutputType([Microsoft.TeamFoundation.Server.NodeInfo])]
    Param
    (
        [Parameter(Position=0)]
        [Alias("Path")]
        [ValidateScript({($_ -is [string]) -or ($_ -is [uri]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [SupportsWildcards()]
        [object]
        $Iteration = '\**',

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

        [Parameter()]
        [object]
        $Collection
    )

    Process
    {
        return _GetCssNodes -Node $Iteration -Scope Iteration -Project $Project -Collection $Collection
    }
}
<#
.SYNOPSIS
    Moves an Area from its parent area to another one in the same Team Project.

.PARAMETER Area
    
    Specifies the name, URI or path of an Area. Wildcards are permitted. If omitted, all Areas in the given Team Project are returned.

    To supply a path, use a backslash ("\") between the path segments. Leading and trailing backslashes are optional.

    When supplying a URI, use URIs in the form of "vstfs:///Classification/Node/<GUID>" (where <GUID> is the unique identifier of the given node)


.PARAMETER Project
    
    Specifies either the name of the Team Project or a previously initialized Microsoft.TeamFoundation.WorkItemTracking.Client.Project object to connect to. If omitted, it defaults to the connection opened by Connect-TfsTeamProject (if any).

    For more details, see the Get-TfsTeamProject cmdlet.


.PARAMETER Collection
    
    Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object.

    When using a URL, it must be fully qualified. The format of this string is as follows:

    http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName>

    Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS.

    To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet.

    For more details, see the Get-TfsTeamProjectCollection cmdlet.


#>

Function Move-TfsArea
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [Alias("Path")]
        [ValidateScript({($_ -is [string]) -or ($_ -is [uri]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [object]
        $Area,

        [Parameter(Position=1l)]
        [ValidateScript({($_ -is [string]) -or ($_ -is [uri]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [object]
        $Destination,

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )

    Process
    {
        $node = Get-TfsArea -Area $Area -Project $Project -Collection $Collection

        if (-not $node)
        {
            throw "Invalid or non-existent area $Area"
        }

        $destinationNode = Get-TfsArea -Area $Destination -Project $Project -Collection $Collection

        if (-not $node)
        {
            throw "Invalid or non-existent destination area $Destination"
        }

        $cssService = _GetCssService -Project $Project -Collection $Collection

        $cssService.MoveBranch($node.Uri, $destinationNode.Uri)

        return $cssService.GetNode($node.Uri)
    }
}
<#
.SYNOPSIS
    Moves an Iteration from its parent iteration to another one in the same Team Project.

.PARAMETER Iteration
    
    Specifies the name, URI or path of an Iteration. Wildcards are permitted. If omitted, all Iterations in the given Team Project are returned.

    To supply a path, use a backslash ("\") between the path segments. Leading and trailing backslashes are optional.

    When supplying a URI, use URIs in the form of "vstfs:///Classification/Node/<GUID>" (where <GUID> is the unique identifier of the given node)


.PARAMETER Project
    
    Specifies either the name of the Team Project or a previously initialized Microsoft.TeamFoundation.WorkItemTracking.Client.Project object to connect to. If omitted, it defaults to the connection opened by Connect-TfsTeamProject (if any).

    For more details, see the Get-TfsTeamProject cmdlet.


.PARAMETER Collection
    
    Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object.

    When using a URL, it must be fully qualified. The format of this string is as follows:

    http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName>

    Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS.

    To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet.

    For more details, see the Get-TfsTeamProjectCollection cmdlet.


#>

Function Move-TfsIteration
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [Alias("Path")]
        [ValidateScript({($_ -is [string]) -or ($_ -is [uri]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [object]
        $Iteration,

        [Parameter(Position=1)]
        [ValidateScript({($_ -is [string]) -or ($_ -is [uri]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [object]
        $Destination,

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )

    Process
    {
        $node = Get-TfsIteration -Iteration $Iteration -Project $Project -Collection $Collection

        if (-not $node)
        {
            throw "Invalid or non-existent iteration $Iteration"
        }

        $destinationNode = Get-TfsIteration -Iteration $Destination -Project $Project -Collection $Collection

        if (-not $node)
        {
            throw "Invalid or non-existent destination iteration $Destination"
        }

        $cssService = _GetCssService -Project $Project -Collection $Collection

        $cssService.MoveBranch($node.Uri, $destinationNode.Uri)

        return $cssService.GetNode($node.Uri)
    }
}
<#
.SYNOPSIS
    Create a new Area ("Area Path") in the given Team Project.

.PARAMETER Area
    Specifies the path of the new Area.
    When supplying a path, use a backslash ("\") between the path segments. Leading and trailing backslashes are optional. The last segment in the path will be the area name.

.PARAMETER Project
    
    Specifies either the name of the Team Project or a previously initialized Microsoft.TeamFoundation.WorkItemTracking.Client.Project object to connect to. If omitted, it defaults to the connection opened by Connect-TfsTeamProject (if any).

    For more details, see the Get-TfsTeamProject cmdlet.


.PARAMETER Collection
    
    Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object.

    When using a URL, it must be fully qualified. The format of this string is as follows:

    http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName>

    Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS.

    To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet.

    For more details, see the Get-TfsTeamProjectCollection cmdlet.


#>

Function New-TfsArea
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true, Position=0)]
        [Alias("Path")]
        [string]
        $Area,

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )

    Process
    {
        return _NewCssNode -Path $Area -Scope Area -Project $Project -Collection $Collection
    }
}
<#

.SYNOPSIS
    Create a new Iteration ("Iteration Path") in the given Team Project.

.PARAMETER Area
    Specifies the path of the new Iteration.
    When supplying a path, use a backslash ("\") between the path segments. Leading and trailing backslashes are optional. The last segment in the path will be the iteration name.

.PARAMETER Project
    
    Specifies either the name of the Team Project or a previously initialized Microsoft.TeamFoundation.WorkItemTracking.Client.Project object to connect to. If omitted, it defaults to the connection opened by Connect-TfsTeamProject (if any).

    For more details, see the Get-TfsTeamProject cmdlet.


.PARAMETER Collection
    
    Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object.

    When using a URL, it must be fully qualified. The format of this string is as follows:

    http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName>

    Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS.

    To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet.

    For more details, see the Get-TfsTeamProjectCollection cmdlet.


#>

Function New-TfsIteration
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true, Position=0)]
        [ValidateScript({($_ -is [string]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [Alias("Path")]
        [object]
        $Iteration,

        [Parameter()]
        [DateTime]
        $StartDate,
    
        [Parameter()]
        [DateTime]
        $FinishDate,

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )

    Process
    {
        return _NewCssNode -Path $Iteration -Scope Iteration -Project $Project -Collection $Collection -StartDate $StartDate -FinishDate $FinishDate
    }
}
<#
.SYNOPSIS
    Deletes one or more Areas ("Area Path").

.PARAMETER Area
    
    Specifies the name, URI or path of an Area. Wildcards are permitted. If omitted, all Areas in the given Team Project are returned.

    To supply a path, use a backslash ("\") between the path segments. Leading and trailing backslashes are optional.

    When supplying a URI, use URIs in the form of "vstfs:///Classification/Node/<GUID>" (where <GUID> is the unique identifier of the given node)


.PARAMETER Project
    
    Specifies either the name of the Team Project or a previously initialized Microsoft.TeamFoundation.WorkItemTracking.Client.Project object to connect to. If omitted, it defaults to the connection opened by Connect-TfsTeamProject (if any).

    For more details, see the Get-TfsTeamProject cmdlet.


.PARAMETER Collection
    
    Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object.

    When using a URL, it must be fully qualified. The format of this string is as follows:

    http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName>

    Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS.

    To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet.

    For more details, see the Get-TfsTeamProjectCollection cmdlet.


#>

Function Remove-TfsArea
{
    [CmdletBinding(ConfirmImpact='High', SupportsShouldProcess=$true)]
    Param
    (
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [Alias("Path")]
        [ValidateScript({($_ -is [string]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [object]
        $Area,

        [Parameter(Position=1)]
        [Alias("NewPath")]
        [ValidateScript({ ($_ -is [string]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo]) })] 
        [object]
        $MoveTo = '\',

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )

    Process
    {
        $Areas = Get-TfsArea -Area $Area -Project $Project -Collection $Collection | Sort -Property Path -Descending

        foreach($i in $Areas)
        {
            if ($PSCmdlet.ShouldProcess($i.RelativePath, "Delete Area"))
            {
                $projectName = $i.Path.Split("\")[1]
                _DeleteCssNode -Node $i -MoveToNode $MoveTo -Scope Area -Project $projectName -Collection $Collection
            }
        }
    }
}
<#
.SYNOPSIS
    Deletes one or more Iterations ("Iteration Paths").

.PARAMETER Area
    
    Specifies the name, URI or path of an Iteration. Wildcards are permitted. If omitted, all Iterations in the given Team Project are returned.

    To supply a path, use a backslash ("\") between the path segments. Leading and trailing backslashes are optional.

    When supplying a URI, use URIs in the form of "vstfs:///Classification/Node/<GUID>" (where <GUID> is the unique identifier of the given node)


.PARAMETER Project
    
    Specifies either the name of the Team Project or a previously initialized Microsoft.TeamFoundation.WorkItemTracking.Client.Project object to connect to. If omitted, it defaults to the connection opened by Connect-TfsTeamProject (if any).

    For more details, see the Get-TfsTeamProject cmdlet.


.PARAMETER Collection
    
    Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object.

    When using a URL, it must be fully qualified. The format of this string is as follows:

    http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName>

    Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS.

    To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet.

    For more details, see the Get-TfsTeamProjectCollection cmdlet.


#>

Function Remove-TfsIteration
{
    [CmdletBinding(ConfirmImpact='High', SupportsShouldProcess=$true)]
    Param
    (
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [Alias("Path")]
        [ValidateScript({($_ -is [string]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [object]
        $Iteration,

        [Parameter(Position=1)]
        [Alias("NewPath")]
        [ValidateScript({ ($_ -is [string]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo]) })] 
        [object]
        $MoveTo = '\',

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )

    Process
    {
        $iterations = Get-TfsIteration -Iteration $Iteration -Project $Project -Collection $Collection | Sort -Property Path -Descending

        foreach($i in $iterations)
        {
            if ($PSCmdlet.ShouldProcess($i.RelativePath, "Delete Iteration"))
            {
                $projectName = $i.Path.Split("\")[1]
                _DeleteCssNode -Node $i -MoveToNode $MoveTo -Scope Iteration -Project $Project -Collection $Collection
            }
        }
    }
}
<#

.SYNOPSIS
    Renames an Area ("Area Path")

.PARAMETER Area
    
    Specifies the name, URI or path of an Area. Wildcards are permitted. If omitted, all Areas in the given Team Project are returned.

    To supply a path, use a backslash ("\") between the path segments. Leading and trailing backslashes are optional.

    When supplying a URI, use URIs in the form of "vstfs:///Classification/Node/<GUID>" (where <GUID> is the unique identifier of the given node)


.PARAMETER NewName
    Specifies the new name of the area. Enter only a name, not a path and name. If you enter a path that is different from the path that is specified in the Area parameter, Rename-TfsArea generates an error. To rename and move an item, use the Move-TfsArea cmdlet.

.PARAMETER Project
    
    Specifies either the name of the Team Project or a previously initialized Microsoft.TeamFoundation.WorkItemTracking.Client.Project object to connect to. If omitted, it defaults to the connection opened by Connect-TfsTeamProject (if any).

    For more details, see the Get-TfsTeamProject cmdlet.


.PARAMETER Collection
    
    Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object.

    When using a URL, it must be fully qualified. The format of this string is as follows:

    http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName>

    Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS.

    To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet.

    For more details, see the Get-TfsTeamProjectCollection cmdlet.


#>

Function Rename-TfsArea
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [ValidateScript({($_ -is [string]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [Alias("Path")]
        [object]
        $Area,

        [Parameter(Position=1)]
        [string]
        $NewName,

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )

    Process
    {
        Set-TfsArea -Area $Area -NewName $NewName -Project $Project -Collection $Collection
    }
}
<#
.SYNOPSIS
    Renames an Iteration ("Iteration Path").

.PARAMETER Iteration
    
    Specifies the name, URI or path of an Iteration. Wildcards are permitted. If omitted, all Iterations in the given Team Project are returned.

    To supply a path, use a backslash ("\") between the path segments. Leading and trailing backslashes are optional.

    When supplying a URI, use URIs in the form of "vstfs:///Classification/Node/<GUID>" (where <GUID> is the unique identifier of the given node)


.PARAMETER NewName
    Specifies the new name of the iteration. Enter only a name, not a path and name. If you enter a path that is different from the path that is specified in the Iteration parameter, Rename-TfsIteration generates an error. To rename and move an item, use the Move-TfsIteration cmdlet.

.PARAMETER Project
    
    Specifies either the name of the Team Project or a previously initialized Microsoft.TeamFoundation.WorkItemTracking.Client.Project object to connect to. If omitted, it defaults to the connection opened by Connect-TfsTeamProject (if any).

    For more details, see the Get-TfsTeamProject cmdlet.


.PARAMETER Collection
    
    Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object.

    When using a URL, it must be fully qualified. The format of this string is as follows:

    http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName>

    Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS.

    To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet.

    For more details, see the Get-TfsTeamProjectCollection cmdlet.


#>

Function Rename-TfsIteration
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [ValidateScript({($_ -is [string]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [Alias("Path")]
        [object]
        $Iteration,

        [Parameter(Position=1)]
        [string]
        $NewName,

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )

    Process
    {
        Set-TfsIteration -Iteration $Iteration -NewName $NewName -Project $Project -Collection $Collection
    }
}
<#

.SYNOPSIS
    Changes the value of a property of an Area.

.PARAMETER Area
    
    Specifies the name, URI or path of an Area. Wildcards are permitted. If omitted, all Areas in the given Team Project are returned.

    To supply a path, use a backslash ("\") between the path segments. Leading and trailing backslashes are optional.

    When supplying a URI, use URIs in the form of "vstfs:///Classification/Node/<GUID>" (where <GUID> is the unique identifier of the given node)


.PARAMETER NewName
    Specifies the new name of the area. Enter only a name, not a path and name. If you enter a path that is different from the path that is specified in the area parameter, Rename-Tfsarea generates an error. To rename and move an item, use the Move-Tfsarea cmdlet.

.PARAMETER MoveBy
    Reorders an area by moving it either up or down inside its parent. A positive value moves an area down, whereas a negative one moves it up.

.PARAMETER Project
    
    Specifies either the name of the Team Project or a previously initialized Microsoft.TeamFoundation.WorkItemTracking.Client.Project object to connect to. If omitted, it defaults to the connection opened by Connect-TfsTeamProject (if any).

    For more details, see the Get-TfsTeamProject cmdlet.


.PARAMETER Collection
    
    Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object.

    When using a URL, it must be fully qualified. The format of this string is as follows:

    http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName>

    Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS.

    To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet.

    For more details, see the Get-TfsTeamProjectCollection cmdlet.


#>

Function Set-TfsArea
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [ValidateScript({($_ -is [string]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [Alias("Path")]
        [object]
        $Area,

        [Parameter()]
        [string]
        $NewName,

        [Parameter()]
        [int]
        $MoveBy,

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )

    Process
    {
        $node = Get-TfsArea -Area $Area -Project $Project -Collection $Collection

        if (-not $node)
        {
            throw "Invalid or non-existent area $Area"
        }

        $cssService = _GetCssService -Project $Project -Collection $Collection

        if ($NewName)
        {
            $cssService.RenameNode($node.Uri, $NewName)
        }

        if ($MoveBy)
        {
            $cssService.ReorderNode($node.Uri, $MoveBy)
        }

        return $cssService.GetNode($node.Uri)
    }
}
<#

.SYNOPSIS
    Changes the value of a property of an Iteration.

.PARAMETER Iteration
    
    Specifies the name, URI or path of an Iteration. Wildcards are permitted. If omitted, all Iterations in the given Team Project are returned.

    To supply a path, use a backslash ("\") between the path segments. Leading and trailing backslashes are optional.

    When supplying a URI, use URIs in the form of "vstfs:///Classification/Node/<GUID>" (where <GUID> is the unique identifier of the given node)


.PARAMETER NewName
    Specifies the new name of the iteration. Enter only a name, not a path and name. If you enter a path that is different from the path that is specified in the Iteration parameter, Rename-TfsIteration generates an error. To rename and move an item, use the Move-TfsIteration cmdlet.

.PARAMETER MoveBy
    Reorders an iteration by moving it either up or down inside its parent. A positive value moves an iteration down, whereas a negative one moves it up.

.PARAMETER StartDate
    Sets the start date of the iteration. To clear the start date, set it to $null. Note that when clearing a date, both must be cleared at the same time (i.e. setting both StartDate and FinishDate to $null)

.PARAMETER FinishDate
    Sets the finish date of the iteration. To clear the finish date, set it to $null. Note that when clearing a date, both must be cleared at the same time (i.e. setting both StartDate and FinishDate to $null)

.PARAMETER Project
    
    Specifies either the name of the Team Project or a previously initialized Microsoft.TeamFoundation.WorkItemTracking.Client.Project object to connect to. If omitted, it defaults to the connection opened by Connect-TfsTeamProject (if any).

    For more details, see the Get-TfsTeamProject cmdlet.


.PARAMETER Collection
    
    Specifies either a URL/name of the Team Project Collection to connect to, or a previously initialized TfsTeamProjectCollection object.

    When using a URL, it must be fully qualified. The format of this string is as follows:

    http[s]://<ComputerName>:<Port>/[<TFS-vDir>/]<CollectionName>

    Valid values for the Transport segment of the URI are HTTP and HTTPS. If you specify a connection URI with a Transport segment, but do not specify a port, the session is created with standards ports: 80 for HTTP and 443 for HTTPS.

    To connect to a Team Project Collection by using its name, a TfsConfigurationServer object must be supplied either via -Server argument or via a previous call to the Connect-TfsConfigurationServer cmdlet.

    For more details, see the Get-TfsTeamProjectCollection cmdlet.


#>

Function Set-TfsIteration
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
        [Alias("Path")]
        [ValidateScript({($_ -is [string]) -or ($_ -is [Microsoft.TeamFoundation.Server.NodeInfo])})] 
        [object]
        $Iteration = '\**',

        [Parameter()]
        [string]
        $NewName,

        [Parameter()]
        [int]
        $MoveBy,

        [Parameter()]
        [Nullable[DateTime]]
        $StartDate,
    
        [Parameter()]
        [Nullable[DateTime]]
        $FinishDate,

        [Parameter()]
        [object]
        $Project,

        [Parameter()]
        [object]
        $Collection
    )

    Process
    {
        $node = Get-TfsIteration -Iteration $Iteration -Project $Project -Collection $Collection

        if (-not $node)
        {
            throw "Invalid or non-existent iteration $Iteration"
        }

        $cssService = _GetCssService -Project $Project -Collection $Collection
        $cssService4 = _GetCssService -Project $Project -Collection $Collection -Version 4

        if ($NewName)
        {
            $cssService.RenameNode($node.Uri, $NewName)
        }

        if ($MoveBy)
        {
            $cssService.ReorderNode($node.Uri, $MoveBy)
        }

        if ($StartDate -or $FinishDate)
        {
            if (-not $PSBoundParameters.ContainsKey("StartDate"))
            {
                $StartDate = $node.StartDate
            }

            if (-not $PSBoundParameters.ContainsKey("FinishDate"))
            {
                $FinishDate = $node.FinishDate
            }

            [void]$cssService4.SetIterationDates($node.Uri, $StartDate, $FinishDate)
        }

        return $cssService.GetNode($node.Uri)
    }
}
Function _GetCssNodes($Node, $Scope, $Project, $Collection)
{
    Process
    {
        if ($Node -is [Microsoft.TeamFoundation.Server.NodeInfo])
        {
            return $Node
        }

        $tp = Get-TfsTeamProject -Project $Project -Collection $Collection
        $tpc = $tp.Store.TeamProjectCollection
        $projectName = $tp.Name
        $cssService = $tpc.GetService([type]"Microsoft.TeamFoundation.Server.ICommonStructureService")
        
        if ($node -is [uri])
        {
            return $cssService.GetNode($node)
        }

        $rootPath = _NormalizePath "$projectName\$Scope"
        $fullPath = _NormalizePath "$rootPath\$Node"

        $rootNodeUri = $cssService.GetNodeFromPath("$rootPath").Uri
        $rootElement = $cssService.GetNodesXml(@($rootNodeUri), $true)
        
        $nodePaths = $rootElement.SelectNodes('//@Path') | Select -ExpandProperty '#text'
        $matchingPaths = $nodePaths | ? { $_ -like $fullPath }

        return $matchingPaths | % { $cssService.GetNodeFromPath($_) }
    }
}

Function _DeleteCssNode($Node, $Scope, $MoveToNode, $Project, $Collection)
{
    Process
    {
        $newNode = _GetCssNodes -Node $MoveToNode -Scope $Scope -Project $Project -Collection $Collection
        $cssService = _GetCssService -Project $Project -Collection $Collection

        $cssService.DeleteBranches($Node.Uri, $newNode.Uri)        
    }
}

Function _NewCssNode ($Project, $Path, $Scope, $Collection, $StartDate, $FinishDate)
{
    Process
    {
        $tp = Get-TfsTeamProject -Project $Project -Collection $Collection
        $tpc = $tp.Store.TeamProjectCollection
        $projectName = $tp.Name
        $cssService = $tpc.GetService([type]"Microsoft.TeamFoundation.Server.ICommonStructureService")

        try
        {
            $fullPath = _NormalizePath "$projectName\$Scope\$Path"
            $parentPath = Split-Path $fullPath -Parent
            $nodeName = Split-Path $fullPath -Leaf
            $parentNode = $cssService.GetNodeFromPath($parentPath)
        }
        catch
        {
            $parentNode = _NewCssNode -Project $Project -Path $parentPath -Scope $Scope -Collection $Collection
        }

        if ($StartDate -or $FinishDate)
        {
            $cssService = $tpc.GetService([type]"Microsoft.TeamFoundation.Server.ICommonStructureService4")
            $nodeUri = $cssService.CreateNode($nodeName, $parentNode.Uri, $StartDate, $FinishDate)
        }
        else
        {
            $nodeUri = $cssService.CreateNode($nodeName, $parentNode.Uri)
        }

        return $cssService.GetNode($nodeUri)
    }
}

Function _NormalizePath($Path)
{
    if([string]::IsNullOrWhiteSpace($Path))
    {
        return [string]::Empty
    }

    $newPath = [System.Text.RegularExpressions.Regex]::Replace($Path, '\\{2,}', '\')

    if (-not $newPath.StartsWith("\"))
    {
        $newPath = "\$newPath"
    }

    if ($newPath.EndsWith("\"))
    {
        $newPath = $newPath.Substring(0, $newPath.Length-1)
    }

    return $newPath
}

Function _GetCssService($Project, $Collection, $Version)
{
    $tp = Get-TfsTeamProject -Project $Project -Collection $Collection
    $tpc = $tp.Store.TeamProjectCollection
    $projectName = $tp.Name

    return $tpc.GetService([type]"Microsoft.TeamFoundation.Server.ICommonStructureService$Version")
}