Power shell 2 Nested array does not work in Powershell 3

Answered Power shell 2 Nested array does not work in Powershell 3

  • Thursday, January 17, 2013 2:58 PM
     
      Has Code

    Hi Guys,

    I don't know a nicer way to code this but I have been using 2x nested variables to index in an array ( Example: $test[$var1][$var2] ). This used to work in powershell 2.0 but does not work in powershell 3 anymore.

    The reason I did this was I want to WMI  query a pc ( the root variable ) get his disks  ( the first index ) store performance info ( The second index ). because I don't know how many disks there are I used the variable indexer so it would create a variable for each disk it encounterd.

    Is there anny way we can get this working in Powershell 3 , or is there a nicer way to program this.

    this is the relevant part of the script I use:

    while ( $perfloop -le $perfloopcount )
    	{
    
    Write-Progress -activity "Harvesting data for Performance" -status "Percent proccesed: " -percentComplete (( $counter++ / $perfloopcount ) * 100)
    		
    $1 = 1
    
    foreach ($perfComputer in $servers)
    {
    
    # process the general server info
    write-host "Processing $perfComputer Hit number: " $perfloop
    
    #collect the WMI data
    $perfrawtemp2 = gwmi -computername $perfComputer Win32_PerfformattedData_PerfOS_System
    $perfrawtemp3 = gwmi -computername $perfComputer Win32_PerfformattedData_Tcpip_NetworkInterface
    $perfrawtemp4 = gwmi -computername $perfComputer Win32_PerfformattedData_PerfDisk_logicalDisk
    
    
    #add to temporary variable for counting
    
    if ( $perfraw3[$1].count -eq $null) { $perfraw3[$1] = 1,2,3,4,5,6,7,8,9 }
    if ( $perfraw31[$1].count -eq $null) { $perfraw31[$1] = 1,2,3,4,5,6,7,8,9 }
    if ( $perfraw32[$1].count -eq $null) { $perfraw32[$1] = 1,2,3,4,5,6,7,8,9 }
    if ( $perfraw4[$1].count -eq $null) { $perfraw4[$1] = 1,2,3,4,5,6,7,8,9 }
    if ( $perfraw41[$1].count -eq $null) { $perfraw41[$1] = 1,2,3,4,5,6,7,8,9 }
    if ( $perfraw42[$1].count -eq $null) { $perfraw42[$1] = 1,2,3,4,5,6,7,8,9 }
    if ( $perfraw43[$1].count -eq $null) { $perfraw43[$1] = 1,2,3,4,5,6,7,8,9 }
    if ( $perfraw44[$1].count -eq $null) { $perfraw44[$1] = 1,2,3,4,5,6,7,8,9 }
    if ( $perfraw45[$1].count -eq $null) { $perfraw45[$1] = 1,2,3,4,5,6,7,8,9 }
    if ( $perfraw46[$1].count -eq $null) { $perfraw46[$1] = 1,2,3,4,5,6,7,8,9 }
    if ( $perfraw47[$1].count -eq $null) { $perfraw47[$1] = 1,2,3,4,5,6,7,8,9 }
    
    
    $2 = 1
    foreach ( $perflan in $perfrawtemp3 ) 
    {
    
    	$perfraw3[$1][$2] = $perflan.name
    	$perfraw31[$1][$2] += $perflan.BytesTotalPersec
    	$perfraw32[$1][$2] = $perflan.CurrentBandwidth
    	$2 += 1
    	
    }
    
    $3 = 1
    
    foreach ( $perfdisk in $perfrawtemp4 ) 
    {
    
    	$perfraw4[$1][$3] = $perfdisk.name
    	$perfraw41[$1][$3] += $perfdisk.AvgDiskQueueLength      #3
    	$perfraw42[$1][$3] += $perfdisk.DiskBytesPersec
    	$perfraw43[$1][$3] += $perfdisk.AvgDisksecPerRead       #20
    	$perfraw44[$1][$3] += $perfdisk.AvgDisksecPerWrite      #100
    	$perfraw45[$1][$3] += $perfdisk.AvgDisksecPerTransfer   #20
    	$perfraw46[$1][$3] += $perfdisk.SplitIOPerSec           #5
    	$perfraw47[$1][$3] += $perfdisk.PercentIdleTime
    	
    	$3 += 1
    	
    }
    
    						
    $1 += 1
    # script break skipped irrelevant part
    			
    if ( $perfdiskname -notlike "*_total*" )
    {
    	if ( $perfdiskname -notlike "*harddisk*" )
    	{
    															
    		$c.Cells.Item($introw,$intcol) = $perfdiskname
    		$intcol += 1
    		$c.Cells.Item($introw,$intcol) = $perfraw41[$id][$id2] / $perfloopcount
    		if ( $perfraw41[$id][$id2] / $perfloopcount -ge "3" ) 
    		{ 
    			$d = $c.Cells.Item($intRow,$intcol)
    			$d.Interior.ColorIndex = 45
    			$performanceminorerror += 1
    		}
    			
    			


    MCTS-MCITP exchange 2010 | MCTS-MCITP Exchange: 2007 | MCSA Messaging: 2003 | MCP windows 2000

All Replies

  • Thursday, January 17, 2013 3:53 PM
     
     
    Do not use arrays - use objects.

    ¯\_(ツ)_/¯

  • Wednesday, January 30, 2013 7:26 PM
     
     

    can you clarify a little bit more or do you know a site explaining what you mean .


    MCTS-MCITP exchange 2010 | MCTS-MCITP Exchange: 2007 | MCSA Messaging: 2003 | MCP windows 2000

  • Wednesday, January 30, 2013 8:13 PM
     
     Answered

    can you clarify a little bit more or do you know a site explaining what you mean .


    MCTS-MCITP exchange 2010 | MCTS-MCITP Exchange: 2007 | MCSA Messaging: 2003 | MCP windows 2000

    Arrays are not descriptive and not discoverable.  They work but the ambiguity can make debugging very hard.  By using explicitly defined and named objects we can inspect the objects at a much later time and understand what it is we are looking at.

    Assume calling a function with an array element and it fails; similar to what you are doing.  If you use the wrong subscripting or calculate it wrong there is no way to know what was intended.  An object or a hash tell you explicitly what they are and the names of their contents.  Items are retrievable using a logical and descriptive name.  This is one of the main purposes of OOP, dotNet and PowerShell.

    In the old days - way back in Dartmouth  Basic - we all learned to use complex arrays because we had no constructs for describing data in any other way.  Consequently every programmer who graduates from a non-computer college and takes a programming course is taught to do everything with arrays.  If you go to Columbia, MIT or other more technical schools this will not be the case. You will learn OOP and C++ along with other object concepts.  This has been the case for over a decade.

    Arrays are useful as simple wrappers for a collection of objects because they are efficient and easy to enumerate.  Other collection types are more powerful and easier to maintain and debug.

     

     

     

    Arrays are not descriptive and not discoverable.  They work but the ambiguity can make debugging very hard.  By using explicitly defined and named objects we can inspect the objects at a much later time and understand what it is we are looking at.

    Assume calling a function with an array element and it fails; similar to what you are doing.  If you use the wrong subscripting or calculate it wrong there is no way to know what was intended.  An object or a hash tell you explicitly what they are and the names of their contents.  Items are retrievable using a logical and descriptive name.  This is one of the main purposes of OOP, dotNet and PowerShell.

    In the old days - way back in Dartmouth  Basic - we all learned to use complex arrays because we had no constructs for describing data in any other way.  Consequently every programmer who graduates from a non-computer college and takes a programming course is taught to do everything with arrays.  If you go to Columbia, MIT or other more technical schools this will not be the case. You will learn OOP and C++ along with other object concepts.  This has been the case for over a decade.

    Arrays are useful as simple wrappers for a collection of objects because they are efficient and easy to enumerate.  Other collection types are more powerful and easier to maintain and debug.

     

     


    ¯\_(ツ)_/¯

  • Monday, February 04, 2013 10:40 PM
    Moderator
     
     Proposed

    PowerShell has many different ways to construct custom objects which can be grouped in collections and iterated. When someone is trying to build arrays containing complex multi-valued data, this is usually because they're not aware that there are far better ways to express the representation of that data than by using arrays. The remedy is thus:

    1. Learn better how objects work in PowerShell

    2. Rewrite the code to use objects rather than arrays

    Bill