From f86fe05e0f939ba1320dd138b19d3d6b21cbd24f Mon Sep 17 00:00:00 2001 From: GMIKE Date: Fri, 14 Mar 2025 23:45:10 +0000 Subject: [PATCH 1/4] Support AdministratorPassword #39 --- .../AnswerFileGeneratorTests.cs | 13 +++++++++++++ src/Ookii.AnswerFile/AnswerFileGenerator.cs | 10 +++++++++- src/Ookii.AnswerFile/AnswerFileOptions.cs | 19 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/Ookii.AnswerFile.Tests/AnswerFileGeneratorTests.cs b/src/Ookii.AnswerFile.Tests/AnswerFileGeneratorTests.cs index dda8871..e276981 100644 --- a/src/Ookii.AnswerFile.Tests/AnswerFileGeneratorTests.cs +++ b/src/Ookii.AnswerFile.Tests/AnswerFileGeneratorTests.cs @@ -238,4 +238,17 @@ public void TestGenerateDomainOnly() AnswerFileGenerator.Generate(actualPath, options); CheckFilesEqual(expectedPath, actualPath); } + + [TestMethod] + public void TestGenerateAdministratorPassword() + { + var (actualPath, expectedPath) = GetPaths(); + var options = new AnswerFileOptions + { + AdministratorPassword = "Password123" + }; + + AnswerFileGenerator.Generate(actualPath, options); + CheckFilesEqual(expectedPath, actualPath); + } } diff --git a/src/Ookii.AnswerFile/AnswerFileGenerator.cs b/src/Ookii.AnswerFile/AnswerFileGenerator.cs index cb2e535..5db7365 100644 --- a/src/Ookii.AnswerFile/AnswerFileGenerator.cs +++ b/src/Ookii.AnswerFile/AnswerFileGenerator.cs @@ -207,7 +207,7 @@ private void GenerateOobePass() using var pass = WritePassStart("oobeSystem"); WriteInternationalCore(); using var shellSetup = WriteComponentStart("Microsoft-Windows-Shell-Setup"); - if (Options.LocalAccounts.Count > 0 || (Options.JoinDomain?.DomainAccounts.Count > 0)) + if (Options.LocalAccounts.Count > 0 || (Options.JoinDomain?.DomainAccounts.Count > 0) || (Options.AdministratorPassword != null)) { using var userAccounts = Writer.WriteAutoCloseElement("UserAccounts"); if (Options.LocalAccounts.Count > 0) @@ -280,6 +280,14 @@ private void GenerateOobePass() Writer.WriteEndElement(); // DomainAccountList } } + + if (Options.AdministratorPassword != null) + { + Writer.WriteStartElement("AdministratorPassword"); + Writer.WriteElementString("Value", Convert.ToBase64String(Encoding.Unicode.GetBytes(Options.AdministratorPassword))); + Writer.WriteElementString("PlainText", "false"); + Writer.WriteEndElement(); + } } bool hideAccountScreens = Options.JoinDomain != null || Options.LocalAccounts.Count != 0; diff --git a/src/Ookii.AnswerFile/AnswerFileOptions.cs b/src/Ookii.AnswerFile/AnswerFileOptions.cs index 7b7ebd6..5069b64 100644 --- a/src/Ookii.AnswerFile/AnswerFileOptions.cs +++ b/src/Ookii.AnswerFile/AnswerFileOptions.cs @@ -167,6 +167,25 @@ public Collection LocalAccounts get => _localAccounts ??= new(); set => _localAccounts = value; } + + /// + /// Gets or sets the administrator password for the system. + /// + /// + /// The password for the administrator account, or if no password is to be set. + /// The default value is . + /// + /// + /// + /// This password will be applied to the default administrator account during the Windows setup. + /// + /// + /// The password is stored using base64 encoding in the answer file; it is not encrypted. + /// Ensure that answer files containing sensitive information are stored securely and are + /// not exposed to unauthorized parties. + /// + /// + public string? AdministratorPassword { get; set; } /// /// Gets or sets options for logging on automatically. From 7bbe31bc1413ed3f5dbfb00f04bada558fe0ecab Mon Sep 17 00:00:00 2001 From: GMIKE Date: Fri, 14 Mar 2025 23:53:51 +0000 Subject: [PATCH 2/4] Create TestGenerateAdministratorPassword.xml --- .../TestGenerateAdministratorPassword.xml | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/Ookii.AnswerFile.Tests/expected/TestGenerateAdministratorPassword.xml diff --git a/src/Ookii.AnswerFile.Tests/expected/TestGenerateAdministratorPassword.xml b/src/Ookii.AnswerFile.Tests/expected/TestGenerateAdministratorPassword.xml new file mode 100644 index 0000000..a713477 --- /dev/null +++ b/src/Ookii.AnswerFile.Tests/expected/TestGenerateAdministratorPassword.xml @@ -0,0 +1,37 @@ + + + + + en-US + en-US + en-US + en-US + + + + + en-US + en-US + en-US + en-US + + + + + UABhAHMAcwB3AG8AcgBkADEAMgAzAA== + false</PlainText> + </AdministratorPassword> + </UserAccounts> + <OOBE> + <ProtectYourPC>1</ProtectYourPC> + <HideEULAPage>true</HideEULAPage> + <HideLocalAccountScreen>false</HideLocalAccountScreen> + <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> + <HideOnlineAccountScreens>false</HideOnlineAccountScreens> + <HideWirelessSetupInOOBE>false</HideWirelessSetupInOOBE> + </OOBE> + <TimeZone>Pacific Standard Time</TimeZone> + <FirstLogonCommands /> + </component> + </settings> +</unattend> \ No newline at end of file From 977434f0b138a0af5b65c6c6832334bf0477f6f0 Mon Sep 17 00:00:00 2001 From: GMIKE <roman.soloweow333@ya.ru> Date: Fri, 14 Mar 2025 23:57:49 +0000 Subject: [PATCH 3/4] Use "Password" salt --- .../expected/TestGenerateAdministratorPassword.xml | 2 +- src/Ookii.AnswerFile/AnswerFileGenerator.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ookii.AnswerFile.Tests/expected/TestGenerateAdministratorPassword.xml b/src/Ookii.AnswerFile.Tests/expected/TestGenerateAdministratorPassword.xml index a713477..4d097e6 100644 --- a/src/Ookii.AnswerFile.Tests/expected/TestGenerateAdministratorPassword.xml +++ b/src/Ookii.AnswerFile.Tests/expected/TestGenerateAdministratorPassword.xml @@ -18,7 +18,7 @@ <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> <UserAccounts> <AdministratorPassword> - <Value>UABhAHMAcwB3AG8AcgBkADEAMgAzAA==</Value> + <Value>UABhAHMAcwB3AG8AcgBkADEAMgAzAFAAYQBzAHMAdwBvAHIAZAA=</Value> <PlainText>false</PlainText> </AdministratorPassword> </UserAccounts> diff --git a/src/Ookii.AnswerFile/AnswerFileGenerator.cs b/src/Ookii.AnswerFile/AnswerFileGenerator.cs index 5db7365..c0c98d9 100644 --- a/src/Ookii.AnswerFile/AnswerFileGenerator.cs +++ b/src/Ookii.AnswerFile/AnswerFileGenerator.cs @@ -284,7 +284,7 @@ private void GenerateOobePass() if (Options.AdministratorPassword != null) { Writer.WriteStartElement("AdministratorPassword"); - Writer.WriteElementString("Value", Convert.ToBase64String(Encoding.Unicode.GetBytes(Options.AdministratorPassword))); + Writer.WriteElementString("Value", Convert.ToBase64String(Encoding.Unicode.GetBytes(Options.AdministratorPassword + "Password"))); Writer.WriteElementString("PlainText", "false"); Writer.WriteEndElement(); } From a3316ca2b93723bfbcf7f65d21bd0e479d20e83f Mon Sep 17 00:00:00 2001 From: GMIKE <roman.soloweow333@ya.ru> Date: Mon, 17 Mar 2025 08:54:57 +0000 Subject: [PATCH 4/4] Update Ookii.AnswerFile.Tests.csproj Copy TestGenerateAdministratorPassword to output --- src/Ookii.AnswerFile.Tests/Ookii.AnswerFile.Tests.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Ookii.AnswerFile.Tests/Ookii.AnswerFile.Tests.csproj b/src/Ookii.AnswerFile.Tests/Ookii.AnswerFile.Tests.csproj index 7579362..c50e758 100644 --- a/src/Ookii.AnswerFile.Tests/Ookii.AnswerFile.Tests.csproj +++ b/src/Ookii.AnswerFile.Tests/Ookii.AnswerFile.Tests.csproj @@ -57,6 +57,9 @@ <Content Include="expected\TestGeneratePreInstalled.xml"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="expected\TestGenerateAdministratorPassword.xml"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> <Content Include="expected\TestJsonSerializationBios.json"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content>