TimeZones.psm1

<#
.SYNOPSIS
    A Module to get the time in a Time Zone or get the Local Time from the time in a Time Zone
.DESCRIPTION
    A Module to get the time in a Time Zone or get the Local Time from the time in a Time Zone
.NOTES
    Authors : Simon Godefroy - Simon.Godefroy@FocusedIT.co.uk
    Version : 1.0.3
    Date : 2022.07.19
        Update : 1.0.3
                    SG - 2022.07.19
                    Fixed Mutlichoice output
        Update : 1.0.2
                    SG - 2022.05.02
                    Removed unrequired Write-Host on load
        Update : 1.0.1
                    SG - 2022.05.02
                    Updated after running Script Analyser. Moved TZMultiChoice out of both functions
        Update : 1.0.0
                    SG - 2021.10.12
                    Initial Script
.LINK
    http://www.FocusedIT.co.uk
#>


Function TZMultiChoice {
            param(
                $InputObject
            )
            begin{
                $Items = @()
            }
            process{
                $Items += $InputObject
            }
            end{
                $InputCount = $Items.count
                $Max = $InputCount -1
                $i = 0
                while($i -le $Max){
                    $Current = ($Items[$i]).Id
                    Write-Host "$i $Current "
                    $i ++
                }
                $Choice = Read-Host "Enter Selection Number"
                if($Choice -match "\d{1}"){
                    $Result = $Items[$Choice]
                }else{
                    $Search = $Items | Where-Object{$_ -match $Choice}
                    if($Search.count -eq 1){
                        $Result = $Search
                    }else{
                        Write-Warning "Please be more specific.."
                    }
                }
                return $Result
            }
        }

function Get-TimeZoneTime{
    <#
        .SYNOPSIS
            Returns Time Difference and Time for a specific Time Zone
        .DESCRIPTION
            Returns Time Difference and Time for a specific Time Zone
        .EXAMPLE
            Get-TimeZoneTime -TimeZone "Eastern Standard Time"
        .NOTES
            Returns Time Difference and Time for a specific Time Zone
    #>

    [cmdletbinding()]
    param (
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$True)]
        [String]$TimeZone ,
        [Parameter(ValueFromPipelineByPropertyName=$True,ValueFromPipeline=$True)]
        [alias("LocalTime")]
        [datetime]$DateTime ,
        [Parameter(HelpMessage="Time Format: hh:mm")]
        [ValidateScript({[DateTime]::ParseExact($_,"HH:mm",$null)})]
        [string]$Time #,

    )

    begin{

        #Get Time Zones
        $timezones = Get-TimeZone -ListAvailable

        if(!($DateTime)){
            if($Time){
                $DateTime = (Get-Date $Time)
            }else{
                $DateTime = (Get-Date)
            }
        }

        #$UTCDateTime = ($DateTime).ToUniversalTime()

        $SelectedTZ = @()
        $TZItems = @()
    }
    process{
        $FoundTZ = $timezones |Where-Object{$_.Id -eq $TimeZone}
        if($FoundTZ.count -eq 0){
            $Characters = $TimeZone.ToCharArray()
            $TZABV = $null
            foreach($C in $Characters){
                [string]$TZABV += $C + "* "
            }
            $TZABV = $TZABV.Trim(" ")
            $FoundTZ = $timezones |Where-Object{$_.Id -like $TZABV}
        }
        if($FoundTZ.count -eq 0){
            $TZSearch = "*" + $TimeZone + "*"
            $FoundTZ = $timezones |Where-Object{$_.Id -like $TZSearch}
        }
        $TZItems += $FoundTZ
    }
    end{
        if(!($FoundTZ)){
            Write-Warning "No Time Zone found"
            return
        }

        if($FoundTZ.count -eq 1){
            $SelectedTZ += $FoundTZ
        }else{
            $SelectedTZ += TZMultiChoice $FoundTZ 
        }

        $TimeDiff = ((Get-TimeZone -Id $SelectedTZ.Id) | Select-Object Base*).BaseUtcOffset
        $TZFinalTime = (Get-Date $DateTime).Add($TimeDiff)
        $Object = [pscustomobject]@{
            TimeZone = $SelectedTZ.Id
            DisplayName = $SelectedTZ.DisplayName
            BaseUtcOffset = $SelectedTZ.BaseUtcOffset
            LocalTime = $DateTime
            TZTime = $TZFinalTime
        }
        $Object
    }
}

function Get-LocalTimeFromTimeZone{
        <#
        .SYNOPSIS
            Returns Local Time for a specific Time and Time Zone
        .DESCRIPTION
            Returns Local Time for a specific Time and Time Zone
        .EXAMPLE
            Get-LocalTimeFromTimeZone -Time 10:00 -TimeZone "Eastern Standard Time"
        .NOTES
            Returns Local Time for a specific Time and Time Zone
    #>

    [cmdletbinding()]
    param (
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$True)]
        [String]$TimeZone ,
        [Parameter(ValueFromPipelineByPropertyName=$True,ValueFromPipeline=$True)]
        [alias("TZTime")]
        [datetime]$DateTime ,
        [Parameter(HelpMessage="Time Format: hh:mm")]
        [ValidateScript({[DateTime]::ParseExact($_,"HH:mm",$null)})]
        [string]$Time #,

    )
    begin{

        $SelectedTZ = @()

    }
    process{
        if(!($Time)){
            if($DateTime){
                $Time = $DateTime.ToString("HH:mm")
            }else{
                [datetime]$TimeDT = (Read-Host "Enter Time (HH:MM)")
                $Time = $TimeDT.ToString("HH:mm")
            }
        }

        #Get Time Zones
        $timezones = Get-TimeZone -ListAvailable

        if(!($DateTime)){
            if($Time){
                $DateTime = (Get-Date $Time)
            }else{

                $DateTime = (Get-Date $Time)
            }
        }
        #$UTCDateTime = ($DateTime).ToUniversalTime()

        $FoundTZ = $timezones |Where-Object{$_.Id -eq $TimeZone}
        if($FoundTZ.count -eq 0){
            $Characters = $TimeZone.ToCharArray()
            $TZABV = $null
            foreach($C in $Characters){
                [string]$TZABV += $C + "* "
            }
            $TZABV = $TZABV.Trim(" ")
            $FoundTZ = $timezones |Where-Object{$_.Id -like $TZABV}
        }
        if($FoundTZ.count -eq 0){
            $TZSearch = "*" + $TimeZone + "*"
            $FoundTZ = $timezones |Where-Object{$_.Id -like $TZSearch}
        }
        $TZItems += $FoundTZ
    }
    end{
        if(!($FoundTZ)){
            Write-Warning "No Time Zone found"
            return
        }

        if($FoundTZ.count -eq 1){
            $SelectedTZ += $FoundTZ
        }else{
            $SelectedTZ += TZMultiChoice $FoundTZ 
        }
        $TimeDiff = ((Get-TimeZone -Id $SelectedTZ.Id) | Select-Object Base*).BaseUtcOffset
        $LocalFinalTime = (Get-Date $DateTime).Add(-$TimeDiff)
        $Object = [pscustomobject]@{
                TimeZone = $SelectedTZ.Id
                DisplayName = $SelectedTZ.DisplayName
                BaseUtcOffset = $SelectedTZ.BaseUtcOffset
                TZTime = $DateTime
                LocalTime = $LocalFinalTime
            }
            $Object
        #LocalTime
    }

}