Creating a tool – “Expanding” Custom PSObject

This topic contains 2 replies, has 2 voices, and was last updated by  Alex Aymonier 3 weeks, 6 days ago.

  • Author
    Posts
  • #90055

    Alex Aymonier
    Participant

    Hey all, hope you all have good Christmas/Holiday.

    I'm creating a tool to capture data from vSphere for any of our VM's so we have a point in time snapshot of the current set up prior to actioning any change on that VM. This data is exported to csv and attached to the change as part of the pre checks in case of roll back. I have sub tools that capture different elements of the VM (Hardware config, Storage config, IP config etc.) and want to combine them together in one object (if possible) so that we can then feed that info to other tools or exported to csv giving us one line per VM with all of its parts.
    Now if the VM has one IP Address and one Hard Disk this is simple. I can create the one object and everyone is happy. However VMs can have multiple IPs and multiple disks. Below are the examples of the output for Server 1 (One Hard Disk), Server 2 (Three Hard Disks) and one non existent vm (bob) which outputs a blank object

    ##Basic VM info

    PS C:\> Get-vSphereVMData -ComputerName server1,server2,bob
    
    VMName     : server1
    Status     : True
    PowerState : PoweredOn
    vCpu       : 2
    MemoryGB   : 4
    Datastore  : LUN01
    VMXFile    : [LUN01] server1/server1.vmx
    vCenter    : vc01
    Host       : esx01.operations.local
    OS         : Microsoft Windows Server 2012 (64-bit)
    
    VMName     : server2
    Status     : True
    PowerState : PoweredOn
    vCpu       : 4
    MemoryGB   : 12
    Datastore  : LUN01
    VMXFile    : [LUN01] server2/server2.vmx
    vCenter    : vc01
    Host       : esx01.operations.local
    OS         : Microsoft Windows Server 2012 (64-bit)
    
    vAppName   : bob
    Status     : False
    PowerState :
    vCpu       :
    MemoryGB   :
    Datastore  :
    VMXFile    :
    vCenter    :
    Host       :
    OS         :
    

    ##Hard disk configuration per vm

    PS C:\> Get-vSphereVMStorageData -ComputerName server1,server2,bob
    
    VM         : server1
    Status     : True
    SCSI       : 0:0
    HD         : Hard disk 1
    Label      : SCSI controller 0
    SCSIType   : LSI Logic
    Filename   : [LUN01] server1/server1_1.vmdk
    CapacityGB : 64
    
    VM         : server2
    Status     : True
    SCSI       : 0:0
    HD         : Hard disk 1
    Label      : SCSI controller 0
    SCSIType   : LSI Logic SAS
    Filename   : [LUN01] server2/server2.vmdk
    CapacityGB : 60
    
    VM         : server2
    Status     : True
    SCSI       : 0:1
    HD         : Hard disk 3
    Label      : SCSI controller 0
    SCSIType   : LSI Logic SAS
    Filename   : [LUN01] server2/server2_2.vmdk
    CapacityGB : 100
    
    VM         : server2
    Status     : True
    SCSI       : 1:0
    HD         : Hard disk 2
    Label      : SCSI controller 1
    SCSIType   : LSI Logic SAS
    Filename   : [LUN01] server2/server2_1.vmdk
    CapacityGB : 200
    
    WARNING: Errors happened when attempting to find VM bob in vc01
    VM         : bob
    Status     : False
    SCSI       :
    HD         :
    Label      :
    SCSIType   :
    Filename   :
    CapacityGB :
    

    I'm foreaching through each disk and grabbing the data I need and outputting one object per disk. Server 1 has one disk, Serer 2 has three disks and bob does not exist.

    The thing that is screwing with my head, is stitching the data together per server. Like i said above it's easy when the VM has one disk but i can't figure out how to handle if a VM has multiple disks. Looking at the the max number of disks a VM can have it can be up to 64 disks. (BTW this question is only looking at disks but i am also having the same problem with multiple IP/Network cards too). Am i going in the right direction with an expanding object (if that's even possible) or am i diving down a Inception rabbit hole going the wrong direction?

  • #90110

    Michael Orellana
    Participant

    Hey Alex-

    To my understanding, if a VM has multiple values for one property you would like to make a custom object containing all those values. Now I cant say that I have the perfect solution for you; however, I was in a similar situation when trying to query active directory users and grab their memberships to export to csv with all group names in separate cells. While exporting to a csv, all the objects must contain the same header quantity and header names in order for this to work. So If I had one user with 23 memberships then all new custom objects I was generating needed to have 23 membership fields. I solved this by gathering the number of groups each user was apart of and just storing the count value in an array and then grabbing the highest number (fig 1). From there, I would create the custom psObject and then run it through a for loop to add new custom note properties equal to the highest number of group memberships (Fig 2). Finally I would start filling in the data gathered, using another for loop. Once again, not saying this is your solution or the best one but maybe it can help get you moving in the right direction.

    Fig 1.

    $adUsers = Get-ADUser -Filter * -Properties DisplayName, SamAccountName, Enabled, MemberOf
    
    $memberCount = @()
    Foreach ($a in $adUsers) {
        $memberCount += $a.MemberOf.Count
    }
    
    $count = $memberCount | Measure-Object -Maximum | Select-Object -ExpandProperty Maximum
    

    Fig 2.

    $result = @()
    ForEach ($a in $adUsers) {
        $groupName = $a.MemberOf | Get-ADGroup | Select -ExpandProperty Name 
        # Create new psObject. [ordered] was a life saver because hashtables dont retain property order.
        $obj = New-Object psobject -Property ([ordered] @{
    
                DisplayName = $a.DisplayName
                SamAccount  = $a.SamAccountName
                Enabled     = $a.Enabled
                Group       = $groupName | Select -First 1
            })
        # Create new alias properties based on the number stored in $count variable
        For ($i = 0; $i -lt $count; $i++) {
            $obj | Add-Member -MemberType NoteProperty -Name "Group_$i" -Value $null -Force
        }
    
  • #90131

    Alex Aymonier
    Participant

    Thanks Michael that has put me in a good direction. I'll let you know how i go.

You must be logged in to reply to this topic.