function Open-TeamCityBlock { <# .SYNOPSIS Open a TeamCity block with a header and description. Useful for collapsing content. .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" .OUTPUTS Returns an object that can be used in pipeline formation to close the block later .LINK Close-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()] [OutputType([object])] param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [string]$Description ) $sanitizedName = ConvertTo-SafeTeamCityMessage -InputText $Name $sanitizedDescription = ConvertTo-SafeTeamCityMessage -InputText $Description if (Test-IsTeamCityProcess) { Write-Host "##teamcity[blockOpened name='$sanitizedName' description='$sanitizedDescription']" } else { Write-Host "$logLead : OpenBlock $sanitizedName : $sanitizedDescription" } # Note that we _could_ *only* return this if an assignment was requested. Ex: $MyInvocation.Line -contains '=' # The way it is written, if it is only invoked on the call alone, we'll get a dump of what was started into the output stream # This could be useful in some scenarios, for debugging return @{ Name = $sanitizedName Description = $sanitizedDescription WasSanitized = $true } }