Multiple foreach on if statement

Hello,

I’m trying to rerun task-sequences on multiple computers from a Drop-Down list that contains the task-sequences names, and a computer list is loaded via a text file.

I tryed 2 diferent functions, $Install_OnClick and $Install_OnClick2, but the action isn’t being triggered, no errors or output from ISE, i’m using a Powershell GUi with a Combobox/Drop-Down List

How can i achieve this?

Thank you

#TaskSequences
$W10_PRELOAD_1809 = "W10_PRELOAD_1809"
$W10_UPG_1809 = "W10_UPG_1809"
$W10_UPG_1809_FORCE = "W10_UPG_1809_FORCE"

$Browse_OnClick = {
    $FileName = Select-FileDialog
    $Computers = Get-Content $FileName
    $Install.enabled = $true
}

$TaskSequence = "$W10_PRELOAD_1809", "$W10_UPG_1809", "$W10_UPG_1809_FORCE", "$W7_CHECK_PRELOAD", "$W7_1809_PRELOAD", "$W7_UPG_1809", "$W7_UPG_1809_FORCE"
$TaskSequence | % { $ListApps.Items.Add($_) }

$Install_OnClick = {
    if (!$ListApps.SelectedItem) {
        [System.Windows.Forms.MessageBox]::Show("Please select a Task-Sequence from the drop down menu")
    }
    else {
        $TaskSequence = $ListApps.SelectedItem.ToString()

        foreach ($Computer in $Computers) {
            if ($TaskSequence -eq "W10_PRELOAD_1809") {
                ([wmiclass]"\\$Computer\ROOT\ccm:SMS_Client").TriggerSchedule('PIC22459--PIC00024-6F6BCC28')
            }

            if ($TaskSequence -eq "W10_UPG_1809") {
                ([wmiclass]"\\$Computer\ROOT\ccm:SMS_Client").TriggerSchedule('PIC22505-PIC00026-6F6BCC28')
            }

            if ($TaskSequence -eq "W10_UPG_1809_FORCE") {
                ([wmiclass]"\\$Computer\ROOT\ccm:SMS_Client").TriggerSchedule('PIC22458-PIC00026-6F6BCC28')
            }
        }
    } 
}

$Install_OnClick2 = {
    foreach ($Computer in $Computers) {
        foreach ($TaskSequence in $ListApps.SelectedItems) {   
            if ($TaskSequence -eq "W10_PRELOAD_1809") {
                ([wmiclass]"\\$Computer\ROOT\ccm:SMS_Client").TriggerSchedule('PIC22459--PIC00024-6F6BCC28')
            }

            if ($TaskSequence -eq "W10_UPG_1809") {
                ([wmiclass]"\\$Computer\ROOT\ccm:SMS_Client").TriggerSchedule('PIC22505-PIC00026-6F6BCC28')
            }

            if ($TaskSequence -eq "W10_UPG_1809_FORCE") {
                ([wmiclass]"\\$Computer\ROOT\ccm:SMS_Client").TriggerSchedule('PIC22458-PIC00026-6F6BCC28')
            }
        }
    } 
}

When you crosspost the same question at the same time to different forums you should at least post links to the other forums along with your question to avoid people willing to you help making their work twice or more.

https://stackoverflow.com/questions/62059290/multiple-foreach-on-if-statement

Thanks

Yes, you’re right, i’ve posted the question 8 hours ago, it’s seems that it’s not understandable. I didn’t know that i should mention that in this post, knowing its still an unanswered question.
Thanks for the feedback :slight_smile:

This is a very SCCM question, specifically OSD, so you would get better assistance in a thread specifically in that arena. There are many blogs that discuss re-running the Task Sequence, assuming that it is still advertised to the client:

Recommend testing this code on a single client first before you attempt to wrap it into a GUI

Hello,
Thanks for the answer
The action to rerun the task sequence is correct, and how to trigger the Task-Sequence via WMI.
If i run the individual code it works.
([wmiclass]“\$Computer\ROOT\ccm:SMS_Client”).TriggerSchedule(‘PIC22458-PIC00026-6F6BCC28’)

But let’me explain, i’ll try to provide an example of what i’m trying to do $Computers = ‘PC1’,‘PC2’ $Fruits/“Drop-DownList”= ‘Pears’, ‘Oranges’ If Oranges are choosed from Drop-Down list, and you hit install button it creates a file named Oranges.txt in PC1 and PC2 If Pears are choosed from Drop-Down list, and you hit install button ,it creates a file named Pears.txt in PC1 and PC2 Hope this helps :slight_smile: The thing that i cannot achieve is to use 2 foreach statements, tried 2 diferent function like Install_OnClick and Install_OnClick2

It seems the issue is less about foreach and if, and more about getting your button to run the code?

Could have sworn there was a dropdown control that you could have a Text and Value to set, which then you would just set the display text as the Task Seq name and the Identifier as the value. When you want the value, you just get SelectedValue vs SelectedText. Another option is to use a hash to do lookups:

https://stackoverflow.com/questions/46776392/powershell-listbox-item-different-value-from-item-text

Either option would remove the need for a loop. The other question is what is $Computers? If that is a multi-select or what kind of control is it because you are referencing it as an array of strings. If it was a multi-select or something, it would be like $computers.SelectedItems or something.

The $Computers is the code ($Computers = Get-Content $FileName), it loads a text file with computers names inside, and then it will trigger the Task-Sequence choosed from the drop-down list to the computers in that file. That’s we’re i’m a bit confused, and i’m still learning powershell to be honest and i don’t know witch is the best option to run the selected task-sequence or action on multiple computers.

The following code is working, performed tests creating a text file on a remote server for tests, this means that i can use the code i want for each action when Task-Sequence is choosed from the list. But i removed the most important part, to run this on multiple computers, or to create text files for each computer, this is the part that i cannot figure out how to make this run on multiple computers.

#foreach ($Computer in $Computers)

 $Install_OnClick= {

    if (!$ListApps.SelectedItem) {[System.Windows.Forms.MessageBox]::Show("Please select a Task-Sequence from the drop down menu")

       }
    else {

        $TaskSequenceItem = $ListApps.SelectedItem.ToString()

      if ($TaskSequenceItem -eq "W10_PRELOAD_1809")
        {
            New-Item -Path \\emeamai-rs08\TEMP\Baseline_FMT\test_$Computer.txt -Force
        }

        if ($TaskSequenceItem -eq "W10_UPG_1809")
        {
             New-Item -Path \\emeamai-rs08\TEMP\Baseline_FMT\test_$Computer.txt -Force
        }

        if ($TaskSequenceItem -eq "W10_UPG_1809_FORCE")
        {
            New-Item -Path \\emeamai-rs08\TEMP\Baseline_FMT\test_$Computer.txt -Force
        }

    }
}

So, GUI’s are cool and all, but you’re adding non-required pain to your development and this is alot of moving things for a first time Take a look at this module written by Adam Bertram:

Specifically, look Invoke-CMClientAction and the error handling that is done. This is basically the exact same thing you are doing, but rather than calling inventory policies, you are initiating a Task Sequence. As I stated above, he’s also using a hash to identify the ‘Friendly’ name and the identification. Start with the straight powershell and get it working with different computers and different task sequences. The gui wrapper is just providing a simple way to add computers and a dropdown of ‘ClientAction’. Here is the basic pseudo code:

function Invoke-CMClientAction {
...
}

$computers = Get-Content -Path 'C:\Scripts\computers.txt'

foreach ($computer in $computers) {
    Invoke-CMClientAction ...
}
$Servers = Get-Content $FileName

ForEach ($Server in $Servers){

    if (!$ListApps.SelectedItem) {[System.Windows.Forms.MessageBox]::Show("Please select a Task-Sequence from the drop down menu")

       }
    else {

        $TaskSequenceItem = $ListApps.SelectedItem.ToString()

      if ($TaskSequenceItem -eq "W10_PRELOAD_1809")
        {
            New-Item -Path \\emeamai-rs08\TEMP\Baseline_FMT\test_PRELOAD_$Server.txt -Force

        }

        if ($TaskSequenceItem -eq "W10_UPG_1809")
        {
             New-Item -Path \\emeamai-rs08\TEMP\Baseline_FMT\test_UPG_$Server.txt -Force
        }

        if ($TaskSequenceItem -eq "W10_UPG_1809_FORCE")
        {
          New-Item -Path \\emeamai-rs08\TEMP\Baseline_FMT\test_Force_$Computer.txt -Force
        }

    }
}
}