locked
Combining two cmdlets and extract their MemberType RRS feed

  • Question

  • Hi Guys,

    Being a newb with powershell I would greatly appreciate your help around this issue. I am trying for 2 days now and reading what not to make a report in powershell using Get-VM and Get-VHD,

    What I am trying to achieve is to extract the MemberType of the two so i can then create a custom object, cycle it through and then out to a HTML report,

    Here's an example of what I am doing:

    Get-VM -ComputerName HOST01 | Select-Object VMId | Get-VHD | ConvertTo-HTML –Property path,vhdtype,
    @{label=’Size(GB)’;expression={$_.filesize/1gb –as [int]}},
    @{label=’Capacity(GB)’;expression={$_.size/1gb –as [int]}},
    @{label=’RAM(GB)’;expression={$_.MemoryAssigned/1gb –as [int]}},
    @{label=’vCPU’;expression={$_.ProcessorCount}},
    @{label=’VMName’;expression={$_.VMName}} > “C:\temp\VlatkoTesting\Report51.htm"

    Now I am aware that only the last command is being loaded in ram "Get-VHD" and that I can only read the MemberType from there, I gave a shot to Get-Member on the end there just to prove myself that I am not getting the MemberTypes from Get-VM which in this case I need them :/

    The result I am getting in the HTML file looks something like this:

    path vhdtype Size(GB) Capacity(GB) RAM(GB) vCPU VMName
    C:\ClusterStorage\VM1\C_DRIVE_2012R2.VHDX Dynamic 152 164 0
    C:\ClusterStorage\VM2\C_DRIVE_2012R2.VHDX Dynamic 52 127 0
    C:\ClusterStorage\VM3\C_DRIVE_2012R2.VHDX Dynamic 670 751 0

    <output ommited>

    Getting the assigned disk space vs used disk space works obviously since Get-VHD is the last cmdlet used. Out of ideas! :(

    If you guys have an idea how to put this together I would be very grateful!!!

    Happy Holidays,

    Vlatko Jordanov


    • Edited by Vlatko_Jordanov Thursday, December 20, 2018 3:48 PM Forgot to add more
    Thursday, December 20, 2018 3:45 PM

Answers

  • Unfortunately you don't tell us which members from Get-VM you're after.  A general tip could be to use loops or the parameter -PipelineVariable.

    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Thursday, December 20, 2018 5:16 PM
  • Ho ho ho ... it's Christmas time and I'm in a good mood ... ;-) :-D

    $Head = @'
    <style>
    body {
        color:#333999;
        font-family: Consolas, "Courier New", "Lucida Console", Monospace;
        font-size: 12pt;
    }
    table, td {
      border: 1px solid black;
      border-collapse: collapse;
      padding: 8px;
      text-align: right;
    }
    th {
      border: 2px solid black;
      border-collapse: collapse;
      padding: 15px;
      text-align: center;
    }
    </style>
    
    <title>Host 01 VM Report</title>
    '@
    
    $PostContent = @'
    <p>Here you could add some additional information about</br>the displayed report if you like ;-).</p>
    '@
    
    $RawData = Get-VM -ComputerName HOST01 |
        ForEach-Object {
            $VM = $_
            $VHDList = Get-VHD -VMId $VM.VMID
            Foreach($VHD in $VHDList){
                [PSCustomObject]@{
                    MemoryAssigned = $VM.MemoryAssigned
                    ProcessorCount = $VM.ProcessorCount
                    VMName = $VM.VMName
                    VHDSize = $VHD.FileSize
                    VHDCapacity = $VHD.Size
                }
            }
        } 
    
    $RawData | Format-Table -AutoSize
    
    $RawData | 
        Select-Object -Property VMName,ProcessorCount,
            @{Name='MemoryAssigned_GB';Expression={[MATH]::Round($_.MemoryAssigned/1GB,0)}},
            @{Name='VHDSize_GB';Expression={[MATH]::Round($_.VHDSize/1GB,0)}},
            @{Name='VHDCapacity_GB';Expression={[MATH]::Round($_.VHDCapacity/1GB,0)}} |
                ConvertTo-HTML -Head $Head -PostContent $PostContent |
                    Out-File -FilePath 'C:\temp\Report51.html'

    Of course that's just a suggestion. You are welcome to improve or change the code according to your needs.

    Have a nice Christmas time!


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''


    • Edited by BOfH-666 Thursday, December 20, 2018 9:31 PM
    • Marked as answer by Vlatko_Jordanov Friday, December 21, 2018 10:17 AM
    Thursday, December 20, 2018 9:28 PM
  • You could have say that before ...  ;-)

    $RawData = Get-ClusterNode -Cluster 'Name of your Cluster' | 
        ForEach-Object {
        $ClusterNode = $_
        Invoke-Command -ComputerName $_.Name {
            Get-VM |
                ForEach-Object {
                $VM = $_
                $VHDList = Get-VHD -VMId $VM.VMID
                Foreach ($VHD in $VHDList) {
                    [PSCustomObject]@{
                        ClusterNode    = $ClusterNode.Name
                        VMName         = $VM.VMName
                        MemoryAssigned = $VM.MemoryAssigned
                        ProcessorCount = $VM.ProcessorCount
                        VHDSize        = $VHD.FileSize
                        VHDCapacity    = $VHD.Size
                        VHDPath        = $VHD.Path
                    }
                }
            }
        }
    }
    $RawData
    Of course you have to add the additional column to the html output.

    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''




    • Marked as answer by Vlatko_Jordanov Friday, December 21, 2018 4:09 PM
    • Edited by BOfH-666 Friday, December 21, 2018 4:42 PM removed an unnecessary code line
    Friday, December 21, 2018 1:21 PM

All replies

  • Unfortunately you don't tell us which members from Get-VM you're after.  A general tip could be to use loops or the parameter -PipelineVariable.

    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Thursday, December 20, 2018 5:16 PM
  • Hey BOfH_666

    Thanks for your reply, i will give -PipelineVariable a try for sure, the members from Get-VM I want to loop are MemoryAssigned, ProcessorCount and VMName and from Get-VHD are Size and FileSize,

    Cheers,

    Vlatko

    Thursday, December 20, 2018 5:50 PM
  • Ho ho ho ... it's Christmas time and I'm in a good mood ... ;-) :-D

    $Head = @'
    <style>
    body {
        color:#333999;
        font-family: Consolas, "Courier New", "Lucida Console", Monospace;
        font-size: 12pt;
    }
    table, td {
      border: 1px solid black;
      border-collapse: collapse;
      padding: 8px;
      text-align: right;
    }
    th {
      border: 2px solid black;
      border-collapse: collapse;
      padding: 15px;
      text-align: center;
    }
    </style>
    
    <title>Host 01 VM Report</title>
    '@
    
    $PostContent = @'
    <p>Here you could add some additional information about</br>the displayed report if you like ;-).</p>
    '@
    
    $RawData = Get-VM -ComputerName HOST01 |
        ForEach-Object {
            $VM = $_
            $VHDList = Get-VHD -VMId $VM.VMID
            Foreach($VHD in $VHDList){
                [PSCustomObject]@{
                    MemoryAssigned = $VM.MemoryAssigned
                    ProcessorCount = $VM.ProcessorCount
                    VMName = $VM.VMName
                    VHDSize = $VHD.FileSize
                    VHDCapacity = $VHD.Size
                }
            }
        } 
    
    $RawData | Format-Table -AutoSize
    
    $RawData | 
        Select-Object -Property VMName,ProcessorCount,
            @{Name='MemoryAssigned_GB';Expression={[MATH]::Round($_.MemoryAssigned/1GB,0)}},
            @{Name='VHDSize_GB';Expression={[MATH]::Round($_.VHDSize/1GB,0)}},
            @{Name='VHDCapacity_GB';Expression={[MATH]::Round($_.VHDCapacity/1GB,0)}} |
                ConvertTo-HTML -Head $Head -PostContent $PostContent |
                    Out-File -FilePath 'C:\temp\Report51.html'

    Of course that's just a suggestion. You are welcome to improve or change the code according to your needs.

    Have a nice Christmas time!


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''


    • Edited by BOfH-666 Thursday, December 20, 2018 9:31 PM
    • Marked as answer by Vlatko_Jordanov Friday, December 21, 2018 10:17 AM
    Thursday, December 20, 2018 9:28 PM
  • $Head = @'
    <style>
    body {
        color:#333999;
        font-family: Consolas, "Courier New", "Lucida Console", Monospace;
        font-size: 12pt;
    }
    table, td {
      border: 1px solid black;
      border-collapse: collapse;
      padding: 8px;
      text-align: right;
    }
    th {
      border: 2px solid black;
      border-collapse: collapse;
      padding: 15px;
      text-align: center;
    }
    </style>
    
    <title>VM Report</title>
    '@
    
    $PostContent = @'
    <p>Please review carefully.</p>
    '@
    
    $RawData = Get-VM -ComputerName HOST01 |
        ForEach-Object {
            $VM = $_
            $VHDList = Get-VHD -VMId $VM.VMID
            Foreach($VHD in $VHDList){
                [PSCustomObject]@{
                    MemoryAssigned = $VM.MemoryAssigned
                    ProcessorCount = $VM.ProcessorCount
                    VMName = $VM.VMName
                    VHDSize = $VHD.FileSize
                    VHDCapacity = $VHD.Size
                    VHDPath = $VHD.Path
                }
            }
        } 
    
    $RawData | Format-Table -AutoSize
    
    $RawData | 
        Select-Object -Property VMName,ProcessorCount,
            @{Name='MemoryAssigned_GB';Expression={[MATH]::Round($_.MemoryAssigned/1GB,0)}},
            @{Name='VHDSize_GB';Expression={[MATH]::Round($_.VHDSize/1GB,0)}},
            @{Name='VHDCapacity_GB';Expression={[MATH]::Round($_.VHDCapacity/1GB,0)}},
            @{Name='Path';Expression={$_.VHDPath}}|
                ConvertTo-HTML -Head $Head -PostContent $PostContent |
                    Out-File -FilePath 'C:\temp\VlatkoTesting\SimpleVHDReport67.htm'

    Yes sir !!!!!

    This works like a charm !! however finally I understood the meaning of -PipelineVariable which worked like a charm for my piece as well but I must say your effort and style is way out of my league! 

    Thank you so much for the contribution on this, I've added one more column with the Path property since I needed that as well but the HTML looks pretty neat I must say! :)

    In future I will try to change this to loop through multiple hosts since I've tried now and it throws an error that it cannot locate the VM. I might need to look at other options since I have 8 hosts in cluster, here's the reference of the error:

    Get-VHD : Hyper-V was unable to find a virtual machine with the given criteria.
    At line:32 char:20
    +         $VHDList = Get-VHD -VMId $VM.VMID
    +                    ~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ObjectNotFound: (1186d9bb-497a-4c24-aaf3-ac6cf75734f9:Guid) [Get-VHD], VirtualizationOperationFailedException
        + FullyQualifiedErrorId : ObjectNotFound,Microsoft.Vhd.PowerShell.GetVhdCommand

    Anyway, thank you so much for helping out, much appreciated !!

    Happy Holidays !

    Cheers,

    Vlatko

    Friday, December 21, 2018 12:47 PM
  • You could have say that before ...  ;-)

    $RawData = Get-ClusterNode -Cluster 'Name of your Cluster' | 
        ForEach-Object {
        $ClusterNode = $_
        Invoke-Command -ComputerName $_.Name {
            Get-VM |
                ForEach-Object {
                $VM = $_
                $VHDList = Get-VHD -VMId $VM.VMID
                Foreach ($VHD in $VHDList) {
                    [PSCustomObject]@{
                        ClusterNode    = $ClusterNode.Name
                        VMName         = $VM.VMName
                        MemoryAssigned = $VM.MemoryAssigned
                        ProcessorCount = $VM.ProcessorCount
                        VHDSize        = $VHD.FileSize
                        VHDCapacity    = $VHD.Size
                        VHDPath        = $VHD.Path
                    }
                }
            }
        }
    }
    $RawData
    Of course you have to add the additional column to the html output.

    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''




    • Marked as answer by Vlatko_Jordanov Friday, December 21, 2018 4:09 PM
    • Edited by BOfH-666 Friday, December 21, 2018 4:42 PM removed an unnecessary code line
    Friday, December 21, 2018 1:21 PM
  • Apologies about that :S, seriously.... can't say how much I am grateful for this, it's been a good school to be honest,

    Thanks !!!

    Vlatko

    Friday, December 21, 2018 4:08 PM