4

If I want to write an object / HashTable to disk and load it up again later does PowerShell support that?

leeand00
  • 25,510
  • 39
  • 140
  • 297

3 Answers3

8

Sure, you can use PowerShell's native CliXml format:

@{
  a = 1
  b = [pscustomobject]@{
    prop = "value"
  }
} | Export-Clixml -Path hashtable.ps1xml

Deserialize with Import-CliXml:

PS C:\> $ht = Import-CliXml hashtable.ps1xml
PS C:\> $ht['b'].prop -eq 'value'
True
mklement0
  • 382,024
  • 64
  • 607
  • 775
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • 1
    Indeed; worth mentioning the potential loss of type fidelity during serialization/deserialization (not a concern with your example) - see [this answer](https://stackoverflow.com/a/59180367/45375). – mklement0 Mar 10 '20 at 17:16
3

As the default PowerShell hash table (@{...}) is of type Object, Object it doesn't concern just a HashTable type but the question implies serializing of any (value) type to disk.

In addition to the answer from @Mathias R. Jessen, you might use the PowerShell serializer (System.Management.Automation.PSSerializer) for this:

Serialize to disk

[System.Management.Automation.PSSerializer]::Serialize($HashTable) | Out-File .\HashTable.txt

Deserialize from disk

$PSSerial = Get-Content .\HashTable.txt
$HashTable = [System.Management.Automation.PSSerializer]::Deserialize($PSSerial)

You could also use this ConvertTo-Expression cmdlet. The downside is that is concerns a non-standard PowerShell cmdlet for serializing but the advantage is that you might use the standard and easy dot-sourcing technique to restore it:

Serialize to disk

$HashTable | ConvertTo-Expression | Out-File .\HashTable.ps1

Deserialize from disk

$HashTable = . .\HashTable.ps1
iRon
  • 20,463
  • 10
  • 53
  • 79
  • 1
    FWIW, `[System.Management.Automation.PSSerializer]::Serialize()` produces the exact same format as `Export-Clixml` – Tomalak Jul 21 '21 at 16:03
2

The answer may depend on the data in your hashtable. For relatively simple data Export-Clixml and Import-CliXml is the native and straightforward PowerShell solution, see another answer.

For more complex data, not well serialized via CliXml, but .NET serializable, you may use one of the standard .NET serializers. For example, BinaryFormatter. You may use (or learn the code) two ready scripts: Export-Binary.ps1 and Import-Binary.ps1. You may find demo examples, including the hashtable, in Export-Binary.test.ps1.

And, if you want to store many hashtables effectively then look for some sort of document store solutions. I recently found that LiteDB is very good for many PowerShell scenarios. So I created Ldbc, the PowerShell wrapper of LiteDB, batteries included. Using this way, you may store and retrieve thousands of hashtables.

UPDATE: If you prefer to store relatively simple data in PSD1 (native PowerShell data format), you may also use the script module PsdKit. (Thank you @iRon for reminding)

Community
  • 1
  • 1
Roman Kuzmin
  • 40,627
  • 11
  • 95
  • 117