none
Getting error when adding psobject in array RRS feed

  • Question

  • Hi All,

    I am creating a GUI tool using PowerShell. 

    $data_array = @()
        $precheck.Add_Click({ 
                               
                               foreach ($server in $serverlist)
                                        {
                                           $status_data = Pre-check -serverlist $server -datapath $datapath -logpath $logpath -threshhold_freediskspace $threshhold_freediskspace
                                           $status_C =       $($status_data.status)
                                           try { 
                                                      $vm_data = get-vm $server -ErrorAction Stop
                                                      $datastore_data = (get-vm $server | Get-Datastore -ErrorAction Stop | sort -Property freespaceGB -Descending)[0]
                                                      if ( $($datastore_data.FreeSpaceGB - (2 * $vm_data.ProvisionedSpaceGB)) -ge $datastore_threshold )
                                                                  {
                                                                     $status_datastore = "yes"
                                                                   }
                                                       else    {
                                                                     $status_datastore = "no"
                                                                   } 
                                                 }
                                            catch {
                                                    $er_msg = $_.exception.message
                                                   }
                                                    
                                           $prop = [ordered]@{ server = $server
                                                              'Cdrive status' = $status_C
                                                              'datastore status' = $status_datastore
                                                              }
                                           $list1 = New-Object -TypeName psobject -Property $prop
                                           $data_array += $list1
                                        }
                               $data_array | Out-GridView -Title "Pre-Check Results" -Wait
                               $data_array | export-csv "$logpath\server_pre_check_status.csv" -NoTypeInformation
        
                               $1.controls.add($lable3)
                               $1.controls.add($text_box4_share)
                             })

     If i declare a variable outside the add_click event, i always get an below error. 

    If i declare the array variable in global:var format, it still get the same error. 

    Method invocation failed because [System.Management.Automation.PSObject] does not contain a method named 'op_Addition'.
    At D:\Asharma5\Scripts\server_upgrade_2k12\gui_tool.ps1:254 char:40
    +                                        $data_array += $list1
    +                                        ~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
        + FullyQualifiedErrorId : MethodNotFound

    Saturday, January 11, 2020 7:57 AM

All replies

  • Just declare the array inside the script block and it will work assuming you exceptions are handled in some way.

    The following is a cleaner and less confusing way to do this.

    $precheck_Click = {
        
        $data_array = @()
                               
        foreach($server in $serverlist){
            $status_data = Pre-check -serverlist $server -datapath $datapath -logpath $logpath -threshhold_freediskspace $threshhold_freediskspace
                
            try { 
                $vm_data = get-vm $server -ErrorAction Stop
                $datastore_data = (get-vm $server | Get-Datastore -ErrorAction Stop | sort -Property freespaceGB -Descending)[0]
                if(($datastore_data.FreeSpaceGB - (2 * $vm_data.ProvisionedSpaceGB)) -ge $datastore_threshold){
                    $status_datastore = 'yes'
                }else{
                    $status_datastore = 'no'
                } 
            }
            catch{
                # WHAT HAPPENS WHEN YOU GET AN ERROR THIS HIDES ALL ERRORS
                $er_msg = $_.exception.message
            }
                    
           $data_array += [pscustomobject]@{ 
                Server = $server
                'Cdrive status' = $status_data.status
                'datastore status' = $status_datastore
            } } $data_array | Out-GridView -Title "Pre-Check Results" -Wait $data_array | export-csv "$logpath\server_pre_check_status.csv" -NoTypeInformation $1.controls.add($lable3) $1.controls.add($text_box4_share) } $precheck.Add_Click($precheck_Click)


    \_(ツ)_/


    • Edited by jrv Saturday, January 11, 2020 11:34 AM
    Saturday, January 11, 2020 11:31 AM
  • The following would be safer and give you more useful information:

    $precheck_Click = {
        
        $data_array = @()
        $ErrorActionPreference = 'Stop'
        
        foreach($server in $serverlist){
            
            try {
                $status_data = Pre-check -serverlist $server -datapath $datapath -logpath $logpath -threshhold_freediskspace $threshhold_freediskspace
                $vm_data = get-vm $server
                $datastore_data = (get-vm $server | Get-Datastore | sort -Property freespaceGB -Descending)[0]
                if(($datastore_data.FreeSpaceGB - (2 * $vm_data.ProvisionedSpaceGB)) -ge $datastore_threshold){
                    $status_datastore = 'yes'
                }else{
                    $status_datastore = 'no'
                }
            }
            catch{
                # WHAT HAPPENS WHEN YOU GET AN ERROR THIS HIDES ALL ERRORS
                $er_msg = $_.exception.message
                $status_datastore = 'error'
            }
                    
           $data_array += [pscustomobject]@{ 
                Server = $server
                'Cdrive status' = $status_data.status
                'datastore status' = $status_datastore
            }
        }
        
        $data_array | Out-GridView -Title 'Pre-Check Results' -Wait
        $data_array | export-csv "$logpath\server_pre_check_status.csv" -NoTypeInformation
    
        $1.controls.add($lable3)
        $1.controls.add($text_box4_share)
    }
    $precheck.Add_Click($precheck_Click)
    


    \_(ツ)_/

    Saturday, January 11, 2020 11:41 AM
  • The following two lines are redundant and in conflict:

    $vm_data = get-vm $server
    $datastore_data = (get-vm $server | Get-Datastore | sort -Property freespaceGB -Descending)[0]

    This would be the safe way to do this:

                $vm = get-vm $server
                $datastores = @($vm | Get-Datastore | sort -Property freespaceGB -Descending)
                $usedspace = $datastores[0].FreeSpaceGB - (2 * $vm.ProvisionedSpaceGB)
                if($usedspace -ge $datastore_threshold){
                    $status_datastore = 'yes'
                }else{
                    $status_datastore = 'no'
                }

    Unfortunately the following line can return multiple VMs:

    $vm = get-vm $server

    Which will cause an error later in the code.


    \_(ツ)_/


    • Edited by jrv Saturday, January 11, 2020 12:04 PM
    Saturday, January 11, 2020 11:59 AM
  • $vm = get-vm $server

    This won't return multiple values as names in VMware Vcenter are always unique.

    the issue may be is I was declaring the $global:data_array outside, but inside i am just writing as $data_array. 

    The below worked fine for me.

    $global:data_array = $global:data_array + $list1

    I replaced every $data_array with $global:data_array. 

    Saturday, January 11, 2020 1:27 PM
  • So your names are not server names but are VM names. You need to name variables correctly. The code implies VIServer names.

    Also it is not clear that a VM object will return a single datastore or all data stores on the VIServer.  In that case the first data store is not necessarily the one associated with the target VM.  You need to rethink the design and discover how to get what you want without returning arbitrary arrays of objects.

    Of course vSphere is not a Windows product and we do not really support it here.  The vShere support site does support PowerShell with their products and supports the CmdLets which are created by them.  Posting to that site will help sort out the best way to do this.

    Some users here do use vSphere so they might have some ideas to help.  Mostly I am assessing your original issue and why it might be causing errors.  Without the code and a way to test it there is a limit to what we can do or assume.

    The examples I posted were to help you simplify the code design so you might be able to see why your code is failing.  Running under a debugger would be the easiest way to understand your issue but your code could easily confuse a debugger.  The simplified example can all ow you to add a line or two that would surface the cause.


    \_(ツ)_/

    Saturday, January 11, 2020 2:10 PM