Public/Set-HDTBootImageTimeZone.ps1
|
function Set-HDTBootImageTimeZone { <# .SYNOPSIS Names the time zone WinPE runs in. .DESCRIPTION WinPE'S ANSWER FILE CANNOT SET THIS, and that is why the command exists. The windowsPE configuration pass carries Microsoft-Windows-International-Core-WinPE, which is InputLocale, SystemLocale, UILanguage and UserLocale - there is no TimeZone in it. Microsoft's TimeZone setting belongs to Microsoft-Windows-Shell-Setup and is valid only in specialize, oobeSystem and auditSystem, which are passes of the DEPLOYED OS. So a booted WinPE runs on whatever the hardware clock says, which is UTC in practice. tzutil IS THE SUPPORTED WAY TO MOVE IT, and startnet.cmd is where a command that has to run on every boot belongs. Named here, Get-HDTStartnetScript writes `tzutil /s "<id>"` after wpeinit. IT IS A WINDOWS TIME ZONE ID, not an offset: 'Israel Standard Time', not '+02:00'. Run Get-HDTTimeZone, or tzutil /l, for the list. The id is NOT validated here - this document is edited and validated on machines that are not the one deploying, and a time zone Windows added last month would be refused by an engine that shipped before it. WHAT IT DOES NOT DO IS SET THE DEPLOYED MACHINE'S TIME ZONE. That is HDTTimeZone, which the task sequence's unattend.xml carries into the specialize pass. Start-HDTDeployment seeds it from this value so one choice covers both, and a rule may override it per machine. IT IS SHAPED LIKE Set-HDTBootImageUnattend - one value, -Clear to take it away, the key removed rather than written empty. .PARAMETER Line The workspace.yaml lines to edit. .PARAMETER Name The Windows time zone id. .PARAMETER Clear Leave WinPE on the hardware clock, which is what it does today. .INPUTS None. This command does not accept pipeline input. .OUTPUTS System.String[] - the workspace.yaml lines, spliced. .EXAMPLE $line = Set-HDTBootImageTimeZone -Line $line -Name 'Israel Standard Time' .EXAMPLE Get-HDTTimeZone | Where-Object { $_.Display -like '*Jerusalem*' } Finding the id to pass. .LINK Get-HDTTimeZone #> [CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = 'Set')] [OutputType([string[]])] param( [Parameter(Mandatory = $true, Position = 0)] [AllowEmptyCollection()] [AllowEmptyString()] [string[]] $Line, [Parameter(Mandatory = $true, Position = 1, ParameterSetName = 'Set')] [AllowEmptyString()] [string] $Name, [Parameter(Mandatory = $true, ParameterSetName = 'Clear')] [switch] $Clear ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' [void] (ConvertFrom-HDTWorkspaceLine -Line $Line) if ($Clear) { if (-not $PSCmdlet.ShouldProcess('bootImage: timeZone', 'Leave WinPE on the hardware clock')) { return [string[]] @($Line) } $result = [string[]] @(Set-HDTWorkspaceKey -Line $Line -Path @('bootImage', 'timeZone') ` -Text ([string[]] @())) } else { if ([string]::IsNullOrWhiteSpace($Name)) { $PSCmdlet.ThrowTerminatingError((New-HDTErrorRecord -TargetObject $Name ` -Message 'a time zone is a Windows time zone id, for example ''Israel Standard Time''. Pass -Clear to leave WinPE on the hardware clock; run Get-HDTTimeZone for the ids.')) } if (-not $PSCmdlet.ShouldProcess($Name, 'Run WinPE in this time zone')) { return [string[]] @($Line) } $result = [string[]] @(Set-HDTWorkspaceKey -Line $Line -Path @('bootImage', 'timeZone') ` -Text ([string[]] @('timeZone: {0}' -f (ConvertTo-HDTRuleScalarText -Value $Name)))) } try { [void] (ConvertFrom-HDTWorkspaceLine -Line $result) } catch { $PSCmdlet.ThrowTerminatingError($_) } return [string[]] $result } |