Please help Posh can't count to 1

This topic contains 6 replies, has 4 voices, and was last updated by  Dan Potter 9 months, 2 weeks ago.

  • Author
    Posts
  • #65715

    Steve
    Participant

    I'm running powershell 5.0 on Windows 7 Ent.

    I've just run into a serious issue where I've discovered a bug.

    My script searches the first two layers of any connected drive and provides list folders.
    The script works great, so long as it returns 2 or more directories.
    It makes an error if less than 2 are returned.
    This error is passed down and the application that uses the results will encounter issues.

    0..( $ProjectsEA.Count - 1 ) | ForEach-Object { $CombinedEA += @( "$($segs[$_])=$($ProjectsEA[$_])" ) }

    Run individually, all these variables produce proper results except when the return is less than 2.

    when less than 2 results are returned the only variable that has a problem is $CombinedEA. The other two STILL produce the proper results.

    I tested by calling the individual vars after the line ran.

    The results for an error are always the same:
    2=E
    (it's not an actual throwable error, it's just incorrect data)

    How else can I mash these two together in order to get the correct results?
    I need a process that will return nothing if zero results are found or just a single entry if only 1 is found.

    Thank you very much for any insight you can provide!

  • #65718

    Ron
    Participant

    It's hard to say for sure without the rest of the code, but most likely, when only 1 result is returned, $ProjectsEA is not an array and $ProjectsEA.Count is null.

    You can force it to be an array when one result is returned like this:

    [array]$ProjectsEA = cmd

    However, it will still be null when no results are returned, so be sure to test for that.

    • #65724

      Steve
      Participant

      ok, so after I posted I did some searching around and found this

      $array = @("test1", "test2", "test3")
      for ($i=0; $i -lt $array.length; $i++) {
      	$array[$i]
      }
      

      from https://powertoe.wordpress.com/2009/12/14/powershell-part-4-arrays-and-for-loops/

      So what I did was try:

      $CombinedEA = for ($i=0; $i -lt $ProjectsEA.Length; $i++){
      "$($segs[$i])=$($ProjectsEA[$i])"
      }
      

      Which also failed if the array were less than 2.

      HOWEVER – your post gave me the key ingredient
      I declared $segs and $ProjectsEA as arrays and that fixed everything.

      [array]$ProjectsEA =
      [array]$segs =

      I just tested with my original script, only adding the [array] declaration and it worked just as well as the code above.

      Thank you!

  • #65725

    Dan Potter
    Participant

    ('one' |measure).count

    ('one','two' |measure).count

  • #65731

    Rob Simmers
    Participant

    I typically cast it like this:

    @($whatever).Count
    

    There is additional information on this in the The Big Book of PowerShell Gotchas in the eBooks link above.

  • #65749

    Steve
    Participant

    What I found, which was the root of the problem, was that powershell didn't know the type of data it was handling. It's pretty sophisticated actually because with a set of two or more it was able to deduce the information was in array format.

    Up until now it's been guessing at my intentions (successfully for the most part) for a couple months on a test systems LOL.

    But like any set of 1 without explicit definitions, powershell was forced to make a guess at the data it was presented. Which is why when I presented it with a unit of 1, powershell returned a result as character by character in separate lines.

    Prior to the solution, I tried noting at the top of the script $var1 = @() and $var2 = @() but this was not effective.

    Only by placing [array] in front of the variable did powershell understand the data content and enumerate it correctly.

  • #65758

    Dan Potter
    Participant

    Powershell does not guess 🙂

    ('one','two').gettype()

    ('one').gettype()

You must be logged in to reply to this topic.