Set-Timer.ps1

<#PSScriptInfo
.VERSION 1.0
.GUID 79ad7a69-1b42-489a-a57c-49a6bc8f55d2
.AUTHOR saw-friendship
.COMPANYNAME
.COPYRIGHT
.TAGS
.LICENSEURI
.PROJECTURI https://sawfriendship.wordpress.com/2016/01/22/powershell-timer/
.ICONURI
.EXTERNALMODULEDEPENDENCIES
.REQUIREDSCRIPTS
.EXTERNALSCRIPTDEPENDENCIES
.RELEASENOTES
#>


<#
.DESCRIPTION
Run scriptblock at time
.PARAMETER at
Do script at time
.PARAMETER in
Do script it time
.EXAMPLE
Set-Timer -in 0 0 5 {hostname.exe}
Run scriptblock after 5 sec
.EXAMPLE
Set-Timer -in 00 00 10 {hostname.exe} -NoProgressBarShow -Force
.EXAMPLE
Set-Timer -at 17 59 59 {hostname.exe} -SoundPlayEvery 5 -SoundPlayBefore 30
.OUTPUTS
Scriptblock Results
.LINK
https://sawfriendship.wordpress.com/2016/01/22/powershell-timer/
#>

[CmdletBinding()]
    param(
        [switch]$at,
        [switch]$in,
        [int]$Hour = 0,
        [int]$Minute = 0,
        [int]$Second = 0,
        [Parameter(ValueFromPipeline = $true)][ScriptBlock]$ScriptBlock = {Write-Host "Done!"},
        [switch]$NoProgressBarShow,
        [int]$SoundPlayEvery,
        [int]$SoundPlayBefore,
        [switch]$Force
    )
    $VerbosePreference = "Continue"
    function SoundPlay {
        $SoundFile = "$env:windir\Media\Windows Feed Discovered.wav"
        if(Test-Path $SoundFile){
            try {
                $sound = new-Object System.Media.SoundPlayer
                $sound.SoundLocation = $SoundFile
                $sound.Play()
            } catch {}
        }
    }
    $GetDate = Get-Date
    try{
        if ($at -and !$in){
            [DateTime]$EndDate = Get-Date -Hour $Hour -Minute $Minute -Second $Second
            }     elseif ($in -and !$at) {
                    [DateTime]$EndDate = $GetDate.AddSeconds($($Second + $Minute*60 + $Hour*3600))
                } elseif ($at -and $in) {
                    Write-Error "Do you know what you want?"
                    break
                    } else {
                        Write-Error "You nothing want..."
                        break
                        }
    } catch {Write-Error $Error[0]; break}
    if((($EndDate -lt $GetDate) -and (!$Force)) -or (($Hour -eq 0) -and ($Minute -eq 0) -and ($Second -eq 0) -and (!$Force))){
        Write-Error "`n$('='*32)`n Date is in the past, use param Force`n$('='*32)`n"
        break
    } else {
        Write-Verbose "`n$('='*32)`n At $($EndDate.ToString()) will be run ScriptBlock:
        $ScriptBlock
        $('-'*32)`n"

        }
    $TotalSecond = ($EndDate.Ticks - $(Get-Date).Ticks)/10E6
    [int]$i = 0
    while($EndDate -gt $GetDate){
        $GetDate = $GetDate.AddSeconds(1)
        if($i%7 -eq 0){$GetDate = Get-Date}
        $SecondsRemaining = ($EndDate.Ticks - $GetDate.Ticks)/10E6
        $PercentComplete = [Math]::Round(($TotalSecond - $SecondsRemaining)/$TotalSecond*100)
        if($EndDate -le $GetDate){$PercentComplete = 100}
        if($SoundPlayEvery){
            if($i%$SoundPlayEvery -eq 0){
                if(!$SoundPlayBefore){
                    SoundPlay
                } elseif ($SoundPlayBefore -ge $SecondsRemaining){
                    SoundPlay
                } else {}
            }
        }
        if(!$NoProgressBarShow){Write-Progress -Activity "Sleep" -SecondsRemaining $SecondsRemaining -PercentComplete $PercentComplete}
        sleep 1
        $i++
    }
    Write-Verbose "`n$('-'*32)` Time: $((Get-Date).ToString()), Run! `n$('='*32)`n"
    Write-Host "`n"
    &$ScriptBlock
    Write-Verbose "`n$('-'*32)`n Was run at: $((Get-Date).ToString()) `n$('='*32)`n"