Templates/Wizard/ComputerDetail.xaml
|
<!--
A PREVIEW PAGE, NOT A PRODUCT ONE. See HDTPreviewTaskSequence.xaml. MDT'S "COMPUTER DETAILS" PANE, and the shape is deliberate: an MDT admin knows this screen. The name and the domain-or-workgroup choice sit together because they are one decision about a machine's identity, and MDT has carried them together since LiteTouch. TWO HALVES, TWO SKIP KEYS. HDTSkipComputerName hides the top half and HDTSkipDomainMembership the bottom - MDT has both properties for this one pane, and the pane mechanism the host already has (Get-HDTWizardSkip returns visibility by control name) is what collapses either. THE RADIO DECIDES DECLARATIVELY. There is no code-behind in WinPE, so which boxes are enabled follows the radio through a DataTrigger, exactly as HDTTheme.xaml's address boxes follow the DHCP/static radio. --> <Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <!-- ============ the name ============ --> <StackPanel Grid.Row="0" x:Name="HDTComputerNamePane"> <TextBlock Text="Computer name" Foreground="#FFCCCCCC" FontSize="14" Margin="0,0,0,8" /> <!-- IT SETS NO FONT, NO PADDING AND NO COLOUR. HDTTheme.xaml's TextBox style sets Height="32" with FontSize="15", and a LOCAL VALUE BEATS A STYLE SETTER - so a page that set its own font and padding grew the text inside a box that stayed 32px tall and clipped the bottom three pixels. The underscore lives entirely in those three pixels, so the box appeared to be dropping the character rather than cutting the bottom off it. --> <TextBox x:Name="HDTComputerNameBox" Text="" MaxLength="15" Width="380" HorizontalAlignment="Left" /> <!-- ONE LINE, NOT A PANEL. This page carried a three-row box explaining the length limit, the ten forbidden characters and the DNS warning - and it pushed the workgroup option off the bottom of the window, which is the choice most machines take. A screen that explains a rule at the cost of hiding a control has the trade backwards. THE RULES STILL REACH THE TECHNICIAN, LATER AND ONLY WHEN THEY MATTER: an illegal character cannot be typed at all, and a name that is too long or not DNS-safe puts the reason on the message line at the bottom of the shell, in red or amber. That is the moment the explanation is worth reading. Before then it is a wall of text between a technician and a text box. --> <TextBlock Foreground="#FF8A8A8A" FontSize="12" TextWrapping="Wrap" MaxWidth="560" HorizontalAlignment="Left" Margin="0,8,0,0" Text="1 to 15 characters. Letters, digits and hyphens are safest - anything else is allowed but is not a valid DNS name. These cannot be typed: . \ / : * ? " < > | or spaces." /> </StackPanel> <!-- ============ the domain or the workgroup ============ --> <StackPanel Grid.Row="1" x:Name="HDTDomainPane" Margin="0,24,0,0"> <TextBlock Text="Join a domain or a workgroup" Foreground="#FFCCCCCC" FontSize="14" Margin="0,0,0,10" /> <RadioButton x:Name="HDTJoinDomainRadio" GroupName="HDTMembership" Content="Join a domain" /> <!-- THE DISTINCTION THAT COSTS PEOPLE AN AFTERNOON, SAID ON THE SCREEN. "Domain to join" is where the MACHINE goes; the account below is WHO puts it there, and it frequently lives somewhere else. --> <TextBlock Text="The machine joins the domain below. The account is who creates its computer object - often from a different domain, and never the account that reaches the deployment share." Foreground="#FF8A8A8A" FontSize="12" TextWrapping="Wrap" MaxWidth="520" HorizontalAlignment="Left" Margin="24,6,0,0" /> <Grid Margin="24,10,0,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="120" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Text="Domain to join" Foreground="#FF8A8A8A" FontSize="13" VerticalAlignment="Center" Margin="0,0,0,8" ToolTip="The domain THIS MACHINE joins - for example corp.contoso.com." /> <TextBox Grid.Row="0" Grid.Column="1" x:Name="HDTJoinDomainBox" Width="380" HorizontalAlignment="Left" Margin="0,0,0,8"> <TextBox.Style> <Style TargetType="TextBox"> <Setter Property="IsEnabled" Value="False" /> <Style.Triggers> <DataTrigger Binding="{Binding IsChecked, ElementName=HDTJoinDomainRadio}" Value="True"> <Setter Property="IsEnabled" Value="True" /> </DataTrigger> </Style.Triggers> </Style> </TextBox.Style> </TextBox> <!-- THE OU IS OPTIONAL AND SAYS SO. Left empty, the machine account lands in the domain's default container - which is a decision somebody made once and nobody remembers, so it is worth stating on the screen rather than in a document. --> <TextBlock Grid.Row="1" Grid.Column="0" Text="OU (optional)" Foreground="#FF8A8A8A" FontSize="13" VerticalAlignment="Center" Margin="0,0,0,8" /> <TextBox Grid.Row="1" Grid.Column="1" x:Name="HDTMachineObjectOuBox" Width="380" HorizontalAlignment="Left" Margin="0,0,0,8"> <TextBox.Style> <Style TargetType="TextBox"> <Setter Property="IsEnabled" Value="False" /> <Style.Triggers> <DataTrigger Binding="{Binding IsChecked, ElementName=HDTJoinDomainRadio}" Value="True"> <Setter Property="IsEnabled" Value="True" /> </DataTrigger> </Style.Triggers> </Style> </TextBox.Style> </TextBox> <!-- THE ACCOUNT THAT PERFORMS THE JOIN. MDT's DomainAdmin, DomainAdminDomain and DomainAdminPassword; HDT already carries all three in Get-HDTVariableMap. Nothing can join a domain without them, so a page that asked for a domain and not for these would collect an answer that cannot be acted on. IT IS NOT THE SHARE ACCOUNT. The Welcome screen's credential reaches the deployment share; this one has rights in the directory. They are frequently different accounts, and conflating them is how a deployment reaches its content and then cannot join. --> <!-- ONE BOX, TYPED THE WAY WINDOWS PROMPTS FOR IT. This was two - the account and the domain it lives in - because that is how MDT's variables are shaped. A technician joining a domain does not think in two boxes; they think CORP\svc-hdt-join. MDT KEEPS A SEPARATE DOMAIN BOX AND SO DOES THIS PAGE - it is the pane an MDT admin already knows, and this file follows it. What the split adds is that BOTH WAYS OF SAYING IT WORK: type CORP\svc-hdt-join and leave the box empty, or type svc-hdt-join and fill the box, and HDTDomainAdmin and HDTDomainAdminDomain come out the same either way. PRECEDENCE, MOST SPECIFIC FIRST: a DOMAIN\ prefix wins over the box, the box wins over the domain being joined. The first of those follows the rule Get-HDTWizardCredential already set - "a UserID that already carries a domain is left alone" - so 'CORP\svc' never becomes 'CORP\CORP\svc'. --> <TextBlock Grid.Row="2" Grid.Column="0" Text="Join account" Foreground="#FF8A8A8A" FontSize="13" VerticalAlignment="Center" Margin="0,0,0,8" ToolTip="The user with rights to create the computer object. NOT the account that reaches the deployment share." /> <TextBox Grid.Row="2" Grid.Column="1" x:Name="HDTDomainAdminBox" Width="380" HorizontalAlignment="Left" Margin="0,0,0,8" ToolTip="CORP\svc-hdt-join, or svc-hdt-join@corp.contoso.com. A bare name means an account in the domain being joined."> <TextBox.Style> <Style TargetType="TextBox"> <Setter Property="IsEnabled" Value="False" /> <Style.Triggers> <DataTrigger Binding="{Binding IsChecked, ElementName=HDTJoinDomainRadio}" Value="True"> <Setter Property="IsEnabled" Value="True" /> </DataTrigger> </Style.Triggers> </Style> </TextBox.Style> </TextBox> <!-- HDTPasswordBox / HDTPasswordRevealBox / HDTPasswordRevealToggle ARE THE NAMES THE HOST ALREADY WIRES. PasswordBox.Password is not a DependencyProperty - it cannot be bound, styled or DataTriggered, and there is no code-behind to reveal it - so the markup carries two boxes in one cell and New-HDTWizardHost swaps which is visible, copying the text across. Using the names it looks for is what gets the eye for nothing. THE PASSWORD NEVER REACHES THE SUMMARY. Its Collect declaration is marked IsSecret, so the summary row reads "(set, not shown)" and the rules.yaml snippet names it in a comment and writes no value - a screen somebody photographs and a file on a share are both worse places for it than a log, and the variable map already says it is never written to one. --> <TextBlock Grid.Row="3" Grid.Column="0" Text="Password" Foreground="#FF8A8A8A" FontSize="13" VerticalAlignment="Center" Margin="0,0,0,8" /> <Grid Grid.Row="3" Grid.Column="1" Margin="0,0,0,8"> <Grid.ColumnDefinitions> <ColumnDefinition Width="380" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <PasswordBox Grid.Column="0" x:Name="HDTPasswordBox" HorizontalAlignment="Left" Width="380"> <PasswordBox.Style> <Style TargetType="PasswordBox"> <Setter Property="IsEnabled" Value="False" /> <Style.Triggers> <DataTrigger Binding="{Binding IsChecked, ElementName=HDTJoinDomainRadio}" Value="True"> <Setter Property="IsEnabled" Value="True" /> </DataTrigger> </Style.Triggers> </Style> </PasswordBox.Style> </PasswordBox> <TextBox Grid.Column="0" x:Name="HDTPasswordRevealBox" Width="380" HorizontalAlignment="Left" Visibility="Collapsed" /> <ToggleButton Grid.Column="1" x:Name="HDTPasswordRevealToggle" Content="👁" Width="36" Height="32" Margin="8,0,0,0" Background="#FF3A3A3C" Foreground="White" BorderThickness="0" ToolTip="Show the password" /> </Grid> <!-- THE ACCOUNT'S OWN DOMAIN, WHERE MDT PUTS IT - under the password, and labelled just "Domain" there. It is labelled "Account's domain" here because the pane already has a "Domain to join" four rows up and two boxes called Domain on one screen is how the wrong one gets filled in. OPTIONAL, AND THE HINT SAYS WHAT HAPPENS WHEN IT IS EMPTY. A required-looking box that can be left blank is a box a technician fills in with a guess. --> <TextBlock Grid.Row="4" Grid.Column="0" Text="Account's domain" Foreground="#FF8A8A8A" FontSize="13" VerticalAlignment="Center" ToolTip="Where the join account lives. Leave empty and the domain being joined is used." /> <StackPanel Grid.Row="4" Grid.Column="1"> <TextBox x:Name="HDTDomainAdminDomainBox" Width="380" HorizontalAlignment="Left" ToolTip="For example CORP. Leave empty to use the domain being joined, or type CORP\svc-hdt-join in the account box instead."> <TextBox.Style> <Style TargetType="TextBox"> <Setter Property="IsEnabled" Value="False" /> <Style.Triggers> <DataTrigger Binding="{Binding IsChecked, ElementName=HDTJoinDomainRadio}" Value="True"> <Setter Property="IsEnabled" Value="True" /> </DataTrigger> </Style.Triggers> </Style> </TextBox.Style> </TextBox> <TextBlock Text="Empty means the domain being joined. A DOMAIN\user in the account box wins over this." Foreground="#FF8A8A8A" FontSize="12" TextWrapping="Wrap" MaxWidth="380" HorizontalAlignment="Left" Margin="0,6,0,0" /> </StackPanel> </Grid> <RadioButton x:Name="HDTJoinWorkgroupRadio" GroupName="HDTMembership" Content="Join a workgroup" IsChecked="True" Margin="0,16,0,0" /> <Grid Margin="24,10,0,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="120" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <TextBlock Grid.Column="0" Text="Workgroup" Foreground="#FF8A8A8A" FontSize="13" VerticalAlignment="Center" /> <TextBox Grid.Column="1" x:Name="HDTJoinWorkgroupBox" Text="WORKGROUP" MaxLength="15" Width="380" HorizontalAlignment="Left"> <TextBox.Style> <Style TargetType="TextBox"> <Setter Property="IsEnabled" Value="False" /> <Style.Triggers> <DataTrigger Binding="{Binding IsChecked, ElementName=HDTJoinWorkgroupRadio}" Value="True"> <Setter Property="IsEnabled" Value="True" /> </DataTrigger> </Style.Triggers> </Style> </TextBox.Style> </TextBox> </Grid> </StackPanel> <!-- THE THIRD ROW IS DELIBERATELY EMPTY. It used to hold a panel explaining what a computer name may contain - three rows, a heading and a border - and it pushed "Join a workgroup" off the bottom of the window, which is the option most machines take. A SCREEN THAT EXPLAINS A RULE AT THE COST OF HIDING A CONTROL HAS THE TRADE BACKWARDS. The rules did not go anywhere: an illegal character cannot be typed at all, a name that is too long or not DNS-safe puts the reason on the shell's message line in red or amber, and the one-line hint under the name box says the rest. Each of those arrives at the moment it is worth reading, rather than as a wall of text between a technician and a text box. The row stays in the layout so the panes above it keep their spacing when the window is taller than they are. --> </Grid> |