header1   header
header
header Register : : Login header
header
connector   connector
menuleft menuright
submenu   submenu
left
'System.OutOfMemoryException' was thrown
Last Post 21 Jun 2011 06:23 AM by itchygee. 6 Replies.
Printer Friendly
  •  
  •  
  •  
  •  
  •  
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages Resolved
itchygeeUser is Offline
New Member
New Member
Posts:4
Avatar

--
20 Jun 2011 03:16 PM
    I've trying to figure out why I keep getting 'System.OutOfMemoryException's. Sorry for the formatting, the web form wouldn't retain it but it is readable. I'm trying to get all the VM guest hostnames and their OS exported to a CSV.... Thank in advance


    Get-View : 6/20/2011 4:36:40 PM Get-View Exception of type 'System.OutOfMemoryException' was thrown. At C:\scripts\queryos\OSguest.ps1:23 char:30 + foreach ($vmView in (Get-View <<<< -ViewType VirtualMachine)) + CategoryInfo : NotSpecified: (:) [Get-View], VimException + FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInterop. GetVIView
    ----

    Add-PSsnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
    # vCenter list
    $VCenters = @()
    $VCenters += "Vcenter1"
    $VCenters += "Vcenter2"
    $VCenters += "Vcenter3"
    $VCenters += "Vcenter4"
    $VCenters += "Vcenter5"
    $VCenters += "Vcenter6"
    $VCenters += "Vcenter7"
    $VCenters += "Vcenter8"
    $VCenters += "Vcenter9"

    ForEach ($vCenter in $vCenters)
    {
    Connect-VIServer $vCenter
    $AllCLusters = Get-Cluster | Sort-Object
    }
    ForEach ($Cluster in $AllClusters)
    {
     $report = @() foreach ($vmView in (Get-View -ViewType VirtualMachine))
    {
    $report += $vmView | Select-Object @{Name="VMName"; Expression={$_.Name}},
    @{Name="GuestVersion"; Expression={$vmView.Guest.GuestFullName}}
    }}

    $report | Export-Csv "C:\scripts\queryos\results.csv" -NoTypeInformation
    Disconnect-VIServer * -confirm:$false -force:$true
    Marco ShawUser is Offline
    Veteran Member
    Veteran Member
    Posts:1684
    Avatar

    --
    20 Jun 2011 04:07 PM
    1. Make sure you're using PowerShell v2.
    2. Try the VMware PowerCLI forums: http://www.vmware.com/go/powercli
    itchygeeUser is Offline
    New Member
    New Member
    Posts:4
    Avatar

    --
    20 Jun 2011 04:13 PM
    It's Windows 7.
    halr9000User is Offline
    PowerShell MVP, Site Admin
    Advanced Member
    Advanced Member
    Posts:565
    Avatar

    --
    20 Jun 2011 04:23 PM
    I can suggest several improvements to how this script is written, but before I do, let me ask this: how many VMs do you have in each vCenter? The error you are seeing has a rather obvious cause. The process hit a memory limit. Why don't you run the script with task manager open and see what kind of memory consumption you are seeing? Is it huge? I'm betting it is and that you've got a really large environment. At least you are thinking to use Get-View--that is a great way to scale with PowerCLI in a large environment. But you might need to examine how this loop is being created and instead do things in a more streaming fashion. using Foreach this way will definitely load up everything in memory before moving on. Contrast that with foreach-object which will perform an operation, then destroy what's in the loop (freeing memory), then moving to the next operation.

    Hit us back with a bit about your environment, and I can expand.

    But Marco's advice is also great, the powerCLI forums are where the VMware experts hang out. :)
    Community Director, PowerShellCommunity.org
    Co-host, PowerScripting Podcast
    Author, TechProsaic
    itchygeeUser is Offline
    New Member
    New Member
    Posts:4
    Avatar

    --
    20 Jun 2011 05:05 PM
    You guessed right, we've got about two dozen clusters with 4 to 250 VMs on each cluster. My memory usage did shoot up to 700mb at its peak. I figured it was the way I wrote the script but it was the best way that I knew how. I planned on posting ok the other forums but thought Id try you guys out and see what kind of input I could get. is the memory limitation on my client side, you think?
    halr9000User is Offline
    PowerShell MVP, Site Admin
    Advanced Member
    Advanced Member
    Posts:565
    Avatar

    --
    21 Jun 2011 05:18 AM
    • Accepted Answer
    Here are some just general tips. Try these and see how it improves the memory usage.

    1. Don't do += here. It's totally unnecessary. In this case, it won't impact memory because we're talking about a short array of strings, but it really can because += will create a duplicate object in memory during the operation. Better choice is to just build the array in one statement, e.g. $vcenter = @( "vcenter1", "vcenter2", "vcenter3" )

    2. I see no reason to do the connect and disconnects in the loop. Do them all up front. Honestly, unless you are talking about a scheduled job that has to run in its own session, I connect in my powershell profile and only seldomly disconnect, and I leave that logic out of my scripts, but I suppose that is a preference thing. Putting it in the loop however is taking up needless time. Also note that I find that the first operation following a connect is very slow. Connect-VIServer will accept multiple host names in an array, did you know that? You can actually work with more hosts simultaneously than is possible using the GUI. Just try it: connect-viserver $vcenter

    3. As mentioned before, foreach will do everything inside the loop before continuing, thus everything that happens inside the {}'s will add up to more RAM usage. Often this is fine, but obviously those objects returned from Get-View are large enough and you have enough of them such that this is an issue for you and is the main cause of your memory consumption. Get-View -viewtype is very quick, but the objects it returns are also very rich and contain a lot of information. I think you will see that VMware will improve the efficiency of PowerCLI overall to give you more options here. Here's another way to do it:

     
    $viserver = 'server1', 'server2', 'server3'
    connect-viserver $viserver
    get-cluster | get-vm | select Name, { $_.Guest.OSFullName } | export-csv file.csv -notypeinformation


    You could improve the last line by adding the Name=, Expression= stuff.
    Community Director, PowerShellCommunity.org
    Co-host, PowerScripting Podcast
    Author, TechProsaic
    itchygeeUser is Offline
    New Member
    New Member
    Posts:4
    Avatar

    --
    21 Jun 2011 06:23 AM
    I had no idea you could pipe all of that out like that. I pretty much elimiated the for statements. That really shortened the script and memory consumption never went above 100MB. Thanks for the suggestions. That gave me some other ideas on a few of my other scripts that didn't really have a problem but for consistency, I think I will change them. No need to reinforce bad habits.
    You are not authorized to post a reply.


    Active Forums 4.3
    right
    footer   footer
    footer Sponsored by Quest Software • SAPIEN Technologies • Compellent • Microsoft Windows Server 2008 R2 footer
    footer   footer