Using hashtable to list snapshots by servername

Tagged: 

This topic contains 6 replies, has 4 voices, and was last updated by Profile photo of Daniel Krebs Daniel Krebs 1 week ago.

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #54302
    Profile photo of Tony Wainwright
    Tony Wainwright
    Participant

    Hi

    I'm trying to list all snapshots on each host and though a hashtable would be the way to go. I've come up with this:

    Clear-Host
    $Output = @{}
    $VMHosts = Get-VMHost -ComputerName S1, S2, S3, S4, S5, S6
    
    ForEach ($VMHost in $VMHosts.Name) {
        $VMS = Get-VMSnapshot -VMName * -ComputerName $VMHost
        ForEach ($VM in $VMS) {
            $Output.Add{Server = $VMHost} #, $VM.VName, $VM.Name,$VM.SnapshotType
        }
    }

    I want to see something like:

    Server   VMName               Name                                   SnapshotType
    S1       Centos.FogServer05    Centos.... - (16/08/2016 - 09:53:55)  Standard
    

    but I am getting this error:

    Cannot find an overload for "Add" and the argument count: "1".
    At D:\Scripts\VMs\Get-SnapshotByServer.ps1:8 char:9
    +         $Output.Add{Server = $VMHost} #, $VM.VName, $VM.Name,$VM.Snap ...
    +         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], MethodException
        + FullyQualifiedErrorId : MethodCountCouldNotFindBest

    What am I missing?
    Thanks
    Tony

    #54303
    Profile photo of Dan Potter
    Dan Potter
    Participant

    $output.add('server','vmhost')

    #54306
    Profile photo of Dan Potter
    Dan Potter
    Participant

    Note: A pscustomobject is easier to deal with multiple properties.

    [pscustomobject]@{

    server = $vmhost
    name = $name
    snapshot = $snapshot
    etc = '...'

    }

    #54311
    Profile photo of Daniel Krebs
    Daniel Krebs
    Participant

    As Dan mentioned you probably want to do something like below:

    Clear-Host
    $Output = @{} # this creates a hashtable
    # I believe what you actually want is an array of hashtables to collect your information
    
    # For performance reasons it is best to use the ArrayList class instead of just @() because it can grow 
    # dynamically added without creating a new copy in-memory everytime an items is being added. 
    # You can use your favorite search engine to find a comparison between @() and ArrayList.
    $Output = New-Object -TypeName 'System.Collections.ArrayList'
    $VMHosts = Get-VMHost -ComputerName S1, S2, S3, S4, S5, S6
    
    ForEach ($VMHost in $VMHosts.Name) {
        $VMS = Get-VMSnapshot -VMName * -ComputerName $VMHost
        ForEach ($VM in $VMS) {
    
            $SnapshotInfo = [PSCustomObject]@{
                Server = $VMHost
                VMName = $VM.VMName
                Name = $VM.Name
                SnapshotType = $VM.SnapshotType
            }
    
            $Output.Add($SnapshotInfo)
        }
    }
    
    #54312
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    Another way to try is a calculated property and avoid all of the for loops:

    $results = Get-VMHost -ComputerName S1, S2, S3, S4, S5, S6 |
               Select *, @{Name="Snapshots";Expression={Get-VMSnapshot -VMName * -ComputerName $_.Name}}
    
    #54314
    Profile photo of Tony Wainwright
    Tony Wainwright
    Participant

    Thanks all, got it working.

    @Dan Potter: used your suggestion and was about to post back as I wanted to put the output into a variable for reporting...
    @daniel Krebs: Your script was the final piece.

    Cheers

    #54315
    Profile photo of Daniel Krebs
    Daniel Krebs
    Participant

    Great. I'm glad you've found my answer helpful.

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

You must be logged in to reply to this topic.