我创建了一个powershell gui来创建IAAS cloudformation模板。我遇到的问题是:
模板成功地为所有环境创建文件夹结构,一旦它开始为部署创建每个文件的过程。
每个文件名都来自变量:
$is = $textbox10.Lines (TEXTBOX WITH A SERVER NAME LIST)如果我输入3个服务器名称,它将在所有文件夹中使用$i中的名称创建3个文件(此部分有效)
###################################################################
### 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"一旦完成该操作,它应该尝试遍历它创建的每个文件并添加其他变量。在本例/示例中:$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个文件都具有$a的第一个变量"a",而不是"test01-a“、"test02-b”、"test03-c“。
发布于 2020-02-04 22:55:42
问题是要替换的文本搜索模式在循环的第一次遍历中被替换,而在第二个循环中不再存在。让我们简化一下,只在一个文件上循环:
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>现在,您的循环第一次运行,其中$a = 'a'。在循环中获取文件的内容,执行字符串替换,并使用Set-Content保存更新的文件。最终产品,该文件现在包含:
<region>
us-east-1a
<region>第二个循环开始,这次是$a = 'b'。在您的循环中,您可以获得文件的内容,它尝试执行字符串替换,但是文件中的“可用性区域”没有被替换的地方,所以它保存文件就像现在一样。
第三个循环,其中$a = 'c'的执行与第二个循环完全一样。它加载文件,找不出要替换的东西,并按原样保存文件。如果您希望它包含$azs中的所有三个项,则需要将字符串组合成单个字符串,并将其用作您的替代项。
$AllZones = ($azs|ForEach{"us-east-1$_"}) -join ", "现在是$AllZones = "us-east-1a, us-east-1b, us-east-1c"。然后将其用作替换字符串,不需要内部循环。
$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()循环而不是ForEach()循环。然后事情开始变成这样:
$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-1c“。如果您的服务器数量和位置相同,那么非常简单。
让我们看看另一种方法,您可能有不同数量的服务器和位置,并且您希望在有限的位置上分发服务器。这将是一个类似的情况,但我们需要做一些数学,以循环通过的位置列表。让我们从设置更多的服务器开始,我们将扩展到5。
$is = "TEST01","TEST02","TEST03","TEST04","TEST05"为了简单起见,我们只需要输出分配给每个服务器到屏幕上的区域:
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'这其中的神奇之处是$y%$azs.count。这样做是在将$y的当前迭代除以$azs.count (即3)之后,给出剩余的部分。因此,第一次通过循环,它是0除以3,这是0,余数为0。$azs[0] = 'a'。下一次迭代是1除以3,这是0,余数为1.$azs[1] = 'b'。迭代3非常相似,产生'c‘。迭代4更有趣的地方是,它被3除以3,它是1,余数为0,这就是导致我们循环回$azs[0] = 'a'开头的原因。
https://stackoverflow.com/questions/60066220
复制相似问题