My function builds a representation of a table as a PSCustomObject. It has a title, an array of column headers, and a [System.Collection.Generic.List][string]
of rows:
function Create-ConfluenceTable{
param(
[Parameter(mandatory=$true)][string]$Title,
[Parameter(mandatory=$true)][string[]]$Columns
)
$rows = [System.Collections.Generic.List[string]]::new()
$t = [PSCustomObject]@{
Title = $Title;
Columns = $Columns;
Rows = $rows
}
return $t
}
I then have a pipeline-aware function for adding rows to the table.
function AddRow {
param(
[Parameter(mandatory,ValueFromPipeline)]$ConfluenceTable,
[Parameter(mandatory=$true)][string[]]$RowValues
)
process
{
foreach($rv in $RowValues) {
$ConfluenceTable.Rows.Add($rv)
}
}
}
When I create the table and then try to pass values to it, I can't get any string variables to correctly resolve. When I run this code...
$bar="https://example.com"
$ct = Create-ConfluenceTable -title "URLs" -Columns {"Type","Url"}
$ct | AddRow -RowValues {"Foo",$bar}
$ct
...my output is:
Title Columns Rows
----- ------- ----
URLs {"Type","Url"} {"Foo",$bar}
What I would like to see is:
Title Columns Rows
----- ------- ----
URLs {"Type","Url"} {"Foo","https://example.com"}
The issue with your code is that you're passing scriptblocks {...}
as argument of your functions instead of strings, by simply removing the curly braces the issue will be gone:
$bar = "https://example.com"
$ct = Create-ConfluenceTable -title "URLs" -Columns "Type", "Url"
$ct | AddRow -RowValues "Foo", $bar
$ct
Opinionated answer here but it seems you could benefit from a class
instead of using separated functions, here is how it would look:
using namespace System.Collections.Generic
using namespace System.Collections.ObjectModel
class ConfluenceTable {
[string] $Title
[string[]] $Columns
hidden [List[string]] $_rows
static ConfluenceTable() {
# add a getter for Rows
$updateTypeDataSplat = @{
TypeName = 'ConfluenceTable'
MemberType = 'CodeProperty'
MemberName = 'Rows'
Value = [ConfluenceTable].GetMethod('get_Rows')
}
Update-TypeData @updateTypeDataSplat
# unfortunate but needed to keep property order :(
$updateTypeDataSplat = @{
TypeName = 'ConfluenceTable'
DefaultDisplayPropertySet = 'Title', 'Columns', 'Rows'
}
Update-TypeData @updateTypeDataSplat
}
hidden static [ReadOnlyCollection[string]] get_Rows([psobject] $instance) {
return [ReadOnlyCollection[string]]::new($instance._rows)
}
ConfluenceTable([string] $title, [string[]] $columns) {
$this.Title, $this.Columns = $title, $columns
$this._rows = [List[string]]::new()
}
[void] AddRow([string] $row) {
$this._rows.Add($row)
}
[void] AddRowRange([string[]] $rows) {
$this._rows.AddRange($rows)
}
}
$bar = 'https://example.com'
$table = [ConfluenceTable]::new('URLs', ('Type', 'Url'))
$table.AddRowRange(('Foo', $bar))
$table