Add unattend.xml sections

This commit is contained in:
2Shirt 2025-12-13 16:58:47 -08:00
parent 4a306b56d9
commit 8495d62a06
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
3 changed files with 118 additions and 1 deletions

83
config/unattend.xml Executable file
View file

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="disabled">
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" language="neutral" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS">
<UserData>
<ProductKey>
<Key />
</ProductKey>
</UserData>
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<Path>reg add HKLM\SYSTEM\Setup\LabConfig /v BypassTPMCheck /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>2</Order>
<Path>reg add HKLM\SYSTEM\Setup\LabConfig /v BypassSecureBootCheck /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>3</Order>
<Path>reg add HKLM\SYSTEM\Setup\LabConfig /v BypassRAMCheck /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>
<settings pass="specialize">
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" language="neutral" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS">
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<Path>reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE /v BypassNRO /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" language="neutral" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS">
<OOBE>
<ProtectYourPC>3</ProtectYourPC>
</OOBE>
<UserAccounts>
<LocalAccounts>
<LocalAccount wcm:action="add">
<Name>NEWUSERNAME</Name>
<DisplayName>NEWUSERNAME</DisplayName>
<Group>Administrators;Power Users</Group>
<Password>
<Value>UABhAHMAcwB3AG8AcgBkAA==</Value>
<PlainText>false</PlainText>
</Password>
</LocalAccount>
</LocalAccounts>
</UserAccounts>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add">
<Order>1</Order>
<CommandLine>net user &quot;NEWUSERNAME&quot; /expires:never</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>2</Order>
<CommandLine>net user &quot;NEWUSERNAME&quot; /passwordchg:yes</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>3</Order>
<CommandLine>net user &quot;NEWUSERNAME&quot; /passwordreq:no</CommandLine>
</SynchronousCommand>
</FirstLogonCommands>
</component>
<component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" language="neutral" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS">
<InputLocale>00000409</InputLocale>
<SystemLocale>en-US</SystemLocale>
<UserLocale>en-US</UserLocale>
<UILanguage>en-US</UILanguage>
<UILanguageFallback></UILanguageFallback>
</component>
<component name="Microsoft-Windows-SecureStartup-FilterDriver" processorArchitecture="amd64" language="neutral" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS">
<PreventDeviceEncryption>true</PreventDeviceEncryption>
</component>
<component name="Microsoft-Windows-EnhancedStorage-Adm" processorArchitecture="amd64" language="neutral" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS">
<TCGSecurityActivationDisabled>1</TCGSecurityActivationDisabled>
</component>
</settings>
</unattend>

View file

@ -38,6 +38,8 @@ use core::{
};
use std::{
env,
fs::{File, create_dir_all},
io::Write,
iter::zip,
path::PathBuf,
sync::{Arc, Mutex},
@ -51,11 +53,12 @@ use ratatui::{
style::Color,
};
use tokio::sync::mpsc;
use tracing::{debug, info};
use tracing::{debug, error, info};
use crate::{
components::{set_username::InputUsername, wim_scan::WimScan},
state::{ScanType, State},
wim::gen_unattend_xml,
};
pub struct App {
@ -220,6 +223,8 @@ impl App {
popup::Type::Info,
String::from("Updating boot configuration"),
))?;
let wim_sources = self.state.wim_sources.lock().unwrap();
let wim_file = wim_sources.get_file(self.state.wim_file_index.unwrap());
// Get System32 path
let system32 = get_system32_path(&self.action_tx);
@ -270,6 +275,29 @@ impl App {
)))?;
}
}
// Add unattend.xml (if applicable)
if let Some(username) = &self.state.username
&& !wim_file.is_backup
{
let unattend_xml_str = gen_unattend_xml(username);
let panther_path = format!("{letter_os}:\\Windows\\Panther");
if create_dir_all(PathBuf::from(&panther_path)).is_ok() {
if let Ok(mut unattend_xml) =
File::create(format!("{panther_path}\\unattend.xml"))
{
if unattend_xml.write_all(unattend_xml_str.as_bytes()).is_ok() {
info!("Created unattend.xml with username set to: {username}");
} else {
error!("Failed to write to unattend.xml");
}
} else {
error!("Failed to create unattend.xml");
}
} else {
error!("Failed to create Panther dir");
}
}
}
}
Mode::ScanDisks => {

View file

@ -30,6 +30,8 @@ use xml::reader::{EventReader, XmlEvent};
use core::system::disk::bytes_to_string;
const UNATTEND_XML: &str = include_str!("../../config/unattend.xml");
static WIMINFO_EXE: LazyLock<String> = LazyLock::new(|| {
let program_files =
PathBuf::from(env::var("PROGRAMFILES").expect("Failed to resolve %PROGRAMFILES%"));
@ -229,6 +231,10 @@ impl WimSources {
}
}
pub fn gen_unattend_xml(username: &str) -> String {
UNATTEND_XML.replace("NEWUSERNAME", username)
}
fn get_wim_xml(wim_file: &str) -> std::io::Result<File> {
let tmp_file = NamedTempFile::new()?;
let _ = Command::new(&*WIMINFO_EXE)