Новичок в Powershell: как получить 2 или более переменных в одном файле, используя вложенный foreach или массивы (или любое другое решение)? - PullRequest
0 голосов
/ 05 февраля 2020

Я создал PowerShell gui для создания шаблонов облачной информации IAAS. Проблема, с которой я сталкиваюсь:

, шаблон успешно создает структуру папок для всех сред, как только он запускает процесс создания каждого файла для развертывания.

каждый файл имя из переменной:

$is = $textbox10.Lines  (TEXTBOX WITH A SERVER NAME LIST)

Если я введу 3 имени сервера, он создаст 3 файла с использованием имен в $ i (эта часть работает) во всех папках

###################################################################
###   COPY AND RENAME PARAMETER FILES IN INFRASTRUCTURE FOLDER  ###
###################################################################

            Copy-Item "$ansibleparamfile" "$($infrawindowsbasefolder)\dev\params_ans_DVW$i.yml"
            Copy-Item "$ansibleparamfile" "$($infrawindowsbasefolder)\sit\params_ans_SVW$i.yml"
            Copy-Item "$ansibleparamfile" "$($infrawindowsbasefolder)\uat\params_ans_UVW$i.yml"
            Copy-Item "$ansibleparamfile" "$($infrawindowsbasefolder)\prep\params_ans_PVW$i.yml"
            Copy-Item "$ansibleparamfile" "$($infrawindowsbasefolder)\prod\params_ans_XVW$i.yml"

как только это будет сделано, он должен попытаться go просмотреть каждый созданный файл и добавить другие переменные. В данном случае / примере: $ a переменная

$azs = $textbox1.Lines

Ниже приведен пример текущего места, в котором я нахожусь.


        $is = "TEST01","TEST02","TEST03"
        #Write-Host $is

        $azs = "a","b","c"
        #Write-Host $azs

        foreach ($i in $is)     

        {


            ###################################################################
            ###   COPY AND RENAME PARAMETER FILES IN INFRASTRUCTURE FOLDER  ###
            ###################################################################

            Copy-Item "$ansibleparamfile" "$($infrawindowsbasefolder)\dev\params_ans_DVW$i.yml"
            Copy-Item "$ansibleparamfile" "$($infrawindowsbasefolder)\sit\params_ans_SVW$i.yml"
            Copy-Item "$ansibleparamfile" "$($infrawindowsbasefolder)\uat\params_ans_UVW$i.yml"
            Copy-Item "$ansibleparamfile" "$($infrawindowsbasefolder)\prep\params_ans_PVW$i.yml"
            Copy-Item "$ansibleparamfile" "$($infrawindowsbasefolder)\prod\params_ans_XVW$i.yml"
            Copy-Item "$cfnparamfile" "$($infrawindowsbasefolder)\dev\params_DVW$i.json"
            Copy-Item "$cfnparamfile" "$($infrawindowsbasefolder)\sit\params_SVW$i.json"
            Copy-Item "$cfnparamfile" "$($infrawindowsbasefolder)\uat\params_UVW$i.json"
            Copy-Item "$cfnparamfile" "$($infrawindowsbasefolder)\prep\params_PVW$i.json"
            Copy-Item "$cfnparamfile" "$($infrawindowsbasefolder)\prod\params_XVW$i.json"

            #############################################
            ###  REPLACE CONTENT IN PARAMETER FILES   ###
            ###########################################


            foreach ($a in $azs)
            {
                #Write-Host $a

                ## REPLACE AVAILABILITY ZONES IN TEMPLATE ##
                (Get-Content "$($infrawindowsbasefolder)\dev\params_DVW$i.json") | foreach-object { $_ -replace "availability-zone", "us-east-1$($a)" } | Set-Content "$($infrawindowsbasefolder)\dev\params_DVW$i.json"
                (Get-Content "$($infrawindowsbasefolder)\sit\params_SVW$i.json") | foreach-object { $_ -replace "availability-zone", "us-east-1$($a)" } | Set-Content "$($infrawindowsbasefolder)\sit\params_SVW$i.json"
                (Get-Content "$($infrawindowsbasefolder)\uat\params_UVW$i.json") | foreach-object { $_ -replace "availability-zone", "us-east-$($a)" } | Set-Content "$($infrawindowsbasefolder)\uat\params_UVW$i.json"
                (Get-Content "$($infrawindowsbasefolder)\prep\params_PVW$i.json") | foreach-object { $_ -replace "availability-zone", "us-east-1$($a)" } | Set-Content "$($infrawindowsbasefolder)\prep\params_PVW$i.json"
                (Get-Content "$($infrawindowsbasefolder)\prod\params_XVW$i.json") | foreach-object { $_ -replace "availability-zone", "us-east-1$($a)" } | Set-Content "$($infrawindowsbasefolder)\prod\params_XVW$i.json"


            }
}

, когда он запускается, 3 файла создаются для каждого все среды имеют 1-ю переменную $ a «a» вместо «test01-a», «test02-b», «test03- c».

1 Ответ

0 голосов
/ 05 февраля 2020

Проблема в том, что шаблон поиска текста для замены заменяется в первом проходе l oop, и больше не существует во вторых двух циклах. Давайте упростим это и просто l oop для одного файла:

foreach ($a in $azs)
            {
                #Write-Host $a

                ## REPLACE AVAILABILITY ZONES IN TEMPLATE ##
                (Get-Content "$($infrawindowsbasefolder)\dev\params_DVW$i.json") | foreach-object { $_ -replace "availability-zone", "us-east-1$($a)" } | Set-Content "$($infrawindowsbasefolder)\dev\params_DVW$i.json"


            }

Предположим, что файл params_DVWTEST01.json содержит текст:

<region>
    availability-zone
<region>

Теперь ваш l oop запускается первый раз, где $a = 'a'. Внутри l oop вы получаете содержимое файла, выполняете замену строки и используете Set-Content для сохранения обновленного файла. Конечный продукт, этот файл теперь содержит:

<region>
    us-east-1a
<region>

Второй l oop начинается, на этот раз $a = 'b'. Внутри вашего l oop вы получаете содержимое файла, он пытается выполнить замену строки, но «зоны доступности» нигде нет в заменяемом файле, поэтому он сохраняет файл таким, какой он есть.

Третий l oop, где $a = 'c' выполняется точно так же, как второй l oop. Он загружает файл, не находит ничего для замены и сохраняет файл таким, каким он был. Если вы хотите, чтобы он содержал все три элемента в $azs, вам нужно будет соединить строки в одну строку и использовать ее в качестве замены.

$AllZones = ($azs|ForEach{"us-east-1$_"}) -join ", "

Now $AllZones = "us-east-1a, us-east-1b, us-east-1c". Затем используйте его в качестве строки замены, и внутренний l oop не требуется.

$AllZones = ($azs|ForEach{"us-east-1$_"}) -join ", "
## REPLACE AVAILABILITY ZONES IN TEMPLATE ##
(Get-Content "$($infrawindowsbasefolder)\dev\params_DVW$i.json") | foreach-object { $_ -replace "availability-zone", $AllZones } | Set-Content "$($infrawindowsbasefolder)\dev\params_DVW$i.json"

Редактировать: Похоже, что вы хотите циклически перемещаться по местоположениям при циклическом переключении между серверами, чтобы каждый сервер имел свое местоположение или, по крайней мере, чтобы серверы были распределены по местам. Есть несколько способов сделать это. Самое простое, если у вас такое же количество серверов, как и у вас. В этом случае вы переключаетесь на использование For() l oop вместо ForEach() l oop. Тогда все начинает выглядеть так:

    $is = "TEST01","TEST02","TEST03"
    #Write-Host $is

    $azs = "a","b","c"
    #Write-Host $azs

    for ($y=0; $y -lt $is.count; $y++)     

    {
        $i = $is[$y]

Затем, когда вы делаете замену, вы ссылаетесь на $azs[$y] как:

(Get-Content "$($infrawindowsbasefolder)\dev\params_DVW$i.json") | foreach-object { $_ -replace "availability-zone", "us-east-1$($azs[$y])" } | Set-Content "$($infrawindowsbasefolder)\dev\params_DVW$i.json"

Затем TEST01 получает "us-east-1a" TEST02 получает «us-east-1b», а TEST03 получает «us-east-1 c». Довольно просто, если ваше количество серверов и количество местоположений равны.

Давайте рассмотрим другой подход, когда у вас может быть разное количество серверов и местоположений, и вы хотите распределить серверы по ограниченному количеству местоположений. , Это была бы похожая ситуация, но нам пришлось бы немного подсчитать, чтобы просмотреть список мест. Начнем с настройки большего количества серверов, мы расширим до 5.

$is = "TEST01","TEST02","TEST03","TEST04","TEST05"

Мы оставим регионы одинаковыми, a, b и c. Теперь для простоты мы просто выведем, какую область мы назначаем каждому серверу на экран:

For($y=0; $y -lt $is.count; $y++){
    "Assigning server '$($is[$y])' to region 'us-east-1$($azs[$y%$azs.count])'"
}

Вывод этого будет:

Assigning server 'TEST01' to region 'us-east-1a'
Assigning server 'TEST02' to region 'us-east-1b'
Assigning server 'TEST03' to region 'us-east-1c'
Assigning server 'TEST04' to region 'us-east-1a'
Assigning server 'TEST05' to region 'us-east-1b'

Волхвы c в этом $y%$azs.count. То, что это делает, дает вам остаток после деления текущей итерации $y на $azs.count (то есть 3). Таким образом, в первый раз через l oop это 0, деленное на 3, что является 0 с остатком 0. $azs[0] = 'a'. Следующая итерация - 1, деленная на 3, которая равна 0 с остатком 1. $azs[1] = 'b'. Итерация 3 очень похожа, производя 'c'. Итерация 4 более интересна, когда она 3 делится на 3, то есть 1 с остатком 0, что заставляет нас вернуться к началу $azs[0] = 'a'.

...