Multiple Hash Table Strings to Objects

This topic contains 0 replies, has 1 voice, and was last updated by  Forums Archives 5 years, 8 months ago.

  • Author
    Posts
  • #6036

    by maverick918 at 2013-02-27 08:09:33

    Hey All –

    So far this forum has been awesome. Every time I post something on here it sparks me into solving part of the issue or leads me down a different path.

    Here is my next issue.

    I'm getting data back from one of my functions in a text file that has multiple hash tables in it. Seen below.

    @{VMSCSIController=SCSI controller 0; VMDiskName=Hard disk 1; SCSI_Id=0 : 0; VMDiskFile=[datavms] VM/VM.vmdk; VMDiskSizeGB=40; WindowsDisk=Disk 0; WindowsDiskSizeGB=39.9948906898499}
    @{VMSCSIController=SCSI controller 0; VMDiskName=Hard disk 2; SCSI_Id=0 : 1; VMDiskFile=[datavms] VM/VM_1.vmdk; VMDiskSizeGB=15; WindowsDisk=Disk 1; WindowsDiskSizeGB=14.999041557312}
    @{VMSCSIController=SCSI controller 0; VMDiskName=Hard disk 3; SCSI_Id=0 : 2; VMDiskFile=[datavms] VM/VM_2.vmdk; VMDiskSizeGB=15; WindowsDisk=Disk 2; WindowsDiskSizeGB=14.999041557312}

    I need to pull these out one by one and convert these to object data that I can actually use. For example, I need to be able to select WindowsDisk,VMDiskSizeGB. This does relate to a previous post but I'm having trouble actually converting these to objects ONE by ONE.

    I know some sort of foreach command will work but I'm struggling to figure out how I can pull out each hash table and convert that pulled out hashtable to and object.

    Thank you so much for any help, I'll continue to research this – sometimes it helps to write it down and ponder afterwards.

    Jake

    by DonJ at 2013-02-27 08:51:15

    So... you have a function that returns hash tables, or a text file that contains the hash table text as above? The latter is a bit weird to work with – do you NEED to use a text file as an intermediate format? Can you not modify the original function to just output objects?

    Text files are a poor storage format... making life a bit harder on you.

    Even if you sometimes need to store the original function's output in a text file, hash tables are an exceptionally poor way to do it, because they're difficult to "re-hydrate" and bring back into the shell.

    by maverick918 at 2013-02-27 10:13:09

    DUPLICATE

    by maverick918 at 2013-02-27 10:13:09

    Absolutely. Well the Function uses Invoke-VMScript which returns raw text to the screen. So its either a report from the screen which has text in a pre-formatted array, or the above example... The report from the screen looks like this.

    VMSCSIController : SCSI controller 0
    VMDiskName : Hard disk 2
    SCSI_Id : 0 : 1
    VMDiskFile : [datavms] VM/VM_1.vmdk
    StorageTier : Bronze
    VMDiskSizeGB : 36
    WindowsDisk : Disk 1
    WindowsDiskSizeGB : 35.9961676597595

    VMSCSIController : SCSI controller 0
    VMDiskName : Hard disk 3
    SCSI_Id : 0 : 2
    VMDiskFile : [datavms] VM/VM_2.vmdk
    VMDiskSizeGB : 15
    WindowsDisk : Disk 2
    WindowsDiskSizeGB : 14.999041557312

    I probably could investigate some way to get the Get-VMDiskMapping (PowerCLI Reference) function to format it in a way that can be easily repurposed as data to be used by another function – IE some sort of file that can be easily turned into an object.

    Thanks for the help! 🙂

    by poshoholic at 2013-02-27 11:54:37

    You should look at using ConvertTo-Csv and ConvertFrom-Csv. Inside of your Invoke-VMScript command, use ConvertTo-Csv to convert the objects into CSV format. Then on the client, when you get the CSV data back, pipe it to ConvertFrom-Csv to get it back into rehydrated object format so that you can reference the object properties.

    One possible complication with that approach would be around objects with properties that are collections...those don't convert into CSV format so well. In those scenarios, there are some internal ways you can convert the objects into CLIXML format, where you can specify the depth required for proper rehydration once you get them back on the client. Or if you don't want to use internal APIs, you can use Export-Clixml in the Invoke-VMScript, then return the contents of that file to the host, on the host write that to a file and then Import-Clixml the file contents.

    Lots of possibilities here. 🙂

    by mjolinor at 2013-02-27 17:06:22

    This may be over-simplifying the situation, but based on your posted data:

    (@'
    @{VMSCSIController=SCSI controller 0; VMDiskName=Hard disk 1; SCSI_Id=0 : 0; VMDiskFile=[datavms] VM/VM.vmdk; VMDiskSizeGB=40; WindowsDisk=Disk 0; WindowsDiskSizeGB=39.9948906898499}
    @{VMSCSIController=SCSI controller 0; VMDiskName=Hard disk 2; SCSI_Id=0 : 1; VMDiskFile=[datavms] VM/VM_1.vmdk; VMDiskSizeGB=15; WindowsDisk=Disk 1; WindowsDiskSizeGB=14.999041557312}
    @{VMSCSIController=SCSI controller 0; VMDiskName=Hard disk 3; SCSI_Id=0 : 2; VMDiskFile=[datavms] VM/VM_2.vmdk; VMDiskSizeGB=15; WindowsDisk=Disk 2; WindowsDiskSizeGB=14.999041557312}
    '@).split("`n") |
    foreach {$_.trim()} | sv text

    $text -replace '=',"='" -replace ';',"';" -replace '}',"'}" |
    foreach {new-object psobject -property (iex $_)}

    WindowsDisk : Disk 0
    SCSI_Id : 0 : 0
    VMSCSIController : SCSI controller 0
    VMDiskFile : [datavms] VM/VM.vmdk
    VMDiskSizeGB : 40
    VMDiskName : Hard disk 1
    WindowsDiskSizeGB : 39.9948906898499

    WindowsDisk : Disk 1
    SCSI_Id : 0 : 1
    VMSCSIController : SCSI controller 0
    VMDiskFile : [datavms] VM/VM_1.vmdk
    VMDiskSizeGB : 15
    VMDiskName : Hard disk 2
    WindowsDiskSizeGB : 14.999041557312

    WindowsDisk : Disk 2
    SCSI_Id : 0 : 2
    VMSCSIController : SCSI controller 0
    VMDiskFile : [datavms] VM/VM_2.vmdk
    VMDiskSizeGB : 15
    VMDiskName : Hard disk 3
    WindowsDiskSizeGB : 14.999041557312

    by maverick918 at 2013-02-27 20:39:45

    Thank you all for the suggestions! I've been working on this tonight but I didn't check here until now.

    I was trying to accomplish this goal through 2 separate functions – I did some more research on how the Get-VMDiskMapping Function actually does its job and I found that the function doesn't actually return the text from Invoke-VMScript. The function actually just gets results back and creates a table on the localhost or wherever you run the script from.

    This helps out so much because as Don mentioned above it can be cumbersome to manipulate text in the manner I want to. In the future if I decide to write a separate function to set the disk up I can explore that, however for the time being I'm going to include my code in the Get-VMDiskMapping function to accomplish the goal.

    So far I have this – Poshoholic I had to make some slight mods to your code.
    foreach ($diskMappingRecord in $diskinfo | Where {$_.WindowsDisk -ne 'Disk 0'})
    {
    $diskMappingRecord | Select WindowsDisk,VMDiskSizeGB
    do {
    $disknumber = Read-Host -Prompt "Enter the Disk Number to Configure"
    }
    while (!($disknumber -gt 0))
    do {
    $diskletter = Read-Host -Prompt 'Enter the Disk Letter'
    }
    while (!($diskletter -ne "C"))
    $label = Read-Host -Prompt 'Enter the Label for this Disk'
    }

    I don't want the users formatting the OS drive in anyway I wanted it to start on "Disk 1". Basically the end goal is to create a Diskpart txt file based on this input per disk and send that diskpart text file to the host and execute.

    I'm making headway 🙂

    Thank you so much for the continued support. I appreciate it guys.

You must be logged in to reply to this topic.