• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 641
  • Last Modified:

Powershell function not working with an array.

Hi,

The below example works out of a function but does not in a function. For education purposes, why?


Open in new window

Param([Array]$Data)

Function try-Count([Array]$Data){
      Clear-Host
      
      If($Data -eq $Null){"Its Null Fool. Try -Data 1..1000"}
      $range = $Data
      $range = $range
      $count = $range.Count
                        For($i=0; $i -lt $count; $i++) {
          $i
            }
}

try-Count -Data $Data


#$Data = 1..1000
#$range = $Data
#$count = $range.Count
#For($i=0; $i -lt $count; $i++) {
#$i
}

Open in new window

0
PeterSinger
Asked:
PeterSinger
  • 9
  • 5
  • 5
  • +1
1 Solution
 
Brent ChallisPrincipal: ITCommented:
What error do you get?  I have tidied you code up a bit in to my own style:
Function try-Count([Array]$Data)
{
      Clear-Host
     
      If($Data -eq $Null)
      {
        "Its Null Fool. Try -Data 1..1000"
      }
      else
      {
          For($i=0; $i -lt $Data.Count; $i++)
          {
              ("{0}: {1}") -f $i,$Data[$i]
          }
      }
}

$Data = 1..1000
try-Count -Data $Data

and it works as a function.
0
 
PeterSingerAuthor Commented:
Param ($Data)
Function try-Count([Array]$Data)
{
      Clear-Host
      
      If($Data -eq $Null)
      {
        "Its Null Fool. Try -Data 1..1000"
      }
      else
      {
          For($i=0; $i -lt $Data.Count; $i++) 
          {
              ("{0}: {1}") -f $i,$Data[$i]
          }
      }
}

try-Count -Data $Data

Open in new window

Yes that works, but this does not, I am trying to work out why.
0
 
Brent ChallisPrincipal: ITCommented:
When I saved the code as a file and called it with:
PS C:\Data\Development\PowerShell> .\TryCountArray.ps1 (1..10)

it seemed to work.  Can you include the way that you have called the script and any error messages or sample output?
0
Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

 
PeterSingerAuthor Commented:
It returns "0: 1..1000" Nothing else
0
 
Brent ChallisPrincipal: ITCommented:
If you put parenthesis around the 1..1000 it will force the calculation of what you have entered which will turn it in to an array.  using 1..1000 on its own goes in as a string, hence only one entry.  If the parameter you pass in to the script (such as the result of something like Get-Service) it should work straight away.
0
 
PeterSingerAuthor Commented:
Param ($Data)

If($Data -like "*..*"){
$Data1 = $data.split("`.`.")
$Data2 = [int]($Data1[0])
$Data3 = [int]($Data1[2]) 
}

Function try-Count([Array]$Data,$Count)
{
      Clear-Host
      
      If($Data -eq $Null)
      {
        "Its Null Fool. Try -Data 1..1000"
      }
      else
      {
          For($i=0; $i -lt $Count; $i++) 
          {
              ("{0}: {1}") -f $i,$Data[$i]
          }
      }
}

try-Count -Data $Data1 -Count $Data3

Open in new window

It sort of works if I do the above. but not with  parenthesis. Unless the parenthesis is at the command line of course and that defeats the purpose.
0
 
Brent ChallisPrincipal: ITCommented:
The issue seems to be with the creation of the array,  I am using PowerShell 3.0 so am probably getting better support for the array work.

Try changing the output line to be:
("{0}: {1}") -f $i,$Data[$i].Name

Set up a variable that is a collection:
$s = Get-Service
and then call the script

.\TryCountArray.ps1 $s
0
 
PeterSingerAuthor Commented:
no good. in v2.
0
 
PeterSingerAuthor Commented:
Param ($Data)
Function try-Count([Array]$Data){Clear-Host;If($Data-eq$Null){"Try -Data (1..1000)"}else{For($i=0;$i-lt$Data.count;$i++){("{0}: {1}")-f$i,$Data[$i]}}}
If($($Data.Count) -lt "5"){Clear-host;'You need to put your array in parenthesis. E.G. -data (1..1000)';Exit}
try-Count -Data $Data

Open in new window

It works like this. But I would love to know how to pass an array via a paramater without putting it in parenthesis.

If anyone knows, please post it to the post.
Thanks
Peter
0
 
chrismerrittCommented:
This works just fine for me, and what's more when it returns the data type from the function it says it's system.array as well.

Function try-Count
{
	Param
	(
		[array]$DataInFunction
	)
	
    Clear-Host
    
    if ($DataInFunction -eq $Null)
    {
      "Its Null Fool. Try -DataInFunction 1..1000"
    }
    else
    {
        for ($i=0; $i -lt $DataInFunction.Count; $i++) 
        {
            "{0}: {1}" -f $i, $DataInFunction[$i]
        }
    }
	
	$DataInFunction.GetType()
}

$Data = 1..1000
try-Count -DataInFunction $Data

Open in new window


IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
0
 
PeterSingerAuthor Commented:
Param([array]$Data)
Function try-Count
{
	Param
	(
		[array]$DataInFunction
	)
	
    Clear-Host
    
    if ($DataInFunction -eq $Null)
    {
      "Its Null Fool. Try -DataInFunction 1..1000"
    }
    else
    {
        for ($i=0; $i -lt $DataInFunction.Count; $i++) 
        {
            "{0}: {1}" -f $i, $DataInFunction[$i]
        }
    }
	
	$DataInFunction.GetType()
}

try-Count -DataInFunction $Data 

Open in new window

Yes that works, but try to pass it from a param. That is what this post is trying to make work. Save it as a script and then run .\Script.ps1 -data 1..1000 (not -data (1..1000))
0
 
chrismerrittCommented:
Gonna go out on a limb here and say that I think you need to declare the array within the parentheses in order for it to compute the command as a command and not a literal, is it a problem to put your array into the parentheses?

If so, and your example is how you intend to use it, you could look at passing in two literal parameters instead like LowerBound + UpperBound and computing the array within the script using these values as boundaries instead.
0
 
PeterSingerAuthor Commented:
Thats the issue. If it is in parentheses at the command line it works. What I want to do is to shape it once it as been passed through and convert it if required, but that seems not to be easy in powershell v2. V3 handles it fine.
0
 
chrismerrittCommented:
If you only need to handle converting something like 1..100 from a literal into an array within the script, I can have a bash, it would fall over and smack it's face on the concrete painfully though if you wanted to handle lots of other types of arrays in this manner though.

Let me know.
0
 
Brent ChallisPrincipal: ITCommented:
The issue is that you need to create an array, somehow.  One way is to create it and store it in a variable such as $a = 1..1000 and the pass the $a to the script, or use a cmdlet that returns and array such as get-Service.  Using the parenthesis simply says calculate this first and also works under version 2.  (One of the many nices things about PowerShell 3.0 is the v 2.0 switch.)
0
 
chrismerrittCommented:
Well this works regardless if you feed it in like 1..10 or (1..10). I've removed some of the functionality outside of the Function itself here though.

Param([array]$InputData)

Clear-Host

if ($InputData -eq $Null)
{
	Write-Host "Its Null Fool. Try -InputData 1..1000"
}
elseif ($InputData[0] -match "..")
{
	$SplitData = $InputData[0].Split("..")
	$Data = $SplitData[0]..$SplitData[-1]
}
else
{
	$Data = $InputData
}

Function try-Count
{
	Param
	(
		[array]$DataInFunction
	)
    
    for ($i = 0; $i -lt $DataInFunction.Count; $i++) 
    {
        "{0}: {1}" -f $i, $DataInFunction[$i]
    }
}

try-Count -DataInFunction $Data

Open in new window

0
 
PeterSingerAuthor Commented:
chrismerritt gets the Trophy. It has to be converted no matter what you try in Powershell v2 I guess.

I will put some checking around it and will have to do what I need to do (a bit more complicated than this) this way.

Thanks All :)
Peter
0
 
chrismerrittCommented:
Like a baws!

Off to bed night! :)
0
 
LearnctxEngineerCommented:
If you just want to iterate through the array you could always just pipe the array into the function.

function try-count
{
   [CmdletBinding()]
   
   param (
      [Parameter(ValueFromPipeLine=$true,Position=0)]
      [Array]$data = $null
   )
   
   Process
   {
      $data
   }
}

Open in new window

1..1000 | try-count

But then if the exercise is to actually have a counter in the function and not just iterate an array then probably not what you want.
0
 
PeterSingerAuthor Commented:
chrismerritt does the trick. Thanks.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 9
  • 5
  • 5
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now