在阵列中执行Robocopy foreach文件夹-仅在选中相应复选框的情况下?

时间:2019-06-04 06:37:32

标签: powershell if-statement foreach robocopy

我们有一个PowerShell表单,其中包含按钮和复选框,以及一个用于显示输出的文本框; 我们有3个复选框分别标记为“ folder1”,“ folder2”和“ folder3”。 我们有一个用于启动robocopy的按钮(无ForEach循环) 我们有一个显示所有脚本输出的文本框 注意:这已经可以完美工作了;我们只是想用一个ForEach循环来完成它

我们希望robocopy仅在选中相应复选框的情况下使用foreach循环复制文件夹(c:\ folder1,c:\ folder2,c:\ folder3)。

如果每个文件夹都有一个单独的robocopy实例,则它可以正常工作,并且仅在选中复选框后才复制一个文件夹。 (请参见下面的代码) 我们只想使用ForEach循环来完成此操作,因为在每段代码中唯一不同的是文件夹的名称和复选框的名称

我们认为问题是,由于“ if($ folder.Checked)”代码,PowerShell正在寻找一个名为“ $ folder”的复选框,而不是像使用文件夹名称和日志文件。

重要说明;我们意识到在这个示例中,没有多少行代码被删除(如果有的话),但是当我们使之工作时,文件夹和复选框的数量将超过3,因此这就是为什么我们希望这样做的原因

TL; DR: 我们有一个带有复选框的PowerShell表单,以及一个启动robocopy的按钮。如果选中了“ folder1”复选框,则应复制“ c:\ src \ folder1”,依此类推。在没有ForEach循环的情况下,它已经可以完美运行,我们只是希望通过ForEach循环来完成

这是什么语法?参见下面的代码

非常感谢您的任何帮助

我们尝试将“ if($ folder.Checked)”放在方括号,引号,双引号,单引号以及它们的不同变体中。我们还尝试以不同的方式在第二个数组中定义复选框,然后在现有的ForEach中添加第二个ForEach,但它仍然不检查复选框是否被选中,有时它多次复制同一文件夹,这在我们尝试时很有意义另一个ForEach内部的一个ForEach。

这是我们目前拥有的解决方案,它可以完美运行:

if ($folder1.Checked) {
 robocopy "c:\src\folder1" "c:\dst\folder1" /l /log+:"c:\folder1.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
 }
if ($folder2.Checked) {
 robocopy "c:\src\folder2" "c:\dst\folder2" /l /log+:"c:\folder2.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
 }
if ($folder3.Checked) {
 robocopy "c:\src\folder3" "c:\dst\folder3" /l /log+:"c:\folder3.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
 }
}

这不起作用:

$Folders = @('folder1','folder2','folder3')
foreach ($Folder in $Folders) {
    if ($folder.Checked) { ##<-- Fails here because it looks for a checkbox named "$folder" instead of going through the array for names##
        robocopy "c:\src\$Folder" "c:\dst\$Folder" /l /log+:"c:\$Folder.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
       } else {$outputBox.AppendText("$folder NOT SELECTED" + "`r`n")}
}
}

此ForEach循环也可以完美运行(但没有复选框),因此我们知道不是ForEach循环存在任何问题:

$Folders = @('folder1','folder2','folder3')
foreach ($Folder in $Folders) {
        robocopy "c:\src\$Folder" "c:\dst\$Folder" /l /log+:"c:\$Folder.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
       }
}
}

预期结果: 仅当选中相应的checlbox并使用ForEach循环时,才复制文件夹。使用ForEach时,只有没有ForEach,我们才能让PowerShell来检查已选中的复选框

表格的完整代码:


#ENABLE VISUALSTYLES#
[System.Windows.Forms.Application]::EnableVisualStyles()

#----------------------------------------------------------------------------GUI FORM + CONSOLE OUTPUT (TEXTBOX)----------------------------------------------------------------------------#
$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(1100,771)
$form.FormBorderStyle = "FixedDialog"
$form.StartPosition = "CenterScreen"
$form.Topmost = $False
$form.add_Load($FormEvent_Load)

#CONSOLE OUTPUT#
$outputBox = New-Object System.Windows.Forms.TextBox 
$outputBox.Location = New-Object System.Drawing.Size(240,110) 
$outputBox.Size = New-Object System.Drawing.Size(850,500)
$outputBox.MultiLine = $True 
$outputBox.ScrollBars = "Both" #"Vertical","Horizontal" 
$outputBox.BackColor = "White"
$outputBox.WordWrap = $False
$outputBox.ReadOnly = $True
$Form.Controls.Add($outputBox)        

#----------------------------------------------------------------------------BUTTONS----------------------------------------------------------------------------#      
$3Button = New-Object System.Windows.Forms.Button
$3Button.Location = New-Object System.Drawing.Size(10,270)
$3Button.Size = New-Object System.Drawing.Size(150,20)
$3Button.Text = "foreach robocopy test"
#$3Button.Add_Click({RobocopyForEveryCheckbox})
$3Button.Add_Click({RobocopyForEach})
$form.Controls.Add($3Button)

#----------------------------------------------------------------------------CHECKBOXES----------------------------------------------------------------------------#
$folder1 = New-Object System.Windows.Forms.checkbox
$folder1.Location = New-Object System.Drawing.Size(10,55)
$folder1.Size = New-Object System.Drawing.Size(110,20)
$folder1.Checked=$True
$folder1.Text = "Folder1"
$form.Controls.Add($folder1)

$folder2 = New-Object System.Windows.Forms.checkbox
$folder2.Location = New-Object System.Drawing.Size(10,75)
$folder2.Size = New-Object System.Drawing.Size(130,20)
$folder2.Checked=$True
$folder2.Text = "Folder2"
$form.Controls.Add($folder2)

$folder3 = New-Object System.Windows.Forms.checkbox
$folder3.Location = New-Object System.Drawing.Size(10,95)
$folder3.Size = New-Object System.Drawing.Size(130,20)
$folder3.Checked=$True
$folder3.Text = "Folder3"
$form.Controls.Add($folder3)

#----------------------------------------------------------------------------FUNCTIONS----------------------------------------------------------------------------#

##############THIS FUNCTION WORKS PERFECTLY###############
function RobocopyForEveryCheckbox {
if ($folder1.Checked) {
 robocopy "c:\src\folder1" "c:\dst\folder1" /l /log+:"c:\folder1.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
 }
if ($folder2.Checked) {
 robocopy "c:\src\folder2" "c:\dst\folder2" /l /log+:"c:\folder2.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
 }
if ($folder3.Checked) {
 robocopy "c:\src\folder3" "c:\dst\folder3" /l /log+:"c:\folder3.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
 }
}

###############THIS FUNCTION DOES -NOT- WORK. BUT IT WORKS PERFECTLY IF WE DO NOT CHECK FOR CHECKED BOXES BUT IT'S THE ONE WE WANT TO USE#########################
function RobocopyForEach {
$Folders = @('folder1','folder2','folder3')
foreach ($Folder in $Folders) {
    if ($folder.Checked) { ###<-----Fails here because it looks for a checkbox named "$folder" instead of going through the array for names and so it cannot find a checkbox named "$folder" because no such exists##
        robocopy "c:\src\$Folder" "c:\dst\$Folder" /l /log+:"c:\$Folder.txt" /njh /njs /ndl /np /tee | foreach {$outputBox.AppendText($_ + "`r`n")}
        } else {$outputBox.AppendText("$folder NOT SELECTED" + "`r`n")}
}
}

$form.ShowDialog()

2 个答案:

答案 0 :(得分:1)

您已经创建了一个数组或字符串,并正在循环遍历。

这就是您的代码所见。

Foreach($Folder in $Folders) {
    If([String]Folder1.Checked) {
    }
}

您想要的是创建一个对象数组。

$Folders = @("$folder1","$folder2","$folder3")

这应该允许您遍历对象并检查它们的状态。

System.Windows.Forms.CheckBox, CheckState: 1
System.Windows.Forms.CheckBox, CheckState: 0
System.Windows.Forms.CheckBox, CheckState: 0

然后您可以通过

得到1(真)或0(假)
($folder.Split(": "))[3]

答案 1 :(得分:0)

只需松开引号即可:

$checkbox1 = New-Object System.Windows.Forms.checkbox
$checkbox1.Location = New-Object System.Drawing.Size(10,55)
$checkbox1.Size = New-Object System.Drawing.Size(110,20)
$checkbox1.Checked = $True
$checkbox1.Text = "Folder1"
$checkbox1.Tag = "c:\Custom-Files"
$form.Controls.Add($checkbox1)

$checkbox2 = New-Object System.Windows.Forms.checkbox
$checkbox2.Location = New-Object System.Drawing.Size(10,75)
$checkbox2.Size = New-Object System.Drawing.Size(130,20)
$checkbox2.Checked = $True
$checkbox2.Text = "Folder2"
$checkbox2.Tag = "c:\somefolder"
$form.Controls.Add($checkbox2)

$checkbox3 = New-Object System.Windows.Forms.checkbox
$checkbox3.Location = New-Object System.Drawing.Size(10,95)
$checkbox3.Size = New-Object System.Drawing.Size(130,20)
$checkbox3.Checked = $True
$checkbox3.Text = "Folder3"
$checkbox3.Tag = "c:\anotherfolder"
$form.Controls.Add($checkbox3)

function RobocopyForEach 
{
    $checkboxes = @($checkbox1, $checkbox2, $checkbox3)

    foreach ($checkbox in $checkboxes) 
    {
        if ($checkbox.Checked) 
        {
            robocopy "c:\src\$($checkbox.Tag)" "c:\dst\$($checkbox.Tag)" /l /log+:"c:\$($checkbox.Tag).txt" /njh /njs /ndl /np /tee | ForEach-Object { $outputBox.AppendText($_ + "`r`n") }
        } 
        else 
        {
            $outputBox.AppendText("$($checkbox.Text) NOT SELECTED" + "`r`n")
        }
    }
}