Create an array object with columns from text inside a script or Convert a Here-String to an array with column headings

So, I had an interesting need the other day when creating another script--I wanted to create a collection of object that were of the same type, but had different values for the properties.  In this case, the objects happened to be registry keys and values that was going to report on, and (optionally) take a series of actions on.  I could have put them into a CSV and imported them and looped through them that way, but I really wanted to make the tool self-contained with no other content to download.

Here-Strings to the rescue.  A Here-String is basically a way to assign a multi-line block of text to a variable.  To designate a here-string, you basically have a construct of @" <some stuff> "@ .

As in:

 $variable = @"
This
is
some
text
"@

When you retrieve its value in PowerShell, it's displayed just as you entered it (multiline string).  When you call the GetType() method on it, you'll see that it indeed is a string.

That's cool and all.  But how do I make that into something like an array with columns?

Consider this:

 # Check for TLS capabilities
$Keys = @'
HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client,DisabledByDefault,reg_dword,0
HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client,Enabled,reg_dword,1
HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server,DisabledByDefault,reg_dword,0
HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server,Enabled,reg_dword,1
HKLM:SOFTWARE\Microsoft\.NETFramework\v4.0.30319,SchUseStrongCrypto,reg_dword,1
'@ -split "`n" |  %  { $_.trim() }
$KeysArray = @()
Foreach ($line in $Keys)
{
[array]$linedata = $line.Split(",")
$KeyData = New-Object PSObject
$KeyData | Add-Member -MemberType NoteProperty -Name "Path" -Value $LineData[0]
$KeyData | Add-Member -MemberType NoteProperty -Name "Item" -Value $LineData[1]
$KeyData | Add-Member -MemberType NoteProperty -Name "Type" -Value $LineData[2]
$KeyData | Add-Member -MemberType NoteProperty -Name "Value" -Value $LineData[3]
$KeysArray += $KeyData
}

What I've done here is create string variable called $Keys that has four distinct columns, separated by commas:

Path,Key,Type,Value

And then split it on the newline character "`n".  Finally, I trimmed out any trailing or leading whitespace, since that will definitely come back to haunt me later.

Then, using $KeysArray = @(), I declare a new empty array variable.

From then on, I can loop through the items in that text string (that are separated by a newline character), split them into smaller string chunks using the "," as a separator, and add each of those values  as NoteProperty members to a PSObject.  Finally, I take that filled-out PSObject and add it to $KeysArray:

The result is an array of PSObjects that I can then reference based on the column (property) name.

Sweet Christmas, indeed!