locked
Turing a bunch or user supplied variables into a pretty table RRS feed

  • Question

  • need some help on this one

    I need to turn this:

    $HDD1GB = "35"
    $HDD2GB = "30"
    $HDD3GB = ""
    $HDD4GB = ""
    $HDD1GBLabel = "data"
    $HDD2GBLabel = "backup"
    $HDD3GBLabel = ""
    $HDD4GBLabel = ""
    $HDD1GBLetter = "d:"
    $HDD2GBLetter = "S:"
    $HDD3GBLetter = ""
    $HDD4GBLetter = ""

    into this:

    Size Label Letter

    $hdd1GB $hdd1GBLabel $Hdd1GBLetter

    $hdd2GB $hdd2GBLabel $Hdd2GBLetter

    So that I can foreach that out but I have no Idea how to turn it in to that kind of table.


    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail


    • Edited by Liam Silva Monday, August 25, 2014 7:28 PM typo
    Monday, August 25, 2014 7:28 PM

Answers

  • This is how to normalize the data:

    $new=@()
    $new+=$csv|select @{n='DriveName';E={$_.Drive1Name}},@{n='DriveLetter';E={$_.Drive1Letter}}
    $new+=$csv|select @{n='DriveName';E={$_.Drive2Name}},@{n='DriveLetter';E={$_.Drive2Letter}}
    $new+=$csv|select @{n='DriveName';E={$_.Drive3Name}},@{n='DriveLetter';E={$_.Drive3Letter}}
    $new
    

    You now have a table of values for drives.


    ¯\_(ツ)_/¯

    • Marked as answer by Liam Silva Tuesday, August 26, 2014 11:40 PM
    Tuesday, August 26, 2014 10:52 PM

All replies

  • Your question reveals a structural problem with how the script is processing data. Let's start with something more basic.

    When we see variables with embedded numbers as an attempt to differentiate values, this is usually the result of a programmer who is unfamiliar with the concept of an array.

    An array is a data structure that can contain multiple values. You can store an array in a single variable. For example:


    $computerList = @("alpha","bravo","charlie")

    The $computerList variable in this example contains 3 values. $computerList[0] contains the string "alpha", $computerList[1] contains "bravo", and $computerList[2] contains "charlie".

    A forum, however, isn't a good place to learn a programming language.


    -- Bill Stewart [Bill_Stewart]

    Monday, August 25, 2014 8:00 PM
  • I did not post the full script here this is part of a larger script that pulls data from a csv that is generated out of an access database.  It is designed to automate the building of virtual servers, as such the drive values are stored in different fields.  This specific piece is designed to then run diskpart in order to format the drives inside the guest OS.  I think thats what made it such a pain for me.  I came of with something very ugly that works.  I would like to clean it up sut here is what I finally came up with.

    $HDD1GB = "35"
    $HDD2GB = "30"
    $HDD3GB = ""
    $HDD4GB = ""
    $HDD1GBLabel = "data"
    $HDD2GBLabel = "backup"
    $HDD3GBLabel = ""
    $HDD4GBLabel = ""
    $HDD1GBLetter = "d:"
    $HDD2GBLetter = "S:"
    $HDD3GBLetter = ""
    $HDD4GBLetter = ""

    If(!($HDD1GB -le "1")){
    $hdd1 =  New-Object System.Object
    $hdd1 | add-member -Type NoteProperty -Name Size -Value $HDD1GB -force | out-null
    $hdd1 | add-member -Type NoteProperty -Name Label -Value $HDD1GBLabel -force | out-null
    $hdd1 | add-member -Type NoteProperty -Name DriveLetter -Value $HDD1GBLetter -force | out-null
    }
    else {Remove-Variable -Name HDD1GB -Force
    Remove-Variable -Name HDD1GBLabel -Force
    Remove-Variable -Name HDD1GBLetter -Force
    }

    If(!($HDD2GB -le "1")){
    $hdd2 =  New-Object System.Object
    $hdd2 | add-member -Type NoteProperty -Name Size -Value $HDD2GB -force | out-null
    $hdd2 | add-member -Type NoteProperty -Name Label -Value $HDD2GBLabel -force | out-null
    $hdd2 | add-member -Type NoteProperty -Name DriveLetter -Value $HDD2GBLetter -force | out-null
    }
    else {Remove-Variable -Name HDD2GB -Force
    Remove-Variable -Name HDD2GBLabel -Force
    Remove-Variable -Name HDD2GBLetter -Force
    }

    If(!($HDD3GB -le "1")){
    $hdd3 =  New-Object System.Object
    $hdd3 | add-member -Type NoteProperty -Name Size -Value $HDD3GB -force | out-null
    $hdd3 | add-member -Type NoteProperty -Name Label -Value $HDD3GBLabel -force | out-null
    $hdd3 | add-member -Type NoteProperty -Name DriveLetter -Value $HDD3GBLetter -force | out-null
    }
    else {Remove-Variable -Name HDD3GB -Force
    Remove-Variable -Name HDD3GBLabel -Force
    Remove-Variable -Name HDD3GBLetter -Force
    }

    If(!($HDD4GB -le "1")){
    $hdd4 =  New-Object System.Object
    $hdd4 | add-member -Type NoteProperty -Name Size -Value $HDD4GB -force | out-null
    $hdd4 | add-member -Type NoteProperty -Name Label -Value $HDD4GBLabel -force | out-null
    $hdd4 | add-member -Type NoteProperty -Name DriveLetter -Value $HDD4GBLetter -force | out-null
    }
    else {Remove-Variable -Name HDD4GB -Force
    Remove-Variable -Name HDD4GBLabel -Force
    Remove-Variable -Name HDD4GBLetter -Force
    }

    $hdds =  New-Object System.Collections.ArrayList
    If(!($hdd1 -eq $null)){$hdds.add($hdd1) | out-null}
    else {}
    If(!($hdd2 -eq $null)){$hdds.add($hdd2) | out-null}
    else {}
    If(!($hdd3 -eq $null)){$hdds.add($hdd3) | out-null}
    else {}
    If(!($hdd4 -eq $null)){$hdds.add($hdd4) | out-null}
    else {}


    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail

    Monday, August 25, 2014 8:25 PM
  • I can only offer general advice, which is: "Don't use multi-numbered variables to store data." Use an array instead.

    We really don't have the resources to rewrite scripts (particularly to overcome fundamental design deficiencies such as this). We can, however, answer specific questions.


    -- Bill Stewart [Bill_Stewart]

    Monday, August 25, 2014 8:29 PM
  • Id love to figure out how I can store the data differently in regards to this situation.  it was not optimal but this is how the csv is spit out from access so I am stuck working with what I have access to.  I guess since the code in my last post works I will just go with it ugly or not.

    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail

    Monday, August 25, 2014 8:37 PM
  • Id love to figure out how I can store the data differently in regards to this situation.  it was not optimal but this is how the csv is spit out from access so I am stuck working with what I have access to.  I guess since the code in my last post works I will just go with it ugly or not.

    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail

    What CSV.  No CSV ever looked like that.  Post the CSV file.  I bet you extracted it as a list and not a CSV.


    ¯\_(ツ)_/¯

    Monday, August 25, 2014 9:12 PM
  • If the original data is in an Access table, then it seems that whoever set up the table is unfamiliar with normalization. (That's not really a topic for a scripting forum, either.)

    It also seems to me that you are asking questions that are outside the scope of this forum. We can answer specific scripting questions, but a complete redesign is probably best handled by hiring a consultant.


    -- Bill Stewart [Bill_Stewart]

    Monday, August 25, 2014 9:13 PM
  • Thanks anyway guys I came up with another way around the situation.  JRV That was not the actual csv listed above. For testing purposes I just wrote the variables in.  I ended up just using an invoke-command to move the csv in to the guest os and then grab my variables from there.  

    Just for clarification the access database provides a form that allows users to put in the specifics for a server build.  They put in the system stats which change from server to server.  From there I created a button on the form that exports the fields to a csv and then calls a powershell session running off of a script to build the vm based of each datacenter specific template.  It configures all the settings based on the cluster, once built it needed to go in to the OS and start some services, rename some accounts, format the drives and add members to the local admins.  I have been banging my head on the automated drive formatting because the number of drives in the system changes from server to server as do the drive letters and labels and i needed this to be generic enough to do all that on a tight deadline.


    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail

    Tuesday, August 26, 2014 10:15 PM
  • It is a design problem.  If you design the access tables correctly none of this is necessary.


    ¯\_(ツ)_/¯

    Tuesday, August 26, 2014 10:17 PM
  • Hopefully I will get a chance to mention that to the dept that owns the database.  All I was signed on for was to figure out how to take what they gave me and make it happen lol.

    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail

    Tuesday, August 26, 2014 10:25 PM
  • Hopefully I will get a chance to mention that to the dept that owns the database.  All I was signed on for was to figure out how to take what they gave me and make it happen lol.

    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail

    But you never posted what the CSV looks like.  Either it is not a CSV or it is some weird invention by someone who does not understand data.

    It is also possible that you just don't understand how to use a CSV.

    Which is it?  Post the CSV.


    ¯\_(ツ)_/¯

    Tuesday, August 26, 2014 10:29 PM
  • Servername,VMWareHost,VMWareDatastore,vCPU,vRAM,AdditionalHDD1,Drive1Name,Drive1Letter,AdditionalHDD2,Drive2Name,Drive2Letter,AdditionalHDD3,Drive3Name,Drive3Letter,AdditionalHDD4,Drive4Name,Drive4Letter,VMwareVirtualNetwork,ServerOwner,OwningDept,CRQNumber,ApplicationName,VmwareCluster,VMwareResourcePool,DataCenter,OU,Ipaddress,NetMask,DefaultGateway,PrimaryDNS,SecondaryDNS,IPMode,AdminPassword,DomainName,Template
    LiamsBuildTest,,,2,4,35,Data,d,30,Backup,s,,,,,,,,,,req0091,Sql,,,,,,255.255.255.0,,,,Static,,,

    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail

    Tuesday, August 26, 2014 10:36 PM
  • So you have all of these in a variable already.  The variable is the row in the CSV.

    $csv=Import-Csv file.csv

    $csv[0] | fl

    That will give you all as a list.

    $csv | ft

    will give you a nice table.

    I do not see what the issue is.


    ¯\_(ツ)_/¯

    Tuesday, August 26, 2014 10:40 PM
  • Like this:


    ¯\_(ツ)_/¯

    Tuesday, August 26, 2014 10:43 PM
  • the problem came from passing the information to the guest using invoke-vmscript or invoke-command and then having to use diskpart as this is all on 2k8r2. Probably made it harder than I needed to honestly.

    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail

    Tuesday, August 26, 2014 10:45 PM
  • It was all down to the diskpart on the guest running a foreachloop to make sure all the drives that were requested were being formatted using an invoke command without adding a script to the template to call as they did not want anything added to the template.

    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail

    Tuesday, August 26, 2014 10:51 PM
  • This is how to normalize the data:

    $new=@()
    $new+=$csv|select @{n='DriveName';E={$_.Drive1Name}},@{n='DriveLetter';E={$_.Drive1Letter}}
    $new+=$csv|select @{n='DriveName';E={$_.Drive2Name}},@{n='DriveLetter';E={$_.Drive2Letter}}
    $new+=$csv|select @{n='DriveName';E={$_.Drive3Name}},@{n='DriveLetter';E={$_.Drive3Letter}}
    $new
    

    You now have a table of values for drives.


    ¯\_(ツ)_/¯

    • Marked as answer by Liam Silva Tuesday, August 26, 2014 11:40 PM
    Tuesday, August 26, 2014 10:52 PM
  • I am answering the question you asked and not telling you how to use diskpart which is not part of the question.


    ¯\_(ツ)_/¯

    Tuesday, August 26, 2014 10:53 PM
  • What ended up making it easier was getting approved to use enable-psremoting as long as I disable at the end per their security.  I was trying to make it work with invoke-vmscript with does not allow for -args so passing info was a PITA.  Now that they are allowing the psremoting I am using invoke-command so I can pass the args I need.

    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail

    Tuesday, August 26, 2014 10:55 PM
  • Thank you that would clean it up a little.  Sadly i dont think that would have helped with invoke-vmscript untill I can figure out how to get the variables to pass.  I know that if you quote out the scripttext variable it is supposed to pass but when I was attempting to pass an array they guest OS saw it as a system object instead of the data.

    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail

    Tuesday, August 26, 2014 11:07 PM
  • you are correct.  It was my fault for not starting with the full set of information.  However the script is running right now and the diskpart portion is working.

    Dislaimer 1:As usual I could be way off so no playing like I'm Frankenstein. Disclaimer 2: my Speeling and proofing skills are teh fail

    Tuesday, August 26, 2014 11:28 PM