[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

How to stop PowerShell function changing return type of ArrayList or string[]

Posted on 2011-05-12
2
Medium Priority
?
3,549 Views
Last Modified: 2012-05-11
I'm attempting to return either a .NET ArrayList collection or a string array
(string[]) from a PowerShell function. PowerShells runtime "unravelling" is not
behaving as described, and the various work arounds I've read about don't address
the issue.

What is being returned is also not what I expect or have read about.

The following code returns a System.Array with a count of 6 and the values
0 1 2 A B C. What I want is only 3 values A B C.

function GetArrayOfStrings([string[]] $strings)
{
      # set up a collection to "read them in"
      $stringAryList = New-Object "System.Collections.ArrayList"
      foreach($string in $strings)
      {
            $stringAryList.Add($string)
      }

            $stringAry = $stringAryList.ToArray()
            return $stringAry
}

#main

$stringAry = GetArrayOfStrings(("A", "B", "C"))

foreach($str in $stringAry)
{
      Write-Host $str
}

The returned  values suggest PowerShell is flattening a hash table where 0 1 2 are the index values and A B C the content values.

Attempting to "wrapper" the return using "," or @(,) syntax doesn't improve things much.

      return ,$stringAry
      return @(,$stringAry)
      
Both result in a System.Array containing {0, 1, 2, System.Array} and an output of

0
1
2
A B C

This is better, but the only way to get the string[] as a System.Array is to do the
following:

$actualStringArray = $stringAry[$stringAry.Count-1]

Some of my readings online have suggested the array is unravelled to make it simpler
for human readability or to be used in foreach, but I certainly don't see how...

I have identical problems when attempting to return the ArrayList

Looking for a way to fully defeat the unravelling or a way to use the results in a foreach,
but only for the content values, not the index values.
0
Comment
Question by:NJThomson
  • 2
2 Comments
 

Accepted Solution

by:
NJThomson earned 0 total points
ID: 35751131
Actually, in further reading, the issue is the following:

In PowerShell, any data that your function or script generates gets sent to the output pipeline, unless something captures that output. Some .NET methods—such as the System.Collections.ArrayList class—produce output, even though you may not expect them to. To prevent these methods from sending data to the output pipeline, either capture the data or cast it to [void]:

PS > $collection = New-Object System.Collections.ArrayList
PS > $collection.Add("Hello")
0
PS > [void] $collection.Add("Hello")

So the solution is to do the [void] trick with the .add function and use the "," operator to send back a single element - the system.array.

The working solution is:

function GetArrayOfStrings([string[]] $strings)
{
      # set up a collection to "read them in"
      $stringAryList = New-Object "System.Collections.ArrayList"
      foreach($string in $strings)
      {
            [Void] $stringAryList.Add($string)
      }

            $stringAry = $stringAryList.ToArray()
            return ,$stringAry
}

#main

$stringAry = GetArrayOfStrings(("A", "B", "C"))

foreach($str in $stringAry)
{
      Write-Host $str
}
0
 

Author Closing Comment

by:NJThomson
ID: 35751132
Found a good answer in an online book in Safari....
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In the absence of a fully-fledged GPO Management product like AGPM, the script in this article will provide you with a simple way to watch the domain (or a select OU) for GPOs changes and automatically take backups when policies are added, removed o…
In this post, I will showcase the steps for how to create groups in Office 365. Office 365 groups allow for ease of flexibility and collaboration between staff members.
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Screencast - Getting to Know the Pipeline

825 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question