There is a more general way to do this, other than using Html::Decode or RegExps. It is far more complicated, but it can be usefull, when some columns, besides link columns, contain special HTML characters, that shouldn't be processed like links (e.g. $PageTitle have something like "foo<bar", what will break markup after using Html::Decode).
This approach using the fact, that ConvertTo-Html produces valid XHTML, which can be used in Powershell/.Net XML facilities. The main idea is to convert cmdlet output to XML document, then retrieve link columns with XPath and modify them to create links using DOM functions.
Here is code snippet:
$pso = New-Object PSObject -Property @{
SiteUrl = 'foobar.org'
PageTitle = 'x&z a<b<c'
PageUrl = 'foobar.org/contact.html'
} | ConvertTo-Html
$xmlDoc = [xml]$pso
$xhtmlNS = 'http://www.w3.org/1999/xhtml'
$xmlNSManager = New-Object System.Xml.XmlNamespaceManager $xmlDoc.NameTable
$xmlNSManager.AddNamespace('x', $xhtmlNS)
$xmlDoc.SelectNodes('//x:table/x:tr/x:td[3]', $xmlNSManager) | %{
$a = $xmlDoc.CreateElement('a', $xhtmlNS)
$a.setAttribute('href', $_.'#text')
[void]$a.AppendChild($xmlDoc.CreateTextNode('Contact Us'))
[void]$_.ReplaceChild($a, $_.FirstChild)
}
$xmlDoc.OuterXml | Out-File 'test.html'
XPath string to retrieve n-th column cells is '//x:table/x:tr/x:td[n]', where n - is number of column (index starts at 1). Some clarifications about using XML namespaces (e.g. XmlNamespaceManager and funky 'x:' prefix) can be found here: Xml Namespace breaking my xpath!
To modify several columns at once, following XPath can be used: '//x:table/x:tr/x:td[position()=1 or position()=2 or ... or position()=last()]'
foreach ($td in $xmlDoc.SelectNodes('//x:table/x:tr/x:td[position()=1 or position()=2 or ... or position()=last()]', $xmlNSManager)) {
# processing first column cells
[void]$foreach.MoveNext()
# processing second column cells
[void]$foreach.MoveNext()
# etc
}