Results 1 to 14 of 14
  1. #1
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    6,414
    Thanks
    208
    Thanked 835 Times in 768 Posts

    PowerShell Arrays have me stumped

    Hey Y'all,

    Now I've been programming for decades and thought I had a good grasp of Arrays but PS has me stumped.
    Can someone tell me why I keep getting this error:
    Unable to index into an object of type
    System.Management.Automation.PSReference`1[System.Object[]].
    At line:18 char:8
    + $PathSegment[$SegCnt++] = $Result.value
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : CannotIndex
    Here's the code:
    Code:
    Function Parse-Path {
      Param ( [Parameter(Mandatory=$True)]
              [ref]$PathSegment ,
              [Parameter(Mandatory=$True)]
                [string]$TestPath ,
              [Parameter(Mandatory=$False)]
               [string]$InclFN = $False
            )          
    
      
      $SegCnt = 0
      $PathRegX = [regex] "[0-9,A-Z,a-z,#,_,-, ]+|\|:"
      $Result = $PathRegX.match($TestPath)
    
      #$Result | Get-Member
    
      While ($Result.Success) {
           $PathSegment[$SegCnt++] = $Result.value  #Stmt causing Error!
           $Result = $Result.nextmatch()
      }   #End While Loop
    
      Return $SegCnt
    
    
    }  #End Function Parse-Path
    
    #Main
    
      Clear-Host
    
      $Elements = @(" "," "," "," "," "," "," "," "," "," "," ")
    
      $ArrCntr = Parse-Path -PathSegment ([ref]$Elements) `
                 -TestPath "G:\BEKDocs\Excel\Test\SkiPro Example_Revised#2.xlsm"
      write-host $Elements.GetType()
      write-host ""
      Write-Host "There are: $ArrCntr items."
      For ( $Cnt=1; $Cnt -lt $ArrCntr; $Cnt++) {
         Write-Host $Elements[$cnt]
      }
    I've tried declaring the $Elements array several different ways as well as using different indexing schemes. (This was originally a 2 dimensional array but I cut it back to one for simplicity...and still can't get it to work.)

    Any insight would be most welcome. I've googled for 2 days now and can't find the answer as all the hits show short command line examples rather that actual program segments that you can follow through.
    May the Forces of good computing be with you!

    RG

    VBA Rules!

    My Systems: Desktop Specs
    Laptop Specs


  2. #2
    Administrator
    Join Date
    Jun 2010
    Location
    Portugal
    Posts
    10,363
    Thanks
    130
    Thanked 1,163 Times in 1,070 Posts
    Ok, from someone who knows nothing about Powershell, so just dismiss me if you think I am writing gibberish.

    1. I see no $Elements array, did you mean $PathSegment?
    2. Is $PathSegment an array?

    Apologies if I am making you lose time.

    I always wanted to know a bit more about Powershell (even have a book), but time is usually so short...
    Rui
    -------
    R4

  3. #3
    Administrator
    Join Date
    Jun 2010
    Location
    Portugal
    Posts
    10,363
    Thanks
    130
    Thanked 1,163 Times in 1,070 Posts
    And what if you used something like this (again, bear with me, any errors are my fault and my "who told you you could learn Powershell arrays with a few reads on your Powershell book" crash course:

    Code:
    While ($Result.Success) {
           $PathSegment += $Result.value  
           $Result = $Result.nextmatch()
           $SegCnt++
      }   #End While Loop
    Rui
    -------
    R4

  4. #4
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    6,414
    Thanks
    208
    Thanked 835 Times in 768 Posts
    Rui,

    Been down that path:
    Method invocation failed because
    [System.Management.Automation.PSReference`1[[System.Object[], mscorlib,
    Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]] does not
    contain a method named 'op_Addition'.
    At line:19 char:8
    + $PathSegment += $Result.value
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (op_Addition:String) [], Runti
    meException
    + FullyQualifiedErrorId : MethodNotFound

    You don't find $Elements in the Function because I'm passing it via Reference.

    Looks like we're both in the same boat and I'm sure doing a lot of baling!

    BTW: The code is self contained so you can copy it into the PS IDE and have at it.
    May the Forces of good computing be with you!

    RG

    VBA Rules!

    My Systems: Desktop Specs
    Laptop Specs


  5. #5
    Administrator
    Join Date
    Jun 2010
    Location
    Portugal
    Posts
    10,363
    Thanks
    130
    Thanked 1,163 Times in 1,070 Posts
    Hmm... I would guess that result means your code is not interpreting the parameter as being an array.
    Rui
    -------
    R4

  6. #6
    4 Star Lounger access-mdb's Avatar
    Join Date
    Dec 2009
    Location
    Oxfordshire, UK
    Posts
    572
    Thanks
    52
    Thanked 42 Times in 39 Posts
    Like Rui I too haven't really got a clue. Where does the array definition occur? It's simple in VBA, and in Perl it's $variable for a scalar and %variable for an array. I think it's similar in Ruby and Python (but I'm not familiar with those). It's even simple in Fortran 66 and 72 (blimey that's going back a few years). I'm not sure I want anything to do with PS if it's this hard. I can't even work out what your program's doing (wot, no comments!).

    Did you mean PS ISE rather than IDE? It's what I've got on my PC (Win 8.1)?

  7. #7
    Administrator
    Join Date
    Jun 2010
    Location
    Portugal
    Posts
    10,363
    Thanks
    130
    Thanked 1,163 Times in 1,070 Posts
    What if you do this? That will make $PathSegment an empty array, so the subsequent additions should work.

    Code:
    $PathSegment = @()
    
    While ($Result.Success) {
           $PathSegment += $Result.value  
           $Result = $Result.nextmatch()
           $SegCnt++
      }   #End While Loop
    Rui
    -------
    R4

  8. #8
    Administrator
    Join Date
    Jun 2010
    Location
    Portugal
    Posts
    10,363
    Thanks
    130
    Thanked 1,163 Times in 1,070 Posts
    I guess you need to declare the parameter as an array?

    Code:
    Function Parse-Path {
      Param ( [Parameter(Mandatory=$True)]
              [ref] [string[]]$PathSegment ,
              [Parameter(Mandatory=$True)]
                [string]$TestPath ,
              [Parameter(Mandatory=$False)]
               [string]$InclFN = $False
            )
    Of course, this will also mean your original way of indexing the variable should work, if this is the cause.


    P.S.: The Powershell books I own are not that good, organization wise. Hate when several examples declare parameters to be arrays but can't see any explanation for that. This has been an exercise in uneducated guessing .
    Rui
    -------
    R4

  9. #9
    Administrator
    Join Date
    Jun 2010
    Location
    Portugal
    Posts
    10,363
    Thanks
    130
    Thanked 1,163 Times in 1,070 Posts
    Ok, this is as far as I've gone:
    Code:
    Function Parse-Path {
      Param ( [Parameter(Mandatory=$True)]
              [ref]$PathSegment ,
              [Parameter(Mandatory=$True)]
                [string]$TestPath ,
              [Parameter(Mandatory=$False)]
               [string]$InclFN = $False
            )          
    
      
      $SegCnt = 0
      $PathRegX = [regex] "[0-9,A-Z,a-z,#,_,-, ]+|\|:"
      $Result = $PathRegX.match($TestPath)
    
      #$Result | Get-Member
      $PathSegment = @()
    
      While ($Result.Success) {
           $Result = $Result.nextmatch()
           $PathSegment.Value += $Result.value  
           $SegCnt++
      }   #End While Loop
    
      Return $SegCnt
    
    
    }  #End Function Parse-Path
    
    #Main
    
      Clear-Host
    
      $Elements = @(" "," "," "," "," "," "," "," "," "," "," ")
    
      $ArrCntr = Parse-Path -PathSegment ([ref]$Elements) `
                 -TestPath "C:\Users\Rui\Documents\ebooks\Windows\Microsoft_Press_eBook_Programming_Windows_Store_Apps_2nd_Edition_2nd_Preview.pdf"
    
      write-host $Elements.GetType()
      write-host ""
      Write-Host "There are: $ArrCntr items."
      For ( $Cnt=1; $Cnt -lt $ArrCntr; $Cnt++) {
         Write-Host $Elements[$cnt]
      }
    No errors returned, count is shown to be 8, which seems correct, but nothing else is printed.
    Rui
    -------
    R4

  10. #10
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    6,414
    Thanks
    208
    Thanked 835 Times in 768 Posts
    Rui,

    Been there done that bought the tee shirt!
    I was actually there yesterday but couldn't figure out why it wouldn't output after returning to the main routine.
    May the Forces of good computing be with you!

    RG

    VBA Rules!

    My Systems: Desktop Specs
    Laptop Specs


  11. #11
    Administrator
    Join Date
    Jun 2010
    Location
    Portugal
    Posts
    10,363
    Thanks
    130
    Thanked 1,163 Times in 1,070 Posts
    Seems Powershell doesn't really like arrays as parameters passed by reference... I couldn't find a reference that dealt with this in an intelligible manner. Sorry RG, hope your sort it, but I can't go any further .
    Rui
    -------
    R4

  12. #12
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    6,414
    Thanks
    208
    Thanked 835 Times in 768 Posts
    Rui,

    Thanks for trying. I've made some progress as I now have a one dimensional array version working.
    Of course I'm no longer passing by reference but it does work!
    Code:
    Function Parse-Path {
      Param ( [Parameter(Mandatory=$True)]
                [string]$TestPath ,
              [Parameter(Mandatory=$False)]
               [string]$InclFN = $False
            )          
    
      $Elements = New-Object 'object[]' 10
      $SegCnt = 0
      $PathRegX = [regex] "[0-9,A-Z,a-z,#,_,-, ]+|\|:"
      $Result = $PathRegX.match($TestPath)
    
      #$Result | Get-Member
    
      While ($Result.Success) {
           $SegCnt += 1
           $Elements[$SegCnt] = $Result.value
           $Result = $Result.nextmatch()
      }   #End While Loop
    
      $Elements[0] = $SegCnt
      Write-Host $Elements
      Return $Elements
    
    }  #End Function Parse-Path
    
    #Main
    
      Clear-Host
    
      $Elements = Parse-Path -TestPath "G:\BEKDocs\Excel\Test\SkiPro Example_Revised#2.xlsm"
      write-host $Elements, $Elements[0]
      write-host ""
      $ArrCntr = $Elements[0]
      Write-Host "There are: $ArrCntr items."
      For ( $Cnt=1; $Cnt -le $($ArrCntr); $Cnt++) {
         Write-Host $Elements[$Cnt]
      }
    Results:

    6 G BEKDocs Excel Test SkiPro Example_Revised#2 xlsm
    6 G BEKDocs Excel Test SkiPro Example_Revised#2 xlsm 6

    There are: 6 items.
    G
    BEKDocs
    Excel
    Test
    SkiPro Example_Revised#2
    xlsm


    Next Steps:
    1. Get it to work with a 2 dimensional array.
    2. Get it to work with passing by reference (not as important any more since I went to it to solve a problem which doesn't exist any more).
    May the Forces of good computing be with you!

    RG

    VBA Rules!

    My Systems: Desktop Specs
    Laptop Specs


  13. #13
    Administrator
    Join Date
    Jun 2010
    Location
    Portugal
    Posts
    10,363
    Thanks
    130
    Thanked 1,163 Times in 1,070 Posts
    Well done . This definitely seems not a very well documented situation. I confess I was a bit perplexed for the lack of easily found references on the issue.
    Rui
    -------
    R4

  14. #14
    Super Moderator RetiredGeek's Avatar
    Join Date
    Mar 2004
    Location
    Manning, South Carolina
    Posts
    6,414
    Thanks
    208
    Thanked 835 Times in 768 Posts
    Hey Y'all,

    Here's a revised version with comments and usage examples.
    Code:
    Function Parse-Path {
    <# +----------------------------------------+
       | Function:        Parse-Path            |
       | Programmed by:                         |
       |    RetiredGeek@windowssecrets.com aka  |
       |    The Computer Mentor                 |
       | Current Version: 1.0                   |
       | Created:         01/05/2014            |
       | Updated:                               |
       +----------------------------------------+
    
    Notes: 
      1. returns a single dimensioned array with each segment
         of a fully qualified file reference in an element of
         the array with the 1st (zero element) containing the
         count of segments.
      2. One REQUIRED parameter, a fully qualified filespec.
      3. Upon return you can access fixed items via:
         Drive Letter: $Variable[1]
         Filename:     $Variable[$Variable[0]-1]
         Extension:    $Variable[$Variable[0]]
         Where: $Variable = your return value variable name.
      4. Note: If you wish to access these within a string use:
               $($Variable[$Variable[0]-1])
    #>
      Param ( [Parameter(Mandatory=$True)]
                [string]$TestPath 
            )          
    
      $Elements = New-Object 'object[]' 10
      $SegCnt = 0
      $PathRegX = [regex] "[0-9,A-Z,a-z,#,_,-, ]+|\|:"
      $Result = $PathRegX.match($TestPath)
     
      While ($Result.Success) {
           $Elements[++$SegCnt] = $Result.value
           $Result = $Result.nextmatch()
      }   #End While Loop
    
      $Elements[0] = $SegCnt
      Return $Elements
    
    }  #End Function Parse-Path
    
    #Main   Function Testing Code!
    
      Clear-Host
    
      $Elements = Parse-Path -TestPath "G:\BEKDocs\Excel\Test\SkiPro Example_Revised#2.xlsm"
      write-host $Elements, $Elements[0]
      write-host ""
      Write-Host "There are: $Elements[0] items."
    
      Write-Host "File Name: $($Elements[$Elements[0]-1]) `nFile Extension: $($Elements[$Elements[0]])`n"
      Write-Host $Elements[$Elements[0]-1] $Elements[$Elements[0]]
    
      For ( $Cnt=1; $Cnt -le $($Elements[0]); $Cnt++) {
         Write-Host $Elements[$Cnt]
      }
    HTH
    May the Forces of good computing be with you!

    RG

    VBA Rules!

    My Systems: Desktop Specs
    Laptop Specs


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •