如何遍历脚本让用户选择不同的选项?

时间:2017-03-03 16:30:34

标签: powershell

Powershell相当新鲜。我正在编写一个脚本,让用户安装所需的不同软件。此过程目前正在手动完成,安装所需的一切可能需要30-45分钟。但是,并非所有工作站都需要安装,因此我需要用户灵活性。这是我到目前为止所提出的。 (为简洁而修改)

$Software1Path = "Path to installer"
$Software2Path = "Path to installer"
$Software3Path = "Path to installer"


function Software1 {
     $Software1Arguments = "/S"
     Start-Process -FilePath $Software1Installer $Software1Arguments -Wait

     InstallOptions
}

function Software2 {
     $Software2Arguments = "/silent"
     Start-Process -FilePath $Software2Installer $Software2Arguments -Wait

     InstallOptions
}


function Software3 {
     $Software3Arguments = "/passive"
     Start-Process -FilePath $Software3Installer $Software3Arguments -Wait

     InstallOptions
}



function InstallOptions {
    Do {
        Clear-Host

        Write-Host('1. Install Software1')
        Write-Host('2. Install Software1')
        Write-Host('3. Install Software1')
        Write-Host('4. Install All Three')
        Write-Host('0. Exit')
        $value = Read-Host 'Input your selection (0-3)'
        }

     Until ($value -eq "o"){
        switch ($value) {
                "0" {exit}
                "1" { Software 1}
                "2" { Software 2}
                "3" { Software 3}
                "4" { Software1  
                      Software2
                      Software3}
       }
     }

}

它没有给出期望的结果。我可以安装一个软件,但然后脚本退出,我也无法安装所有三个。我已经使用了InstallOptions,并用十种不同的方式编写了它,但我仍然没有得到理想的结果。有什么建议?

1 个答案:

答案 0 :(得分:1)

您可以在InstallOptions中调用while($true) {}(只要您保持0退出)或其他类型的循环,以使其返回菜单。如果您从软件安装功能中调用菜单,当您使用"安装所有"时,它将永远不会达到2和3。尝试:

$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 }

您可能还想要清理它。防爆。当$Sofware1Path在里面时,$Software1Arguments在函数之外。对于简单安装,您可以清理它以使用ex。一个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 }