Loading a PowerShell hashtable from a file?

前端 未结 6 1151
粉色の甜心
粉色の甜心 2020-12-11 14:45

I\'ve got a file containing some data in PowerShell Object Notation:

@{ X = \'x\'; Y = \'y\' }

I\'d like to load this into a variable from

相关标签:
6条回答
  • 2020-12-11 15:22

    If you can give this file the extension .ps1, say, data.ps1 then it cannot be simpler than this code:

    $data = <path>\data.ps1
    
    0 讨论(0)
  • 2020-12-11 15:24

    I've used ConvertFrom-StringData. If you want to use this approach you'll need to change the way you store key/value pairs with each on its own line and no quotes:

    #Contents of test.txt
    X = x
    Y = y
    
    get-content .\test.txt | ConvertFrom-StringData
    
    Name                           Value
    ----                           -----
    X                              x
    Y                              y
    

    ConvertFrom-StringData is a built-in cmdlet. I created corresponding ConvertTo-StringData function available here http://poshcode.org/1986

    0 讨论(0)
  • 2020-12-11 15:28

    (I figured it out while putting together a repro)

    PS> $content = ( Get-Content .\foo.pson | Out-String )
    PS> $data = ( Invoke-Expression $content )
    

    Get-Content returns an array with the lines in the file; the Out-String is used to join them together.

    Invoke-Expression then runs the script, and the result is captured. This is open to injection attacks, but that's OK in my specific case.

    Or, if you prefer your PowerShell terse:

    PS> $data = gc .\foo.pson | Out-String | iex
    

    (I can't find a shorter form of Out-String)

    0 讨论(0)
  • 2020-12-11 15:31

    I ran into trouble using ConvertFrom-StringData as @Chad suggested. If you do:

    $hash = get-content .\test.txt | ConvertFrom-StringData
    

    I found I had an object array rather than a hash table. In fact, it appears that I had an array of hash tables, each with one entry. I confirmed with a:

    $hash.GetType()
    

    It looks like you need to join each line of the slurped input file to ensure that it forms a single string for ConvertFrom..'s use:

    $hash = ((get-content .\test.txt) -join '`n') | ConvertFrom-StringData
    
    0 讨论(0)
  • 2020-12-11 15:33

    Starting from PowerShell 5.0 you have

    Import-PowerShellDataFile
    

    Which imports values from a .psd1-file. So the only thing you have to do is rename your file to *.psd1

    Official help is here.

    0 讨论(0)
  • 2020-12-11 15:44

    This is an older post but, this is sort of a twist on your accepted solution and perhaps slightly more "safe", keep in mind un-trusted files.

    From your notes, you have a file that contains a hashtable using Powershell syntax. Given that constraint, you can import it directly:

    $HashPath = ".\foo.pson"
    # input file contents
    $filecontent = Get-Content -Path $HashPath -Raw -ErrorAction Stop
    # put the file in a script block
    $scriptBlock = [scriptblock]::Create( $filecontent )
    #check that the file contains no other Powershell commands
    $scriptBlock.CheckRestrictedLanguage( $allowedCommands, $allowedVariables, $true )
    #execute it to create the hashtable 
    $hashtable = ( & $scriptBlock ) 
    

    Note on the $scriptBlock.CheckRestrictedLanguage you could replace that with

    $scriptBlock.CheckRestrictedLanguage([string[]]@(), [string[]]@(), $false)
    

    Use an empty list of strings so we do not allow any Powershell commands. When importing a hashtable, this is exactly what we want. That last one is allowEnvironmentVariables so we restrict that in this example with $false.

    Side note, a Powershell module (psd1 file) is just a hashtable so this concept may help you to also pull in script blocks or other things.

    Reference: https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.scriptblock.checkrestrictedlanguage?view=powershellsdk-1.1.0

    0 讨论(0)
提交回复
热议问题