在Powershell脚本中遍历多个数组 [英] Iterate through multiple arrays in powershell script
问题描述
我正在尝试使用多个数组来传递多个服务器名称,也许还有其他元素,这可能需要彼此结合在一起才能在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屋!