function Close-TeamCityBlock { <# .SYNOPSIS Close the TeamCity block .DESCRIPTION Used to write a handy marker for content collapsing. Note that TeamCity does not honor the name of the closed block as a developer might, so the first close that occurs after any open will close that opening block. This is tricky to troubleshoot and will make your life frustrating when you do not manage your opening and closing as tightly as you can. Using the pair of named functions makes it much easier to see that you have indeed opened and closed the block as expected. .PARAMETER Name The name of the block being opened. Think "collapsed" .PARAMETER Description The description to show in the UI for more detail. Think "expanded" .PARAMETER WasSanitized Skips sanitizing inputs. Only provided for the use-case of allowing the block returned object from Open-TeamCityBlock to be splatted as: Close-TeamCityBlock @block .OUTPUTS Returns an object that can be used in pipeline formation to close the block later .LINK Open-TeamCityBlock .EXAMPLE $block = Open-TeamCityBlock -Name "some Name" -Description "This is a long description that indicates what we are doing here" Close-TeamCityBlock -Block $block .EXAMPLE $block = Open-TeamCityBlock -Name "some Name" -Description "This is a long description that indicates what we are doing here" Close-TeamCityBlock @block .EXAMPLE $block = Open-TeamCityBlock -Name "some Name" -Description "This is a long description that indicates what we are doing here" $block | Close-TeamCityBlock .EXAMPLE Open-TeamCityBlock -Name "some Name" -Description "This is a long description that indicates what we are doing here" Close-TeamCityBlock -Name "some Name" -Description "This is a long description that indicates what we are doing here" Note that this example will emit a block-opened object into the pipeline #> [CmdletBinding(DefaultParameterSetName = 'Message')] [OutputType([void])] param( [Parameter(Mandatory = $true, ParameterSetName = 'Message')] [string]$Name, [Parameter(Mandatory = $true, ParameterSetName = 'Message')] [string]$Description, [Parameter(Mandatory = $false, ParameterSetName = 'Message')] [switch]$WasSanitized, [Parameter(Mandatory = $true, ParameterSetName = 'Block', ValueFromPipeline = $true)] [object]$Block ) $logLead = Get-LogLeadName $sanitizedName = "" $sanitizedDescription = "" if ($PSCmdlet.ParameterSetName -eq 'Block') { if ($Block.WasSanitized) { $sanitizedName = $Block.Name $sanitizedDescription = $Block.Description } else { $sanitizedName = ConvertTo-SafeTeamCityMessage -InputText $Block.Name $sanitizedDescription = ConvertTo-SafeTeamCityMessage -InputText $Block.Description } } else { if ($WasSanitized) { $sanitizedName = $Name $sanitizedDescription = $Description } else { $sanitizedName = ConvertTo-SafeTeamCityMessage -InputText $Name $sanitizedDescription = ConvertTo-SafeTeamCityMessage -InputText $Description } } if (Test-IsTeamCityProcess) { Write-Host "##teamcity[blockClosed name='$sanitizedName' description='$sanitizedDescription']" } else { Write-Host "$logLead : CloseBlock $sanitizedName : $sanitizedDescription" } }