Robocopy foreach folder in array - ONLY if corresponding checkbox is checked?

<p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; line-height: inherit; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; box-sizing: inherit; clear: both; color: #242729; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;">We have a PowerShell form, with buttons and checkboxes, and a textbox to display output; We have 3 checkboxes labeled "folder1", "folder2" and "folder3". We have a button for starting robocopy (no ForEach loop) We have a textbox which displays all script output NOTE: This already works perfectly; we just want it done with a ForEach loop instead</p> <p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; line-height: inherit; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; box-sizing: inherit; clear: both; color: #242729; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;">We want robocopy to only copy the folders (c:\folder1, c:\folder2, c:\folder3) if the corresponding checkbox is checked, with a foreach loop.</p> <p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; line-height: inherit; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; box-sizing: inherit; clear: both; color: #242729; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;">If we have a separate robocopy instance for each folder, it works perfectly and only copies a folder if a checkbox is checked. (see code below) We just want to do it with a ForEach loop because the only this that differs in each piece of code is the name of the folder, and name of the checkbox</p> <p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; line-height: inherit; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; box-sizing: inherit; clear: both; color: #242729; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;">What we think the problem is, is that PowerShell is looking for a checkbox named "$folder" because of the "if ($folder.Checked)" code, instead of matching the name up against the array like it does with foldernames and logfiles.</p> <p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; line-height: inherit; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; box-sizing: inherit; clear: both; color: #242729; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;">An important note; we realize that not many lines of code are removed (if any at all) with this example, but when we get this to work, there will be many more folders and checkboxes than 3, so that's why we want it done this way if possible.</p> <p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; line-height: inherit; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; box-sizing: inherit; clear: both; color: #242729; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;">TL;DR: We have a PowerShell form with checkboxes, and a button that starts a robocopy. If "folder1" checkbox is checked, "c:\src\folder1" should be copied, and so on. This already works perfectly without a ForEach loop, we just want it done with a ForEach loop instead</p> <p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; line-height: inherit; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; box-sizing: inherit; clear: both; color: #242729; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;">What is the syntax for this? See code below</p> <p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; line-height: inherit; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; box-sizing: inherit; clear: both; color: #242729; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;">THANK YOU VERY MUCH IN ADVANCE FOR ANY HELP</p> <p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; line-height: inherit; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; vertical-align: baseline; box-sizing: inherit; clear: both; color: #242729; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;">We have tried putting the "if ($folder.Checked)" in brackets, quotes, double quotes, single quotes and different variations of these. We also tried defining the checkboxes in a second array in different ways and then adding a second ForEach inside the existing ForEach, but it still does not check if the checkboxes are checked and sometimes it copies the same folder several times which makes sense when we tried a ForEach inside another ForEach.</p>
This is the solution we currently have, and it works perfectly: [pre]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")} } }[/pre]
This does not work: [pre]$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")} } }[/pre]
This ForEach loop also WORKS perfectly (but without checkboxes) so we know it's not the ForEach loop there is anything wrong with: [pre] $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")} } } } [/pre]
Full code for form:
[pre] #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() [/pre]

Your function isn’t referencing the form. All you’re doing is trying to look at the ‘checked’ property on the string objects in the $folders collection (which doesn’t exist).

What you want to do is get all the checkboxes on the form and test them. I didn’t test the robocopy bit, just that the output box showed the correct selections. I hope it points you in the right direction:

function RobocopyForeach {

    foreach ($control in $form.controls) {

        if ($control.GetType().ToString() -eq 'System.Windows.Forms.CheckBox') {

            if ($control.Checked) {

                $folder = $control.Text 
                robocopy "c:\src\$Folder" "c:\dst\$Folder" /l /log+:"c:\$Folder.txt" /njh /njs /ndl /np /tee
                $outputBox.AppendText($($control.Text) + "`r`n")
        
            } #end if checked do copy

            else {
    
                $outputBox.AppendText("$($control.Text) NOT SELECTED" + "`r`n") 

            } #end else skip copy
        
        } #end if control is checkbox
    
    } #end foreach 

} #end function

This is great, thank you very much for your help.