Public/Start-Countdown.ps1

<#
 
# Start-Countdown
 
Zeigt die Restlaufzeit in einem GUI-Fenster.
 
- **Hashtags** UserCmdlet Countdown
 
- **Version** 2020.6.8
 
#>


using namespace System
using namespace System.Management.Automation
using namespace System.Windows.Markup
using namespace System.Windows.Media
using namespace System.Windows.Threading

$BackupErrorActionPreference = $ErrorActionPreference
$ErrorActionPreference = [ActionPreference]::Stop
Set-StrictMode -Version Latest

Add-Type -AssemblyName 'WindowsBase'
Add-Type -AssemblyName 'PresentationFramework'
Add-Type -AssemblyName 'PresentationCore'

function Start-Countdown {
    <#
        .SYNOPSIS
            Zeigt die Restlaufzeit in einem GUI-Fenster.
 
        .EXAMPLE
            Start-Countdown -Minutes 15 -Title 'Kaffeepause-Ende in'
    #>

    param (
        [ValidateRange(1, 525600)] # 1 Minute bis 1 Jahr
        [decimal]$Minutes = 1,

        [ValidateLength(3, 50)]
        [string]$Title = 'Restlaufzeit des Countdowns'
    )

    $Script:My = [HashTable]::Synchronized(@{})

    $Script:My.WindowXaml = @'
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Countdown" WindowStartupLocation="CenterScreen" Height="270" Width="770">
    <Viewbox StretchDirection="Both" Stretch="Uniform">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <TextBlock x:Name="Überschrift" Grid.Row="0" HorizontalAlignment="Center" Margin="50 20" VerticalAlignment="Center" FontFamily="Consolas" FontSize="40" FontWeight="ExtraBold" />
            <TextBlock x:Name="CounterText" Grid.Row="1" HorizontalAlignment="Center" Margin="50 20" VerticalAlignment="Center" FontFamily="Consolas" FontSize="40" />
            <ProgressBar x:Name="ProgressBar" Grid.Row="2" Background="Transparent" Maximum="100" Margin="50 20" Height="50" />
        </Grid>
    </Viewbox>
</Window>
'@


    $Script:My.Window = [XamlReader]::Parse($Script:My.WindowXaml)

    $Script:My.Überschrift = $Script:My.Window.FindName('Überschrift')
    $Script:My.Überschrift.Text = $Title

    $Script:My.CounterText = $Script:My.Window.FindName('CounterText')
    $Script:My.ProgressBar = $Script:My.Window.FindName('ProgressBar')

    $Script:My.Timer = New-Object -TypeName 'DispatcherTimer'
    $Script:My.DauerGesamt = New-TimeSpan -Minutes $Minutes
    $Script:My.Ende = (Get-Date) + $Script:My.DauerGesamt

    $Script:My.Window.Add_Loaded({
        $Script:My.Timer.Interval = [timespan]::FromSeconds(1)
        $Script:My.Timer.Add_Tick({
            $DauerRest = $Script:My.Ende - (Get-Date)

            if ($DauerRest.TotalSeconds -le 0) {
#$Script:My.Window.Close()
$Script:My.Timer.Stop()
$Script:My.CounterText.Text = '{0:#.##} Minuten sind abgelaufen! ' -f $DauerRest.TotalMinutes
            }

            $ZeitAbgelaufenInSekunden = [int]($Script:My.DauerGesamt.TotalSeconds - $DauerRest.TotalSeconds)
            $ZeitAbgelaufenInProzent = [int]($ZeitAbgelaufenInSekunden / $Script:My.DauerGesamt.TotalSeconds * 100)
            $CountdownMessage = '{0} Stunden - {1} Minuten - {2} Sekunden' -f $DauerRest.Hours, $DauerRest.Minutes, $DauerRest.Seconds
            if ($DauerRest.Hours   -eq 1) { $CountdownMessage = $CountdownMessage -replace 'Stunden'  , 'Stunde'  }
            if ($DauerRest.Minutes -eq 1) { $CountdownMessage = $CountdownMessage -replace 'Minuten'  , 'Minute'  }
            if ($DauerRest.Seconds -eq 1) { $CountdownMessage = $CountdownMessage -replace 'Sekunden' , 'Sekunde' }

            $Script:My.CounterText.Text = $CountdownMessage
            $Script:My.ProgressBar.Value = $ZeitAbgelaufenInProzent
            switch ($ZeitAbgelaufenInProzent) {
                {$_ -ge  0 -and $_ -le 10} { $Script:My.ProgressBar.Foreground="Yellow"      ; break }
                {$_ -gt 10 -and $_ -le 20} { $Script:My.ProgressBar.Foreground="GreenYellow" ; break }
                {$_ -gt 20 -and $_ -le 30} { $Script:My.ProgressBar.Foreground="YellowGreen" ; break }
                {$_ -gt 30 -and $_ -le 40} { $Script:My.ProgressBar.Foreground="Green"       ; break }
                {$_ -gt 40 -and $_ -le 50} { $Script:My.ProgressBar.Foreground="DeepSkyBlue" ; break }
                {$_ -gt 50 -and $_ -le 60} { $Script:My.ProgressBar.Foreground="DodgerBlue"  ; break }
                {$_ -gt 60 -and $_ -le 70} { $Script:My.ProgressBar.Foreground="Blue"        ; break }
                {$_ -gt 70 -and $_ -le 80} { $Script:My.ProgressBar.Foreground="Orange"      ; break }
                {$_ -gt 80 -and $_ -le 90} { $Script:My.ProgressBar.Foreground="OrangeRed"   ; break }
                {$_ -gt 90               } { $Script:My.ProgressBar.Foreground="Red"         ; break }
            }
        })
        $Script:My.Timer.Start()
    })

    $Script:My.Window.Add_Unloaded({
        $Script:My.Timer.Stop()
    })

    $Script:My.Window.Topmost = $true
    $Script:My.Window.ShowDialog() | Out-Null
    Clear-Variable -Name this -Scope Script -Force
}
$ErrorActionPreference = $BackupErrorActionPreference
Set-StrictMode -Off