DSCResources/TimezoneHelper.psm1
#region localizeddata if (Test-Path "${PSScriptRoot}\${PSUICulture}") { Import-LocalizedData ` -BindingVariable LocalizedData ` -Filename TimezoneHelper.psd1 ` -BaseDirectory "${PSScriptRoot}\${PSUICulture}" } else { #fallback to en-US Import-LocalizedData ` -BindingVariable LocalizedData ` -Filename TimezoneHelper.psd1 ` -BaseDirectory "${PSScriptRoot}\en-US" } #endregion <# .SYNOPSIS Internal function to throw terminating error with specified errroCategory, errorId and errorMessage #> function New-TerminatingError { [CmdletBinding()] param ( [Parameter(Mandatory)] [String] $ErrorId, [Parameter(Mandatory)] [String] $ErrorMessage, [Parameter(Mandatory)] [System.Management.Automation.ErrorCategory] $ErrorCategory ) $exception = New-Object System.InvalidOperationException $errorMessage $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null throw $errorRecord } # function New-TerminatingError <# .SYNOPSIS Get the of the current timezone Id. #> function Get-TimeZoneId { [CmdletBinding()] param() if (Test-Command -Name 'Get-Timezone' -Module 'Microsoft.PowerShell.Management') { Write-Verbose -Message ($LocalizedData.GettingTimezoneMessage -f 'Cmdlets') $Timezone = (Get-Timezone).StandardName } else { Write-Verbose -Message ($LocalizedData.GettingTimezoneMessage -f 'CIM') $TimeZone = (Get-CimInstance ` -ClassName WIN32_Timezone ` -Namespace root\cimv2).StandardName } Write-Verbose -Message ($LocalizedData.CurrentTimezoneMessage ` -f $Timezone) $timeZoneInfo = [System.TimeZoneInfo]::GetSystemTimeZones() | Where-Object StandardName -eq $TimeZone return $timeZoneInfo.Id } # function Get-TimeZoneId <# .SYNOPSIS Compare a timezone Id with the current timezone Id #> function Test-TimeZoneId { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [System.String] $TimeZoneId ) # Test Expected is same as Current $currentTimeZoneId = Get-TimeZoneId return $TimeZoneId -eq $currentTimeZoneId } # function Test-TimeZoneId <# .SYNOPSIS Sets the current timezone using a timezone Id #> function Set-TimeZoneId { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [System.String] $TimeZoneId ) if (Test-Command -Name 'Set-Timezone' -Module 'Microsoft.PowerShell.Management') { Set-Timezone -Id $TimezoneId } else { if (Test-Command -Name 'Add-Type' -Module 'Microsoft.Powershell.Utility') { # We can use Reflection to modify the TimeZone Write-Verbose -Message ($LocalizedData.SettingTimezoneMessage ` -f $TimeZoneId,'.NET') Set-TimeZoneUsingNET -TimezoneId $TimeZoneId } else { # For anything else use TZUTIL.EXE Write-Verbose -Message ($LocalizedData.SettingTimezoneMessage ` -f $TimeZoneId,'TZUTIL.EXE') try { & tzutil.exe @('/s',$TimeZoneId) } catch { $ErrorMsg = $_.Exception.Message Write-Verbose -Message $ErrorMsg } # try } # if } # if Write-Verbose -Message ($LocalizedData.TimezoneUpdatedMessage ` -f $TimeZone) } # function Set-TimeZoneId <# .SYNOPSIS This function exists so that the ::Set method can be mocked by Pester. #> function Set-TimeZoneUsingNET { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [System.String] $TimeZoneId ) # Add the [TimeZoneHelper.TimeZone] type if it is not defined. if (-not ([System.Management.Automation.PSTypeName]'TimeZoneHelper.TimeZone').Type) { Write-Verbose -Message ($LocalizedData.AddingSetTimeZonedotNetTypeMessage) $SetTimeZoneCs = Get-Content ` -Path (Join-Path -Path $PSScriptRoot -ChildPath 'SetTimeZone.cs') ` -Raw Add-Type ` -Language CSharp ` -TypeDefinition $SetTimeZoneCs } # if [Microsoft.PowerShell.xTimeZone.TimeZone]::Set($TimeZoneId) } # function Set-TimeZoneUsingNET <# .SYNOPSIS This function tests if a cmdlet exists. #> function Test-Command { [CmdletBinding()] [OutputType([boolean])] param( [Parameter(Mandatory = $true)] [System.String] $Name, [Parameter(Mandatory = $true)] [System.String] $Module ) return ($null -ne (Get-Command @PSBoundParameters -ErrorAction SilentlyContinue)) } # function Test-Command |