Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell 如何循环脚本,让用户选择不同的选项?_Powershell - Fatal编程技术网

Powershell 如何循环脚本,让用户选择不同的选项?

Powershell 如何循环脚本,让用户选择不同的选项?,powershell,Powershell,对Powershell来说相当陌生。我正在编写一个脚本,允许用户安装所需的不同软件。此过程目前正在手动完成,安装所需的所有内容可能需要30-45分钟。然而,并不是所有的东西都需要安装在每个工作站上,所以我需要为用户提供灵活性。这就是我到目前为止所想到的。(为简洁起见进行了修改) 它没有给出期望的结果。我可以安装一个软件,但是脚本退出,我也不能安装所有三个。我已经使用了InstallOptions并用十种不同的方式编写了它,但是我仍然没有得到想要的结果。有什么建议吗 您可以在while($true

对Powershell来说相当陌生。我正在编写一个脚本,允许用户安装所需的不同软件。此过程目前正在手动完成,安装所需的所有内容可能需要30-45分钟。然而,并不是所有的东西都需要安装在每个工作站上,所以我需要为用户提供灵活性。这就是我到目前为止所想到的。(为简洁起见进行了修改)


它没有给出期望的结果。我可以安装一个软件,但是脚本退出,我也不能安装所有三个。我已经使用了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 }