Строка добавляется, потому что это то, что вы сказали ей сделать.
Прямо вверх, +=
говорит добавить новое содержимое в конце, так что в случае
$sync_output = Join-Path $syncPATH $CUBE_input
...
$sync_output += "_$Destination_Server.txt"
Он устанавливает строку, а затем добавляет элементы в конец этой строки и продолжает добавлять к ней каждый раз, когда эта команда выполняется, когда цикл ForEach-Object
циклически повторяется.Это усугубляется вашим другим использованием +=
, который добавляет объекты в массив, так как вы устанавливаете $Destination_Server = @()
, который устанавливает эту переменную как пустой массив.Поэтому, когда вы добавляете к своей строке, вы добавляете весь массив к этой строке.
Итак, чтобы повторить ваш пример:
$sync_output = 'CUBE'
$destination_server = @()
Затем внутри цикла на первом проходе вы добавляете строкук массиву:
$destination_server += 'Destination_Server1'
Так что в этом массиве есть 1 элемент.Затем вы добавляете этот массив к $sync_output
, который при расширении переменных в основном выглядит следующим образом:
"CUBE" += "_Destination_Server1.txt"
Так что теперь $sync_output
имеет значение CUBE_Destination_Server1.txt
.Следующая итерация цикла!Вы добавляете еще одну строку в массив $Destination_Server
:
$destination_server += 'Destination_Server2'
Теперь, когда в массиве есть 2 строки, поэтому, когда вы добавляете его в строковую переменную $sync_output
, вы, по сути, делаете это:
"CUBE_Destination_Server1.txt" += "_Destination_Server1Destination_Server2.txt"
Это происходит потому, что массив строк просто объединяет все строки в своем массиве в одну строку.Чтобы действительно это исправить, вы должны быть последовательными и ссылаться на последнюю строку в массиве.Я рекомендую не использовать одну и ту же переменную для этого и буду использовать $sync_output_file
.
$sync_output = Join-Path $syncPATH $CUBE_input
$i=0
$Destination_Server = @()
foreach($row in $Table | where { $_.cube_name -match $CUBE })
{
$i++
$Destination_Server += $row.Item("query_server")
write-host " > Query Server $($i):" $Destination_Server[$Destination_Server.length -1]
$sync_output_file = $sync_output + '_' + $Destination_Server[-1] + '.txt'
Invoke-ASCmd –InputFile $XML_file -Server $Destination_Server[$Destination_Server.length -1] >$sync_output_file
}
Редактировать: Вот почему $Destination_Server[$Destination_Server.length - 1]
работает как $Destination_Server[-1]
:
В PowerShell каждый элемент в массиве имеет индекс.Этот индекс основан на нуле.Вы можете ссылаться на элемент в массиве по его порядковому номеру, например $Array[X]
, где X
- это порядковый номер интересующего вас элемента. Поэтому, учитывая этот массив:
$MyArray = 'cat','dog','fish','goat','banana'
Если вы ссылаетесь$MyArray[0]
вернет cat
, так как это первый элемент в массиве.С массивами в PowerShell свойства .length и .count являются синонимами, поэтому, когда вы ссылаетесь на $MyArray.length
, вы просто получаете количество элементов в массиве.Когда вы подсчитываете элементы, вы начинаете с 1, но индексы массива начинаются с 0, поэтому вам нужно сделать .length - 1
, чтобы получить номер индекса последнего элемента в массиве.В моем примере, если мы сделаем $MyArray.Length
, он вернет 5
, потому что в моем массиве есть 5 элементов.Таким образом, $MyArray[$MyArray.Length - 1]
- это, по сути, $MyArray[5 - 1]
или $MyArray[4]
, который является последним элементом в $MyArray
.
В дополнение к ссылкам на элементы по индексу вы также можете использовать отрицательные числа, которые начинаются сконец массива и считать в обратном направлении.Этот метод не основан на нуле, поэтому $MyArray[-1]
ссылается на последний элемент в массиве, точно так же, как $MyArray[-2]
является вторым по отношению к последнему элементу в массиве.
Таким образом, разница между $MyArray[$MyArray.length - 1]
и $MyArray[-1]
заключается в том, что в первом вы вычисляете номер индекса для последнего элемента в массиве, где второй ссылается на последний элемент в массиве независимо от того, какой у него номер индекса.
Вы также можете указать диапазоны этогоКстати, $MyArray[0..2]
даст вам первые 3 элемента в массиве, а $MyArray[-2..-1]
даст вам последние 2 элемента в массиве.Это на самом деле не относится к вашей ситуации прямо сейчас, но это полезно знать в целом и может быть полезно в будущем для вас.