Source/Public/Demo-Construct.ps1

# Filename: Demo-Construct.ps1
# Author: Frits van Drie (3-Link.nl)
# Date: 2022-04-06


#region: If, ElseIf, Else

    <#
        If (Condition1) {Action1}
        ElseIf (Condition2) {Action2}
        ElseIf (Condition3) {Action3}
        Else {Action4}
    #>


    $one = 1
    $two = 2

    If ($one -eq 0 -or $two -eq 0) {Write-Host "$one or $two is Zero"}
    ElseIf ($one -gt $two)         {Write-Host "$One > $Two"}
    ElseIf ($one -lt $two)         {Write-Host "$One < $Two"}
    Else                           {Write-Host "$One = $Two"}

    Suspend-Service workstation
    Get-Service 'l*' | ForEach-Object {
        if ($_.status -eq 'running') {
            write-host "$($_.Name) is started" -ForegroundColor Green
        }
        elseif ($_.status -eq 'stopped') {
            write-host "$($_.Name) is stopped" -ForegroundColor Red
        }
        else {
            write-host "$($_.Name) is $($_.status)" -ForegroundColor Yellow
        }
    }
    Resume-Service workstation

#endregion


#region: ForEach (Statement/Construct)
    
    # ForEach ( $x in $y ) {
    # <commands>
    # }

    # PS 7: Parallel processing
    # ForEach -Parallel ( $x in $y ) {
    # <commands>
    # }


    $SvcList = Get-service "sp*"
    ForEach ( $Svc in $SvcList ) {
        Write-Host "$($Svc.Name) is $($Svc.Status)"
    }

    # Foreach Construct is not the same as ForEach-Object Cmdlet !!!

    $SvcList |ForEach-Object {
        Write-Host "$($_.Name) is $($_.Status)"
    }

    # Wrong
    ForEach-Object ( $Svc -in $SvcList ) {
        Write-Host "$($Svc.Name) is $($Svc.Status)"  # > ERROR
    }

    ForEach ( $Svc in $SvcList ) {
        Write-Host "$($Svc.Name) is $($Svc.Status)"
    }


#endregion


#region: Break the loop: Continue / Break

    $array = @('1','2','3','4')

    foreach ($nr in $array) {
        if ($nr -lt 3 ) {
            Write-Host "$nr < 3"
        }
        Write-Host "$nr >= 3"
    }

    ###

    $array = @('1','2','3','4')

    foreach ($nr in $array) {
        if ($nr -lt 3 ) {
            Write-Host "$nr < 3"
            continue
        }
        Write-Host "$nr >= 3"
    }

    ###

    $array | foreach {
        if ($_ -lt 3 ) {
            Write-Host "$_ < 3"
            Break
        }
        Write-Host "$_ >= 3"
    }

#endregion


#region: For () {}

    # Repeat code block while condition is true

    # For (start; condition; action ) { codeblock }



    For ($x = 1; $x -le 10; $x++ ) {
        Write-Host "Line $x"
    }

    1..10 | foreach {Write-Host "Line $_"}
    1..10 | Write-Host "Line $_" #> ERROR
    1..10 | Write-Host
    1..10

    help Write-Host -ShowWindow

#endregion


#region: Do .. While .. Until

    # Executed at least 1 time
    # Repeat while condition is True

    # Do {codeblock} While (condition is true)
    # Do {...} While (...)


    $x = 10
    Do {
        Write-Host "Line $x"
        $x++
    }
    While ($x -le 10)


#endregion


#region: Do .. Until

    # Executed at least 1 time
    # Repeat while condition is False
    # Do {codeblock} Until (condition is true)

    $x =0
    Do {$x++; Write-Host "Line $x"} until ($x -gt 5)

    $x =6
    Do {$x++; Write-Host "Line $x"} until ($x -gt 5)


    $x =0
    Do {$x++; Write-Host "Line $x"} until ($x -le 5)

    $x =6
    Do {$x++; Write-Host "Line $x"} until ($x -le 5)

#endregion

    
#region: While

    # Executed at least 0 time
    # While (condition is true) {codeblock}


    $x =1
    While ($x -le 4) {
        Write-Host "Line $x"
        $x++
    }


    $x =5
    While ($x -le 4) {
        Write-Host "Line $x"
        $x++
    }

    # Attention: when condition is already true !!
    $Menu = "Make a choice"

    Do {$choice = Read-Host $Menu}  While ($choice -notin ('1','2','3','4','5')) 

    While ($choice -notin ('1','2','3','4','5'))  {$choice = Read-Host $Menu}

    Remove-Variable choice

    While ($choice -notin ('1','2','3','4','5'))  {$choice = Read-Host $Menu}

    <#
    :red while (<condition1>) {
      :yellow while (<condition2>) {
        while (<condition3>) {
          if ($a) {break}
          if ($b) {break red}
          if ($c) {break yellow}
        }
        Write-Host "After innermost loop"
      }
      Write-Host "After yellow loop"
    }
    Write-Host "After red loop"
    #>

    $red    = 0
    $yellow = 0
    $green  = 0
    $breakGreen  = $true
    $breakYellow = $true
    $breakRed    = $true

    :red while ( $red -le 2 ) {
        $red++
        Write-Host "Red loop $red" -f Red
        Start-Sleep 1

        :yellow while ( $yellow -le 2 ) {
            $yellow++
            Write-Host "`tYellow loop $yellow" -f Yellow
            Start-Sleep 1

            while ( $green -le 2 ) {
                $green++
                Write-Host "`t`tGreen loop $green" -f Green 
                Start-Sleep 1
                if ($breakGreen)  {break}
                if ($breakYellow) {break yellow}
                if ($breakRed)    {break red}
            }
            Write-Host "`t`tAfter green loop" -f Green
        }
        Write-Host "`tAfter yellow loop" -f Yellow
    }
    Write-Host "After red loop" -f Red
#endregion


#region: Switch
    <#
        Switch (Variable to test) {
            1 {command 1} # multiple values can be true
            2 {command 2}
            Default {action default}
        }
    #>

    $x = 2
    Switch ($x) {
        1 {Write-Host "Option 1"}
        2 {Write-Host "Option 2"}
        3 {Write-Host "Option 3"}
        Default {Write-Host "Something Else"}
    }


    $x = 5
    Switch ($x) {
        1 {Write-Host "Option 1"}
        2 {Write-Host "Option 2"}
        3 {Write-Host "Option 3"}
        Default {Write-Host "Something Else"}
    }
    #> Option 2


    $x = 'Rotterdam'
    Switch -Wildcard ($x) {
        *dam {Write-Host "Rotterdam or Amsterdam"}
        A*   {Write-Host "Amsterdam"}
        R*   {Write-Host "Rotterdam"}
        Default {Write-Host "Somewhere else"}
    }
    #> Rotterdam or Amsterdam
    #> Rotterdam

    $Size = 465388000000
    Switch ($Size) {
        DEFAULT      { $Unit = 1   ;  $Symbol = 'B'}
        {$_ -gt 1KB} { $Unit = 1KB ;  $Symbol = 'KB'}
        {$_ -gt 1MB} { $Unit = 1MB ;  $Symbol = 'MB'}
        {$_ -gt 1GB} { $Unit = 1GB ;  $Symbol = 'GB'}

    }
    "Total size: {0:N2} $Symbol" -f ($Size/$Unit)

#endregion


#region: Begin..Proces..End

    Function Demo-BeginProcessEnd {
        PARAM (
            $Par1,
            [parameter(ValueFromPipeline=$true)]$Par2,
            [parameter(ValueFromPipeline=$true)]$Par3
        )

        Begin{
            Write-Host "Start Function: $($MyInvocation.MyCommand)"
            Write-Host "Begin:`tExecuted once" -ForegroundColor Green
            Write-Host "="
            $i = 1
        }

        Process {
            Write-Host "Process Pipeline input: $Par2" -BackgroundColor White -ForegroundColor Blue
            foreach ($p in $Par1) {
                Write-Host "`t Parameter: $p"
            }
        }

        End{
            write-Host "="
            Write-Host "End Function: $($MyInvocation.MyCommand)"
            Write-Host "End:`tExecuted once" -ForegroundColor Red
        }
    }

    cls
    "ABC", "DEF" | Demo-BeginProcessEnd -Par1 "123", "456", "789"


    ##################
    Function Test
    {
        begin
        {
            $i = 0
        }

        process
        {
            "Iteration: $i"
            $i++
            "`tInput: $input, $input"
            "`tInput: $input"
            "`tAccess Again: $input"
            $input.Reset()
            "`tAfter Reset: $input"
        }
    }
    "one","two" | Test



#endregion


#region: Demo-Menu:
    $gsv = 'Get-Service'
    $gps = 'Get-Process'
    $msg = $null

    Function MakeMenu {
    $Script:Menu= @"
Menu
---------------------------

`t1.`t$gsv
`t2.`t$gps
`t3.`tGet System Eventlog
`t4.`tCheck Freespace (GB) `t$msg
`t5.`tQuit

`tSelect an option
"@
     # @"" = Multi-line string literal with embedded variables.
    }
    Do {
        MakeMenu
        $msg = $null
        $choice = Read-Host $Menu
        Switch ($choice) {

            1 {Invoke-Expression $gsv}
            2 {Invoke-Expression $gps}
            3 {Get-Eventlog -LogName System -Newest 10}
            4 {$FreeSpace = '{0:N0}'-f ((Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DeviceId='c:'").FreeSpace/1GB)+" GB"
              #{((Get-wmiObject -Class Win32_LogicalDisk -Filter "DeviceId='c:'").FreeSpace/1GB)}
               $msg = "Freespace: $FreeSpace"
              }
            5 {Break}
            default {Write-Warning "$choice is not a valid choice"}

        }
    } While ($choice -ne 5) 

#endregion