VmWare and Powershell multi-valued attributes

This topic contains 8 replies, has 2 voices, and was last updated by Profile photo of Dan Gheorghe Dan Gheorghe 8 months, 1 week ago.

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #34213
    Profile photo of Dan Gheorghe
    Dan Gheorghe
    Participant

    Hello guys and Happy New Year!!
    I have a question about multi-valued attributes and how to export them as csv.
    While I know how to work with multi-valued attributes I've come to a dead end with this script that I am writing.
    Here are the details:
    I have to export a csv file that will contain VMName, HardDiskName, FileName etc.
    At first I tried this approach (1):
    $hdd = Get-HardDisk -VM "vmname" -DiskType RawPhysical| select Parent, Name
    $props = @{'VMName' = $hdd.parent
    'HDDName' = $hdd.name

    }
    $obj = New-Object -TypeName PSObject -Property $props
    #Write-Output $obj
    $obj | Export-Csv vm.csv -NoTypeInformation
    I quickly realised that this approach won't work because I am dealing with multi-valued attributes and I won't be able to export them properly.
    ...than I tried this (approach 2)

    $hdd = Get-HardDisk -VM "vmname" -DiskType RawPhysical| select @{Name='VmName';Expression={[string]::join(“;”, ($_.parent))}}, @{Name='HDDName';Expression={[string]::join(“;”, ($_.name))}}
    $props = @{'VMName' = $hdd.parent
    'HDDName' = $hdd.name
    }

    $obj = New-Object -TypeName PSObject -Property $props
    #Write-Output $obj
    $obj | Export-Csv vm.csv -NoTypeInformation

    Needles to say that this did not work either

    Some attributes are not multi-valued and I could get them with approach 1 but I cannot get the multi-valued attributes.

    if I do this
    $hdd = Get-HardDisk -VM svwdbn21 -DiskType RawPhysical| select @{Name='VmName';Expression={[string]::join(“;”, ($_.parent))}}, @{Name='HDDName';Expression={[string]::join(“;”, ($_.name))}},`
    @{Name='FileName';Expression={[string]::join(“;”, ($_.filename))}}, @{Name='DeviceName';Expression={[string]::join(“;”, ($_.devicename))}},`
    @{Name='CanonicalName';Expression={[string]::join(“;”, ($_.ScsiCanonicalName))}}| Export-csv test.csv

    I can get almost all details I need except LUN info which I am getting it with the following piece of code:

    $hdd = Get-HardDisk -VM "vmname" -DiskType RawPhysical| select parent, name, filename, devicename, ScsiCanonicalName
    $Lun = Get-SCSILun $hdd.SCSICanonicalName -VMHost $vm.vmhost
    $lunpaths=$lun|Get-ScsiLunPath
    $luns = $lunpaths | select name, sanid, State, Preferred
    $luns

    ... and here is where I got really stuck.
    I need a way to combine in one csv file all the multi-valued atributes and LUN info which right now is stored in $luns.
    Any ideas/help will be much appreciated.
    Thank you

    #34225
    Profile photo of Matt Bloomfield
    Matt Bloomfield
    Participant

    Please can you give some sample data for $luns and the output you would like in the CSV. It's hard to answer the question without knowing specifically what data you have and what you want the CSV file to look like.

    If you're just looking to get a multivalued property or array in a single cell then I think you're working along the right lines using the join method. Here's a quick example with Win32_LogicalDisk

    $disks = Get-WmiObject Win32_LogicalDisk | Select-Object DeviceId,VolumeName
    
    $obj = [PSCustomObject] @{
    
        Id   = $disks.DeviceId -join ';'
        Name = $disks.VolumeName -join ';'
      
    }
    
    $obj | ConvertTo-Csv
    
    #34226
    Profile photo of Dan Gheorghe
    Dan Gheorghe
    Participant

    Hi Matt and thank you.
    I do not have some sample data for $luns. I have to be at work to be able to get that data but you gave me an idea
    All the info that I need (with the exception of VmHost) I can get it from Get-HardDisk so please follow my logic here and let me know if I make sense:

    What do you think?
    Thank you Matt

    #34231
    Profile photo of Matt Bloomfield
    Matt Bloomfield
    Participant

    Yes, that's the kind of approach I would take and I think using the second options for the luns should work.

    In the CSV, that will give you columns something like this:

    VMName, ... ,LunName,SANId,State,Preferred
    VM01, ... ,LUN0;LUN3;LUN5,SAN0;SAN1;SAN2,Online;Offline;Online,No;Yes;No
    VM02, ... ,LUN7;LUN8,SAN1;SAN2,Online;Offline,Yes;No
    
    #34248
    Profile photo of Dan Gheorghe
    Dan Gheorghe
    Participant

    Hi Matt,
    this is working in the sense that I am getting all the info that I need but the .csv file is giving me what I really want.
    Right now as you mentioned i get all the info on one row:
    HardDisk LunName FileName ...
    Hdd1;hdd2; lun1;lun2;lun3 filename1;filename2...
    what i really want is:
    HardDisk LunName FileName
    Hdd1 lun1 filename1
    hdd2 lun2 filename2
    hdd3 lun3 filename3
    Is this possible?
    Thank you again Matt

    #34256
    Profile photo of Matt Bloomfield
    Matt Bloomfield
    Participant

    That should be possible using a foreach loop and a collection of objects. Here's a working example with Win32_LogicalDisk as PoC:

    $disks = Get-WmiObject Win32_LogicalDisk | Select-Object DeviceId,VolumeName
    
    $objColl = @()
    
    foreach ($disk in $disks) {
    
        $obj = [PSCustomObject] @{
    
            Id   = $disk.DeviceId
            Name = $disk.VolumeName
      
        }
    
        $objColl += $obj
    
    }
    
    $objColl | Export-Csv F:\report.csv -NoTypeInformation
    

    I can't test your code but I imagine it would look something like this:

    $vm = Get-VM "vnname"| select name,VMHost
    $hdd = Get-HardDisk -VM "vmname" -DiskType RawPhysical| select Parent, Name, Filename, SCSICanonicalName, DeviceName
    $Lun = Get-SCSILun $hdd.SCSICanonicalName -VMHost $vm.vmhost
    $lunpaths=$lun|Get-ScsiLunPath
    $luns = $lunpaths | select name, sanid, State, Preferred
    
    $objColl = @()
    
    foreach ($lun in $luns) {
          
        $props = @{'VMName' = $hdd.parent 
            'HDDName' = $hdd.name 
            'FileName' = $hdd.filename 
            'DeviceName' = $hdd.devicename 
            'CanonicalName' = $hdd.scsicanonicalname 
            'LunName' = $luns.name 
            'SANId' = $luns.sanid
            'State' = $luns.state
            'Preferred' = $luns.preferred 
          
        }
    
        $obj = New-Object -TypeName PSObject -Property $props
    
        $objColl += $obj
    
    }
    
    #Write-Output $obj
          $objColl | Export-Csv vm.csv -NoTypeInformation
    
    #34258
    Profile photo of Dan Gheorghe
    Dan Gheorghe
    Participant

    Almost there Matt. This is what I am getting when I run the script.
    I won't take more of your time. I will have to figure out this all by myself now.
    Thank you again for your help.
    HDDName LunName FileName SANId Preferred DeviceName State CanonicalName VMName
    System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[]
    System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[]
    System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[]
    System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[]
    System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[]
    System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[]
    System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[]
    System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[] System.Object[]

    #34272
    Profile photo of Matt Bloomfield
    Matt Bloomfield
    Participant

    Looks like you've still got collections for those properties. I'm sure a combination of the techniques will get you where you need to be. I'm happy to continue looking at it if you want to post some sample data. If not, hopefully some combination of the above will get you what you're after.

    #34277
    Profile photo of Dan Gheorghe
    Dan Gheorghe
    Participant

    Thank you Matt.
    Would it be possible to take this off-line for now until we sort this out and post the code after we are done.
    I am afraid that this thread will get too long.
    I've made some changes to the code and I would like to show them to you.

Viewing 9 posts - 1 through 9 (of 9 total)

You must be logged in to reply to this topic.