在Powershell脚本中遍历多个数组 [英] Iterate through multiple arrays in powershell script

查看:913
本文介绍了在Powershell脚本中遍历多个数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用多个数组来传递多个服务器名称,也许还有其他元素,这可能需要彼此结合在一起才能在Powershell函数中使用函数的参数集.如果使用单个循环,即使可能的话.

I am attempting to use multiple arrays to pass multiple server names, and maybe other elements, that maybe be needed in conjunction to each other to a function's set of Parameters in a Powershell function. While using a single loop, if that is even possible.

我想编写此过程的脚本,因此您可以通过参数将数组作为较大的函数传递给第二个函数,但要使用数组.而不是嵌套的Hashtable.

I wanted to script this process so you could pass an array via a parameter as a larger function to the 2nd function but use arrays. Instead of nested Hashtable.

这与我尝试执行的操作类似,但是我似乎无法让数组每次为每个数组一次传递每个元素.

This is similar to what i was attempting to do but I cant seem to get the arrays to pass each element one at a time for each respective array.

这是我获得相似"结果的结果,但是如果必须通过 [0] 获得索引位置,我将无法工作.

This is what I have gotten to get a "similar" result but I will not work if I have to have the index position via the [0].

$servers1 = @('serv1-01','serv1-02')
$servers2 = @('serv2-01','serv2-02')

$collectionItems = @()
    $temp = New-Object System.Object
    $temp | Add-Member -MemberType NoteProperty -Name "Server1" -Value $servers1
    $temp | Add-Member -MemberType NoteProperty -Name "Server2" -Value $servers2
    $collectionItems += $temp
Write-Host "Server1 is $($item.Server1[0]) and Server2 is $($item.Server2[0])"

foreach ($item in $collectionItems)
{
    Write-Host "Server1 is $($item.Server1) and Server2 is $($item.Server2)"
}


#### This is the output if you run the above script#####
Server1 is serv1-01 and Server2 is serv2-01
Server1 is serv1-01 serv1-02 and Server2 is serv2-01 serv2-02

下面是我要完成的工作的骨架...我知道您可以有一个嵌套的Hashtable,它使用Key:Value对之一作为数组,但是我不确定是否可以传递它作为嵌套Hashtable在命令行中输入,或者如何使用参数将其添加到Hashtable的嵌套部分中,而不是保持此哈希表为最新状态((这不理想))

Below is kind of the skeleton of what i am trying to accomplish... I know that you can have a nested Hashtable that uses one of the Key:Value pairs as an array, but im not sure if you can pass that in at the commandline as a nested Hashtable or how that would work to use the params to add to the nested sections of the Hashtable vs keeping this hashtable up to date ((Which would not be ideal))

我知道下面的代码将无法正常工作,但能以最佳的视觉方式体现我期望的最终目标

function Bigger-ServerListAdding { 
#List of servers to add some config too
$servers1 = @('serv1-01','serv1-02')
$servers2 = @('serv2-01','serv2-02')

#This variable can be passed in and fixed with a -join ',' as a comma separated list
$componentlist = @('sister','brother','uncle','mom','dad')


###This section should do each element not the entire array list being passed###
foreach (item in $somecollection){
 Set-TheseServersOnaConfig -Server1 $item.servers1 -Server2 $item.servers2 -ComponentList $($componentlist -join ",")
}


}

请记住,这就像他在StackOverflow上问过的第二个问题一样.将来有任何关于此类事情的建议.

Mind you this is like he 2nd question i've ever asked on StackOverflow. Any suggestions as this type of thing in the future.

非常感谢!

推荐答案

Powershell对多维数组的处理非常糟糕,因此,我尽量避免使用它们. Jawad在评论中的回答是创建一个HashTables数组,这是避免使用它们的一种方法,但它没有利用PowerShell的面向对象性质.例如,我要传递有关3台计算机的信息,它们的名称,HD大小和内存大小.使用HashTable解决方案,您将得到:

Powershell's handling of multi-dimensional arrays is pretty lousy, and I try to avoid using them any chance I get. Jawad's answer in the comments, to create an array of HashTables, is one way of avoiding using them, but it doesn't take advantage of PowerShell's object oriented nature. As an example, I want to pass information about 3 computers, their names, HD Size, and Memory Size. Using the HashTable solution, you get:

$Array = @()
$Array += @{Computer='star';HD='2TB';Memory='16GB'}
$Array += @{Computer='comet';HD='1TB';Memory='8GB'}
$Array += @{Computer='meteor';HD='3TB';Memory='16GB'}

此数组包含3个项目:

PS> $Array.Count
3

您可以按期望的方式访问数据:

And you can access the data as you would expect:

PS> $Array[1]['Computer']
comet

但是您也可以将其作为属性来访问.

But you can also access it as a property.

PS> $Array[1].Computer
comet

但是,当您列出内容时,数据会混杂在一起,而且不容易理解:

But, when you list the contents, the data is intermingled, and not easy to understand:

PS> $Array
Name                           Value                                                                                                  
----                           -----                                                                                                  
Memory                         16GB                                                                                                   
HD                             2TB                                                                                                    
Computer                       star                                                                                                   
Memory                         8GB                                                                                                    
HD                             1TB                                                                                                    
Computer                       comet                                                                                                  
Memory                         16GB                                                                                                   
HD                             3TB                                                                                                    
Computer                       meteor        

此外,您创建的字段"不是对象的属性,而是键数组的成员,并且遍历比其所需的难度更大.

And further, the "fields" you have created are not properties of the object, but are members of the keys array, and are more difficult to iterate through than they need to be.

PS C:\Users\Matthew> $Array[0] | gm

   TypeName: System.Collections.Hashtable

Name              MemberType            Definition                                                                                    
----              ----------            ----------                                                                                    
Add               Method                void Add(System.Object key, System.Object value), void IDictionary.Add(System.Object key, S...
Clear             Method                void Clear(), void IDictionary.Clear()                                                        
Clone             Method                System.Object Clone(), System.Object ICloneable.Clone()                                       
Contains          Method                bool Contains(System.Object key), bool IDictionary.Contains(System.Object key)                
ContainsKey       Method                bool ContainsKey(System.Object key)                                                           
ContainsValue     Method                bool ContainsValue(System.Object value)                                                       
CopyTo            Method                void CopyTo(array array, int arrayIndex), void ICollection.CopyTo(array array, int index)     
Equals            Method                bool Equals(System.Object obj)                                                                
GetEnumerator     Method                System.Collections.IDictionaryEnumerator GetEnumerator(), System.Collections.IDictionaryEnu...
GetHashCode       Method                int GetHashCode()                                                                             
GetObjectData     Method                void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Seri...
GetType           Method                type GetType()                                                                                
OnDeserialization Method                void OnDeserialization(System.Object sender), void IDeserializationCallback.OnDeserializati...
Remove            Method                void Remove(System.Object key), void IDictionary.Remove(System.Object key)                    
ToString          Method                string ToString()                                                                             
Item              ParameterizedProperty System.Object Item(System.Object key) {get;set;}                                              
Count             Property              int Count {get;}                                                                              
IsFixedSize       Property              bool IsFixedSize {get;}                                                                       
IsReadOnly        Property              bool IsReadOnly {get;}                                                                        
IsSynchronized    Property              bool IsSynchronized {get;}                                                                    
Keys              Property              System.Collections.ICollection Keys {get;}                                                    
SyncRoot          Property              System.Object SyncRoot {get;}                                                                 
Values            Property              System.Collections.ICollection Values {get;}                                                  

但是,如果要利用PowerShell的对象性质而不是HashTables,请使用PowerShell定制对象(类型[PSCustomObject]),该对象会发生巨大变化.您可以通过多种方式创建新对象,但是您可以查看此TechNet文章

However, if you were to take advantage of the Object nature of PowerShell, and instead of HashTables, use a PowerShell Custom Object (Type [PSCustomObject]), that changes dramatically. You can create a new object in many ways, but you can check out this TechNet Article PowerShell: Creating Custom Objects for a bunch of them. I'm going to use my personal favorite, which is extremely similar to the HashTable method, as it uses a HashTable to define the object parameters:

$Array = @()
$Array += [PSCustomObject]@{Computer='star';HD='2TB';Memory='16GB'}
$Array += [PSCustomObject]@{Computer='comet';HD='1TB';Memory='8GB'}
$Array += [PSCustomObject]@{Computer='meteor';HD='3TB';Memory='16GB'}

这将为您提供数组中相同的3个项目:

This gives you the same 3 items in the array:

PS> $Array.Count
3

由于数据不是HashTable格式,因此您不能像HashTable一样访问它,但可以像属性一样访问它:

Since the data is not in HashTable format, you can't access it like a HashTable, but you can access it like a property:

PS> $Array[1]['Computer']

PS> $Array[1].Computer
comet

但是您获得的是数据分别保存在不同的对象中

But what you gain is that the data is kept separately in distinct objects:

PS> $Array

Computer HD  Memory
-------- --  ------
star     2TB 16GB  
comet    1TB 8GB   
meteor   3TB 16GB  

该对象的定义很简洁:

PS> $Array[0] | gm

   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition                    
----        ----------   ----------                    
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()             
GetType     Method       type GetType()                
ToString    Method       string ToString()             
Computer    NoteProperty string Computer=star          
HD          NoteProperty string HD=2TB                 
Memory      NoteProperty string Memory=16GB            

我希望这可以帮助您更多地了解PowerShell如何处理数据,并帮助您正确选择存储方式.

I hope this assists you in understanding more about how PowerShell handles data, and helps you make the right choices for how to store yours.

这篇关于在Powershell脚本中遍历多个数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆