Powershell 如何循环脚本,让用户选择不同的选项?
对Powershell来说相当陌生。我正在编写一个脚本,允许用户安装所需的不同软件。此过程目前正在手动完成,安装所需的所有内容可能需要30-45分钟。然而,并不是所有的东西都需要安装在每个工作站上,所以我需要为用户提供灵活性。这就是我到目前为止所想到的。(为简洁起见进行了修改)Powershell 如何循环脚本,让用户选择不同的选项?,powershell,Powershell,对Powershell来说相当陌生。我正在编写一个脚本,允许用户安装所需的不同软件。此过程目前正在手动完成,安装所需的所有内容可能需要30-45分钟。然而,并不是所有的东西都需要安装在每个工作站上,所以我需要为用户提供灵活性。这就是我到目前为止所想到的。(为简洁起见进行了修改) 它没有给出期望的结果。我可以安装一个软件,但是脚本退出,我也不能安装所有三个。我已经使用了InstallOptions并用十种不同的方式编写了它,但是我仍然没有得到想要的结果。有什么建议吗 您可以在while($true
它没有给出期望的结果。我可以安装一个软件,但是脚本退出,我也不能安装所有三个。我已经使用了InstallOptions并用十种不同的方式编写了它,但是我仍然没有得到想要的结果。有什么建议吗 您可以在
while($true){}
中调用InstallOptions
(只要保持0
退出)或其他类型的循环,使其返回菜单。如果您从软件安装功能调用菜单,当您使用“全部安装”时,它将永远不会到达2和3。尝试:
你可能还想清理一下。例如,$Sofware1Path
位于函数外部,而$Software1Arguments
位于函数内部。对于简单的安装,您可以使用csv存储阵列(如果需要,可以读取并存储在单独的文件中)来清理此文件。比如:
$Installations = @(@"
Name,Step,Path,Arguments
Software1,1,"c:\Install Files\Product1\Setup.exe",/S
Software2,2,"c:\Install Files\Product2\SetupPart2.exe",/silent
Software2,1,"c:\Install Files\Product2\Setup.exe","/silent ""space test with ,"""
Software3,1,"c:\Install Files\Product3\Setup.exe",/passive "space test"
"@ | ConvertFrom-Csv)
function InstallSoftware ($Name) {
Write-Host "Installing $Name..."
$Installations | Where-Object { $_.Name -eq $Name } | Sort-Object { $_.Step -as [int] } | ForEach-Object {
ExecuteStep -Path $_.Path -Arguments $_.Arguments
}
}
function ExecuteStep ($Path, $Arguments) {
Write-Host "Executing '$Path' '$Arguments'"
Start-Process -FilePath $Path -ArgumentList $Arguments -Wait
}
function Menu {
$UniqueSoftware = $Installations | Select-Object -ExpandProperty Name -Unique | Sort-Object
$NumOfSoftware = $UniqueSoftware.Count
#Generate menu
Clear-Host
for($i=0;$i -lt $NumOfSoftware; $i++) {
Write-Host ("{0}. Install {1}" -f ($i+1), $Software[$i].Name)
}
Write-Host ("{0}. Install all" -f ($NumOfSoftware+1))
Write-Host "0. Exit"
do {
#Get input
$value = (Read-Host "Input your selection (0-$($NumOfSoftware+1))") -as [int]
#Execute
switch ($value) {
0 { exit }
{ $_ -gt 0 -and $_ -le $NumOfSoftware } { InstallSoftware -Name $UniqueSoftware[($_-1)] }
($NumOfSoftware+1) { 0..($NumOfSoftware-1) | ForEach-Object { InstallSoftware -Name $UniqueSoftware[($_)] } }
default { Write-Host "Invalid input..." }
}
#Validate input or retry
} until ( $value -ge 0 -and $value -le $NumOfSoftware+1 )
}
#Start the train
while($true) { Menu }
那是因为每次你安装东西时,你都会递归调用InstallOptions什么是循环回到“菜单”的更好方法?好吧,如果我在做这件事,我会完全重新设计方法,tbh,没有必要尝试做得更好我不反对重写它。我是一个新手,如果你想给我介绍一个资源,在那里我可以学习不同的方法,我很乐意学习。我认为学习创建一个带有按钮的GUI对你来说是一个好主意,这样你就不必担心循环等等,因为这都是函数,您可以拥有安装功能和开关,当用户按下按钮时,它会将号码发送到开关,然后开关会激活安装。foxdeploy给我们上了一堂关于GUI的好课:祝你好运,我可以看到你一次又一次地利用这个想法!非常感谢。我一直在一块一块地构建它,但我肯定看到了以你的方式进行的价值,因为这样做效率更高。我会试试看它是否能按我需要的方式工作。没问题。如果您所拥有的对您有用,那么简单的解决方案就是第一个示例中的修复。另一个只是一个更具动态性的替代解决方案,但是有很多方法可以做到这一点,正确的解决方案取决于软件。这可能不是复杂安装脚本的最佳步骤。实际上,我再次更新了替代解决方案,以支持多个步骤(已订购),从而为您提供多部分安装的想法谢谢,您真是太好了。如果我不在这个脚本中使用它,我肯定会在我需要的第二个脚本中使用它。我想一行一行地看一遍,真正理解它在做什么。
$Software1Path = "Path to installer"
$Software2Path = "Path to installer"
$Software3Path = "Path to installer"
function Software1 {
$Software1Arguments = "/S"
Start-Process -FilePath $Software1Path -ArgumentList $Software1Arguments -Wait
}
function Software2 {
$Software2Arguments = "/silent"
Start-Process -FilePath $Software2Path -ArgumentList $Software2Arguments -Wait
}
function Software3 {
$Software3Arguments = "/passive"
Start-Process -FilePath $Software3Path -ArgumentList $Software3Arguments -Wait
}
function InstallOptions {
Clear-Host
Write-Host('1. Install Software1')
Write-Host('2. Install Software2')
Write-Host('3. Install Software3')
Write-Host('4. Install All Three')
Write-Host('0. Exit')
$value = Read-Host 'Input your selection (0-3)'
switch ($value) {
"0" {exit}
"1" { Software1}
"2" { Software2}
"3" { Software3}
"4" {
Software1
Software2
Software3
}
}
}
#Start the train
while($true) { InstallOptions }
$Installations = @(@"
Name,Step,Path,Arguments
Software1,1,"c:\Install Files\Product1\Setup.exe",/S
Software2,2,"c:\Install Files\Product2\SetupPart2.exe",/silent
Software2,1,"c:\Install Files\Product2\Setup.exe","/silent ""space test with ,"""
Software3,1,"c:\Install Files\Product3\Setup.exe",/passive "space test"
"@ | ConvertFrom-Csv)
function InstallSoftware ($Name) {
Write-Host "Installing $Name..."
$Installations | Where-Object { $_.Name -eq $Name } | Sort-Object { $_.Step -as [int] } | ForEach-Object {
ExecuteStep -Path $_.Path -Arguments $_.Arguments
}
}
function ExecuteStep ($Path, $Arguments) {
Write-Host "Executing '$Path' '$Arguments'"
Start-Process -FilePath $Path -ArgumentList $Arguments -Wait
}
function Menu {
$UniqueSoftware = $Installations | Select-Object -ExpandProperty Name -Unique | Sort-Object
$NumOfSoftware = $UniqueSoftware.Count
#Generate menu
Clear-Host
for($i=0;$i -lt $NumOfSoftware; $i++) {
Write-Host ("{0}. Install {1}" -f ($i+1), $Software[$i].Name)
}
Write-Host ("{0}. Install all" -f ($NumOfSoftware+1))
Write-Host "0. Exit"
do {
#Get input
$value = (Read-Host "Input your selection (0-$($NumOfSoftware+1))") -as [int]
#Execute
switch ($value) {
0 { exit }
{ $_ -gt 0 -and $_ -le $NumOfSoftware } { InstallSoftware -Name $UniqueSoftware[($_-1)] }
($NumOfSoftware+1) { 0..($NumOfSoftware-1) | ForEach-Object { InstallSoftware -Name $UniqueSoftware[($_)] } }
default { Write-Host "Invalid input..." }
}
#Validate input or retry
} until ( $value -ge 0 -and $value -le $NumOfSoftware+1 )
}
#Start the train
while($true) { Menu }