У нас есть форма PowerShell с кнопками и флажками, а также текстовое поле для отображения вывода;
У нас есть 3 флажка, помеченных как «folder1», «folder2» и «folder3».
У нас есть кнопка для запуска Robocopy (без цикла ForEach)
У нас есть текстовое поле, которое отображает весь вывод скрипта
ПРИМЕЧАНИЕ: это уже работает отлично; мы просто хотим сделать это с помощью цикла ForEach
Мы хотим, чтобы robocopy копировал только папки (c: \ folder1, c: \ folder2, c: \ folder3), если установлен соответствующий флажок, с циклом foreach.
Если у нас есть отдельный экземпляр robocopy для каждой папки, он отлично работает и копирует папку, только если установлен флажок. (см код ниже)
Мы просто хотим сделать это с помощью цикла ForEach, поскольку единственное, что отличается в каждом фрагменте кода, - это имя папки и имя флажка
Проблема заключается в том, что PowerShell ищет флажок с именем «$ folder» из-за кода «if ($ folder.Checked)» вместо сопоставления имени с массивом, как это происходит с foldernames и logfiles.
Важное примечание; мы понимаем, что в этом примере удаляется не так много строк кода (если они вообще есть), но когда мы заставим это работать, будет гораздо больше папок и флажков, чем 3, поэтому мы хотим, чтобы это было сделано таким образом, если это возможно .
TL; ДР:
У нас есть форма PowerShell с флажками и кнопка, которая запускает робокопию. Если флажок «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. Мы не можем заставить PowerShell проверять флажки при использовании ForEach, только без ForEach
Полный код формы:
#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()