Home > Net >  How to parse a here-string in PowerShell as a hash?
How to parse a here-string in PowerShell as a hash?

Time:02-03

This example is easy enough:

PS C:\Users\saunders\Desktop\misc>
PS C:\Users\saunders\Desktop\misc> $hash = @"
>> Name = Jackson
>> Employer = BigData
>> EmpID = 2032
>> Type = Permanent
>> "@
PS C:\Users\saunders\Desktop\misc>
PS C:\Users\saunders\Desktop\misc> $hash
Name = Jackson
Employer = BigData
EmpID = 2032
Type = Permanent
PS C:\Users\saunders\Desktop\misc>
PS C:\Users\saunders\Desktop\misc> $hash | ConvertFrom-StringData

Name                           Value
----                           -----
Employer                       BigData
Type                           Permanent
EmpID                          2032
Name                           Jackson


PS C:\Users\saunders\Desktop\misc>

Which is excellent and the desired output. Here:

PS C:\Users\saunders\Desktop\misc>
PS C:\Users\saunders\Desktop\misc> cat .\hash.txt
$hash = @"
Name = Jackson
Employer = BigData
EmpID = 2032
Type = Permanent
"@
PS C:\Users\saunders\Desktop\misc>
PS C:\Users\saunders\Desktop\misc> $foo = Get-Content .\hash.txt
PS C:\Users\saunders\Desktop\misc>
PS C:\Users\saunders\Desktop\misc> $foo
$hash = @"
Name = Jackson
Employer = BigData
EmpID = 2032
Type = Permanent
"@
PS C:\Users\saunders\Desktop\misc>

the data originates in a file. How is this file read as a here-string so that it can be used as above?

CodePudding user response:

Your .\hash.txt is in effect a .ps1 script file, so you could change its extension an then load it via ., the dot-sourcing operator, at which point $hash will be defined and can be passed to ConvertFrom-StringData.

To process the file as-is, you can pass its content to Invoke-Expression (though note that this cmdlet should generally be avoided):

Invoke-Expression (Get-Content -Raw t.txt)
$hash | ConvertFrom-StringData

If you have control over how .\hash.txt gets created and can change its name, you can save it as a PowerShell data file, i.e. with extension .psd1, which can be read as-is with the Import-PowerShellDataFile cmdlet:

A .psd1 file is in effect the source-code representation of a hashtable literal, whose syntax requirements are more stringent than for text that can be parsed with ConvertFrom-StringData:

# Save the source-code representation of a hashtable literal
# to a file - do NOT include a variable assignment:
@'
@{
  Name = 'Jackson'
  Employer = 'BigData'
  EmpID = 2032
  Type = 'Permanent'
}
'@ > hash.psd1

Import-PowerShellDataFile hash.psd1

As an aside:

  • As of PowerShell 7.3.2, both ConvertFrom-StringData and Import-PowerShellData do not preserve the entries in definition order, given that [hasthable] instances are inherently unordered.

  • GitHub issue #19070 proposes overcoming this limitation, by making these cmdlets return ordered hashtables instead, via System.Management.Automation.OrderedHashtable, which derives from [hashtable].

  • Related