Powershell to Convert HTML Table to Array of PSCustomObject
Parsing HTML

I won't lay into you too badly about using RegEx on HTML since you clearly already know it's a bad idea and are trying to parse it as XML instead. Not a bad idea.

I have to recommend HTML Agility Pack though. It is designed for HTML and it works well with imperfect HTML (unlike the XML parser which is very strict).

It seems to be designed with C# in mind but I've used it in PowerShell before with great success.

Also, you're relying on the parsing done by Invoke-WebRequest, which relies on Internet Explorer. This can have some side effects, for example it won't work on Server Core (because IE is not installed), and it won't work if it's run as a user who has never opened Internet Explorer before. It also sometimes messed up its check of whether IE is available.

Using agility pack won't rely on any of that. You can still use Invoke-WebRequest -UseBasicParsing to retrieve the page without doing the DOM parsing and it doesn't need IE for that call.

Aliases

This is a personal choice, but I don't like aliases in finished scripts that are intended to be reused. I would replace % with ForEach-Object and ? with Where-Object.

Create-Url

There's a bug in this. You accept a parameter called $Uri but refer to $url in the function body.

Once you fix that, it has another problem: it ignores the existing path of the passed in URI, and it ignores whether the form action is absolute (will break), relative with leading / (will work), relative with no leading / (will work when original URI has no path, but will break otherwise).

ConvertFrom-HtmlTableRow



if($headers[$i] -ne $null)


This could just be written as:

if($headers[$i])


ConvertFrom-HtmlTable

if ($headers -gt [System.String]::Empty)


You can use ![String]::IsNullOrEmpty($headers) for this, but really, it can be shortened to just:

if ($headers)