From 0d7006372843c1ca1852ce9f2b466688c5c7c015 Mon Sep 17 00:00:00 2001 From: Nadja Heitmann Date: Tue, 27 Apr 2021 10:21:52 +0200 Subject: [PATCH] Fixes #36495 - Extend Windows templates for Puppet and Ansible Co-authored-by: Fabrice Brimioulle Co-authored-by: Ewoud Kohl van Wijngaarden --- .../foreman/template_snapshot_service.rb | 12 ++ .../finish/windows_default_finish.erb | 193 +++++++++--------- .../windows_default_provisioning.erb | 56 +++-- .../script/windows_default_script.erb | 50 +++-- ...orking_snippet.erb => windows_network.erb} | 53 ++--- .../user_data/windows_default_user_data.erb | 6 +- test/factories/host_related.rb | 10 + test/factories/medium.rb | 5 + test/factories/operatingsystem.rb | 11 + test/unit/foreman/renderer/snapshots.yaml | 4 + ...ows_default_finish.windows10_dhcp.snap.txt | 77 +++++++ ..._default_provision.windows10_dhcp.snap.txt | 102 +++++++++ ...indows_peSetup.cmd.windows10_dhcp.snap.txt | 104 ++++++++++ .../windows_network.windows10_dhcp.snap.txt | 27 +++ 14 files changed, 559 insertions(+), 151 deletions(-) rename app/views/unattended/provisioning_templates/snippet/{windows_networking_snippet.erb => windows_network.erb} (69%) create mode 100644 test/unit/foreman/renderer/snapshots/ProvisioningTemplate/finish/Windows_default_finish.windows10_dhcp.snap.txt create mode 100644 test/unit/foreman/renderer/snapshots/ProvisioningTemplate/provision/Windows_default_provision.windows10_dhcp.snap.txt create mode 100644 test/unit/foreman/renderer/snapshots/ProvisioningTemplate/script/Windows_peSetup.cmd.windows10_dhcp.snap.txt create mode 100644 test/unit/foreman/renderer/snapshots/ProvisioningTemplate/snippet/windows_network.windows10_dhcp.snap.txt diff --git a/app/services/foreman/template_snapshot_service.rb b/app/services/foreman/template_snapshot_service.rb index c7e45b97ab6..01ac0e9b3a5 100644 --- a/app/services/foreman/template_snapshot_service.rb +++ b/app/services/foreman/template_snapshot_service.rb @@ -50,6 +50,10 @@ def self.rocky9_dhcp new.rocky9_dhcp end + def self.windows10_dhcp + new.windows10_dhcp + end + def self.render_template(template, host_name = :host4dhcp) host_stub = send(host_name.to_sym) source = Foreman::Renderer::Source::Snapshot.new(template) @@ -205,6 +209,14 @@ def rocky9_dhcp define_host_params(host) end + def windows10_dhcp + host = FactoryBot.build(:host_for_snapshots_ipv4_dhcp_windows10, + name: 'snapshot-ipv4-dhcp-windows10', + subnet: FactoryBot.build(:subnet_ipv4_dhcp_for_snapshots), + interfaces: [ipv4_interface]) + define_host_params(host) + end + private def files diff --git a/app/views/unattended/provisioning_templates/finish/windows_default_finish.erb b/app/views/unattended/provisioning_templates/finish/windows_default_finish.erb index 18b7f39dd45..34b9b98d68d 100644 --- a/app/views/unattended/provisioning_templates/finish/windows_default_finish.erb +++ b/app/views/unattended/provisioning_templates/finish/windows_default_finish.erb @@ -8,6 +8,8 @@ oses: - Windows Server 2012 - Windows Server 2012 R2 - Windows +test_on: +- windows10_dhcp description: | A finish template executed at the end of Windows provisioning. For more information, please see https://community.theforeman.org/t/windows-provisioning-made-easy/16756 @@ -31,102 +33,107 @@ description: | <% # safemode renderer does not support unary negation puppet_enabled = !host_param_true?('skip-puppet-setup') && (host_puppet_server.present? || host_param_true?('force-puppet')) - salt_enabled = host_param('salt_master') ? true : false + salt_enabled = host_param('salt_master').present? chef_enabled = @host.respond_to?(:chef_proxy) && @host.chef_proxy + network_location = host_param('networklocation', 'Private') %> @echo off <% unless host_param('localAdminAccountDisabled') -%> - echo Activating administrator - net user administrator /active:yes -<% end -%> - -<% if @host.pxe_build? %> - set ctr=0 - set nettimeout=10 - - (echo Updating time) - (sc config w32time start= auto) - sc start w32time - ::ipconfig /renew - - <% if host_param('ntpServer') %> - echo setting time server - w32tm /config /manualpeerlist:<%= host_param('ntpServer') %> /syncfromflags:manual /update - <% end %> - - echo sync time - w32tm /resync - w32tm /resync - - <% if host_param('computerDomain') -%> - <% if host_param('domainAdminAccount').present? && host_param('domainAdminAccountPasswd').present? -%> - echo performing secure domain join - powershell.exe -OutputFormat text -command Add-Computer -DomainName '<%= host_param('computerDomain') -%>' -Credential (New-Object -TypeName System.Management.Automation.PSCredential '<%= host_param('domainAdminAccount') -%>', (ConvertTo-SecureString -String '<%= host_param('domainAdminAccountPasswd') -%>' -AsPlainText -Force)) <% if host_param('computerOU').present? -%>-OUPath '<%= host_param('computerOU') -%>'<% end -%> - <% else %> - <% if host_param('machinePassword').present? %> - echo performing unsecure domain join - powershell.exe -OutputFormat text -command Add-Computer -Domain '<%= host_param('computerDomain') -%>' -Options UnsecuredJoin,PasswordPass -Credential (New-Object -TypeName System.Management.Automation.PSCredential $null, (ConvertTo-SecureString -String '<%= host_param('machinePassword') -%>' -AsPlainText -Force)) - <% end %> - <% end %> - <% end %> - - <% if host_param('localAdminAccountDisabled') %> - echo Disabling %tempAdminUser% - net user %tempAdminUser% %tempAdminUser% /active:no - <% end %> - - <% if host_param('ansible_port') == 5985 or host_param('ansible_winrm_scheme') == 'http' %> - cmd /c winrm set winrm/config/service @{AllowUnencrypted="true"} - <% end %> - - <% if host_param('ansible_winrm_transport') == 'basic' %> - cmd /c winrm set winrm/config/client/auth @{Basic="true"} - cmd /c winrm set winrm/config/service/auth @{Basic="true"} - <% end %> - - <% if host_param('ansible_winrm_transport') == 'credssp' %> - cmd /c winrm set winrm/config/client/auth @{CredSSP="true"} - cmd /c winrm set winrm/config/service/auth @{CredSSP="true"} - <% end %> - - <% if host_param('ansible_winrm_transport') == 'certificate' %> - cmd /c winrm set winrm/config/client/auth @{Certificate="true"} - cmd /c winrm set winrm/config/service/auth @{Certificate="true"} - <% end %> - - <%= snippet 'Windows network' %> - - <% if foreman_url('user_data') %> - echo execute user data script - IF EXIST c:\deploy\user_data.ps1 powershell.exe -OutputFormat text -command c:\deploy\user_data.ps1 - <% end -%> - - <% if puppet_enabled %> - echo Installing puppet - start /w "" msiexec /qn /i C:\extras\puppet.msi PUPPET_AGENT_STARTUP_MODE=Manual PUPPET_MASTER_SERVER=<%= host_puppet_server -%> PUPPET_AGENT_ACCOUNT_DOMAIN=<%= @host.domain -%> PUPPET_AGENT_ACCOUNT_USER=administrator PUPPET_AGENT_ACCOUNT_PASSWORD="<%= host_param('domainAdminAccountPasswd') -%>" - echo set puppet to auto start - sc config puppet start= auto - sc query puppet - <% end%> - - <% if host_param('foremanDebug') != true %> - - echo reboot in 15sec - start /b shutdown /r /t 15 - - echo Safely remove wimaging files - sdelete.exe -accepteula -p 2 -r c:\wimaging - sdelete.exe -accepteula -p 2 -r c:\minint - sdelete.exe -accepteula -p 2 c:\Windows\Panther\unattend.xml - sdelete.exe -accepteula -p 2 C:\Windows\Setup\Scripts\SetupComplete.cmd - - echo Safely remove leftover directories - sdelete.exe -accepteula -p 2 -r c:\drivers - sdelete.exe -accepteula -p 2 -r c:\updates - - echo Safely removing c:\deploy - cd / - sdelete.exe -accepteula -p 2 -r c:\deploy - <% end -%> +echo Activating administrator +net user administrator /active:yes +<% end -%> + +<% if @host.pxe_build? -%> +set ctr=0 +set nettimeout=10 +<% end -%> + +<%= snippet 'windows_network' %> + +<% if host_param('ntpServer') -%> +echo Setting time server +w32tm /config /manualpeerlist:<%= host_param('ntpServer') %> /syncfromflags:manual /update +<% end -%> + +echo Syncing time +w32tm /resync + +<% if host_param('computerDomain') -%> +<% if host_param('domainAdminAccount').present? && host_param('domainAdminAccountPasswd').present? -%> +echo Performing secure domain join +powershell.exe -OutputFormat text -command Add-Computer -DomainName '<%= host_param('computerDomain') -%>' -Credential (New-Object -TypeName System.Management.Automation.PSCredential '<%= host_param('domainAdminAccount') -%>', (ConvertTo-SecureString -String '<%= host_param('domainAdminAccountPasswd') -%>' -AsPlainText -Force))<% if host_param('computerOU').present? -%> -OUPath '<%= host_param('computerOU') -%>'<% end -%> +<% else -%> +<% if host_param('machinePassword').present? -%> +echo Performing unsecure domain join +powershell.exe -OutputFormat text -command Add-Computer -Domain '<%= host_param('computerDomain') -%>' -Options UnsecuredJoin,PasswordPass -Credential (New-Object -TypeName System.Management.Automation.PSCredential $null, (ConvertTo-SecureString -String '<%= host_param('machinePassword') -%>' -AsPlainText -Force)) +<% end -%> +<% end -%> +<% end -%> + +<% if host_param('localAdminAccountDisabled') -%> +echo Disabling %tempAdminUser% +net user %tempAdminUser% %tempAdminUser% /active:no +<% end -%> + +<% if host_param('http-proxy').present? -%> +cmd /C "netsh winhttp set proxy <%= host_param('http-proxy') %>:<%= host_param('http-proxy-port') %>" +<% end -%> + +<% unless host_param('computerDomain') -%> +powershell /c "Get-NetConnectionProfile -InterfaceAlias \"Ethernet0\" | Set-NetConnectionProfile -NetworkCategory <%= network_location %>" +<% end -%> + +<% if host_param('ansible_user').present? -%> +<% if host_param_true?('create_ansible_user') -%> +powershell /c "set-localuser -name <%= host_param('ansible_user') %> -passwordneverexpires 1" +<% end -%> +powershell /c "Enable-PSRemoting" +cmd /c "netsh advfirewall firewall add rule name="WinRM-HTTP" dir=in localport=5985 protocol=TCP action=allow" +cmd /c winrm set winrm/config/service @{AllowUnencrypted="true"} +cmd /c winrm set winrm/config/client/auth @{Basic="true"} +cmd /c winrm set winrm/config/service/auth @{Basic="true"} +<% end -%> + +<% if host_param('ping') -%> +cmd /c "netsh advfirewall firewall add rule name=\"Enable IPv4 ICMP\" dir=in protocol=icmpv4 action=allow" +<% end -%> + +<% if host_param('remote_desktop') -%> +cmd /c "netsh advfirewall firewall set rule group=\"remote desktop\" new enable=Yes" +cmd /c "netsh advfirewall firewall set rule group=\"remotedesktop\" new enable=Yes" +<% end -%> + +<% if puppet_enabled -%> +echo Downloading Puppet installer +wget "<%= host_param('win_puppet_source') %>" -O C:\puppet-agent-latest.msi +echo Installing Puppet +start /w "" msiexec /qn /i C:\puppet-agent-latest.msi PUPPET_AGENT_STARTUP_MODE=Manual PUPPET_SERVER=<%= host_puppet_server -%> PUPPET_CA_SERVER=<%= host_puppet_ca_server -%> PUPPET_AGENT_ACCOUNT_DOMAIN=<%= @host.domain -%> PUPPET_AGENT_ACCOUNT_USER=administrator PUPPET_AGENT_ACCOUNT_PASSWORD="<%= host_param('domainAdminAccountPasswd') -%>" +echo Setting Puppet to auto start +sc config puppet start= auto +sc query puppet +<% end -%> + +<% if !host_param_true?('foremanDebug') -%> +echo Rebooting in 60 sec +shutdown /r /t 60 + +echo Removing wimaging files +rd /s /q c:\wimaging +sdelete.exe -accepteula -p 2 c:\Windows\Panther\unattend.xml +sdelete.exe -accepteula -p 2 C:\Windows\Setup\Scripts\SetupComplete.cmd + +echo Removing leftover directories +rd /s /q c:\MININT +rd /s /q c:\drivers +rd /s /q c:\updates + +<% if puppet_enabled -%> +echo Removing Puppet installer +sdelete.exe -accepteula -p 2 C:\puppet-agent-latest.msi +<% end -%> + +echo Removing deploy directory +rd /s /q c:\deploy + <% end -%> diff --git a/app/views/unattended/provisioning_templates/provision/windows_default_provisioning.erb b/app/views/unattended/provisioning_templates/provision/windows_default_provisioning.erb index c9e256ef7e6..e84d6428854 100644 --- a/app/views/unattended/provisioning_templates/provision/windows_default_provisioning.erb +++ b/app/views/unattended/provisioning_templates/provision/windows_default_provisioning.erb @@ -4,6 +4,8 @@ name: Windows default provision model: ProvisioningTemplate oses: - Windows +test_on: +- windows10_dhcp description: | A templated answers.xml file for windows installations. This provides all answers to the questions an interactive installation would ask. It supports the following parameters: @@ -12,13 +14,15 @@ description: | - systemLocale: en-US - systemUILanguage: en-US - systemTimeZone: GMT Standard Time #see https://msdn.microsoft.com/en-us/library/ms912391(v=winembedded.11).aspx - - wimImageName = Windows 8.1 Pro # Image name seems only necessary if the WIM contains more than one image + - wimImageName = Windows 10 Pro # Image name seems only necessary if the WIM contains more than one image -%> <% - system_locale = host_param('systemLocale') ? host_param('systemLocale') : 'en-US' - system_ui_lang = host_param('systemUILanguage') ? host_param('systemUILanguage') : 'en-US' + system_locale = host_param('systemLocale', 'en-US') + system_ui_lang = host_param('systemUILanguage', 'en-US') setup_ui_lang = 'en-US' - system_timezone = host_param('systemTimeZone') ? host_param('systemTimeZone') : 'GMT Standard Time' + input_locale = host_param('inputLocale', 'en-US') + system_timezone = host_param('systemTimeZone', 'GMT Standard Time') + network_location = host_param('networklocation', 'private') -%> @@ -30,14 +34,14 @@ description: | - <%= host_param('EnableFirewall') || 'true' %> + <%= host_param('EnableFirewall', 'true') %> true Restart - <%= host_param('wimImageName') -%> + <%= host_param('wimImageName') -%> true @@ -52,7 +56,7 @@ description: | <%= setup_ui_lang %> - <%= system_locale %> + <%= input_locale %> <%= system_locale %> <%= setup_ui_lang %> <%= system_ui_lang %> @@ -61,7 +65,7 @@ description: | - <%= system_locale %> + <%= input_locale %> <%= system_locale %> <%= setup_ui_lang %> <%= system_ui_lang %> @@ -70,9 +74,23 @@ description: | - false</PlainText> <Value><%= root_pass %></Value> + <PlainText>false</PlainText> </AdministratorPassword> + <% if host_param('ansible_user') && host_param('create_ansible_user') -%> + <LocalAccounts> + <LocalAccount wcm:action="add"> + <Password> + <Value>![CDATA[<%= host_param('ansible_ssh_pass') %>]]</Value> + <PlainText>true</PlainText> + </Password> + <Description>Ansible login service user</Description> + <DisplayName><%= host_param('ansible_user') %></DisplayName> + <Group>Administrators</Group> + <Name><%= host_param('ansible_user') %></Name> + </LocalAccount> + </LocalAccounts> + <% end -%> </UserAccounts> <TimeZone><%= system_timezone -%></TimeZone> <% if host_param('windowsLicenseOwner') -%> @@ -81,7 +99,7 @@ description: | <% end -%> <OOBE> <HideEULAPage>true</HideEULAPage> - <NetworkLocation>Work</NetworkLocation> + <NetworkLocation>Home</NetworkLocation> <ProtectYourPC>1</ProtectYourPC> <SkipUserOOBE>true</SkipUserOOBE> <SkipMachineOOBE>true</SkipMachineOOBE> @@ -113,16 +131,26 @@ description: | <RegisteredOrganization><%= host_param('windowsLicenseOwner') -%></RegisteredOrganization> <RegisteredOwner><%= host_param('windowsLicenseOwner') -%></RegisteredOwner> <% end -%> - <TimeZone><%= system_timezone -%></TimeZone> + <TimeZone><%= system_timezone -%></TimeZone> </component> <component name="Networking-MPSSVC-Svc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <DomainProfile_EnableFirewall><%= host_param('EnableFirewall') || 'true' %></DomainProfile_EnableFirewall> - <PrivateProfile_EnableFirewall><%= host_param('EnableFirewall') || 'true' %></PrivateProfile_EnableFirewall> - <PublicProfile_EnableFirewall><%= host_param('EnableFirewall') || 'true' %></PublicProfile_EnableFirewall> + <DomainProfile_EnableFirewall><%= host_param('EnableFirewall', 'true') %></DomainProfile_EnableFirewall> + <PrivateProfile_EnableFirewall><%= host_param('EnableFirewall', 'true') %></PrivateProfile_EnableFirewall> + <PublicProfile_EnableFirewall><%= host_param('EnableFirewall', 'true') %></PublicProfile_EnableFirewall> + </component> + <component name="Microsoft-Windows-DNS-Client" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <% if @host.provision_interface.subnet && !@host.provision_interface.subnet.dhcp_boot_mode? -%> + <DNSSuffixSearchOrder> + <DomainName wcm:action="add" wcm:keyValue="1"><%= @host.domain %></DomainName> + </DNSSuffixSearchOrder> + <% end -%> + <DNSDomain><%= @host.domain %></DNSDomain> </component> + <% if host_param('hide_server_manager') -%> <component name="Microsoft-Windows-ServerManager-SvrMgrNc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <DoNotOpenServerManagerAtLogon>true</DoNotOpenServerManagerAtLogon> </component> + <% end -%> <component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <fDenyTSConnections>false</fDenyTSConnections> </component> diff --git a/app/views/unattended/provisioning_templates/script/windows_default_script.erb b/app/views/unattended/provisioning_templates/script/windows_default_script.erb index 0c444ac5d5e..f984a66ae77 100644 --- a/app/views/unattended/provisioning_templates/script/windows_default_script.erb +++ b/app/views/unattended/provisioning_templates/script/windows_default_script.erb @@ -4,15 +4,20 @@ name: Windows peSetup.cmd model: ProvisioningTemplate oses: - Windows +test_on: +- windows10_dhcp description: | The provisioning template used for Windows You can create and assign a "user_data" ProvisioningTemplate as powershell to execute some custom code See https://community.theforeman.org/t/windows-provisioning-made-easy/16756/ params: - wimImageName: Windows 8.1 Pro # name of wim image to apply + - windowsLicenseKey: ABCDE-ABCDE-ABCDE-ABCDE-ABCDE # Valid Windows license key + - windowsLicenseOwner: Company, INC # Legal owner of the Windows license key -%> <% - proxy_uri = host_param('http-proxy') ? "http://#{host_param('http-proxy')}:#{host_param('http-proxy-port') || 3128}" : nil + iface = @host.provision_interface + proxy_uri = host_param('http-proxy') ? "#{host_param('http-proxy')}:#{host_param('http-proxy-port', 3128)}" : nil proxy_string = proxy_uri ? "-e http_proxy=#{proxy_uri}" : '' %> @setlocal enableextensions enabledelayedexpansion @@ -21,13 +26,25 @@ set WGET=wget64.exe <%= @host.diskLayout %> -echo Started downloading main WIM -%WGET% <%= proxy_string %> "<%= medium_uri %>/sources/images.ini" -O X:\images.ini +<% if iface.subnet && !iface.subnet.dhcp_boot_mode? -%> +echo Setting network config for static interfaces + netsh interface ip set address name="Ethernet0" static "<%= iface.ip %>" "<%= iface.subnet.mask %>" "<%= iface.subnet.gateway %>" + net stop "DHCP-Client" + net stop "DHCP Client" + net start "DNS-Client" + net start "DNS Client" + ping -n "<%= iface.subnet.gateway %>" + netsh interface ip set dns name="Ethernet0" static "<%= iface.subnet.dns_primary %>" +<% end -%> + +echo Downloading main WIM + +%WGET% <%= proxy_string %> "<%= medium_uri %>sources/images.ini" -O X:\images.ini if %ERRORLEVEL% == 0 goto :lookup_image echo WARNING: Couldn't download the images.ini, falling back to legacy mode! -%WGET% <%= proxy_string %> "<%= medium_uri %>/sources/install.wim" -O C:\install.wim +%WGET% <%= proxy_string %> "<%= medium_uri %>sources/install.wim" -O C:\install.wim goto :install :lookup_image @@ -39,7 +56,7 @@ for /f "usebackq delims=" %%a in ("!file!") do ( set currkey=%%b set currval=%%c if "x!key!"=="x!currkey!" ( - %WGET% <%= proxy_string %> "<%= medium_uri %>/sources/!currval!" -O C:\install.wim + %WGET% <%= proxy_string %> <%= medium_uri %>sources/!currval! -O C:\install.wim ) ) ) @@ -49,9 +66,9 @@ for /f "usebackq delims=" %%a in ("!file!") do ( echo Writing install image to partition while downloading additional files ( - start /min cmd /C "echo Write the install image to the partition + start /min cmd /C "echo Writing the install image to the partition dism.exe /apply-image /imagefile:C:\install.wim /Name:"<%= host_param('wimImageName') %>" /ApplyDir:C:\ - echo removing install.wim + echo Removing install.wim del /q /s C:\install.wim" start /min cmd /C "echo Downloading the drivers md c:\drivers @@ -74,37 +91,36 @@ IF not exist %PantherDirectory% (mkdir %PantherDirectory%) echo Finalizing installation... echo Downloading custom theme -%WGET% -P C:\Windows\Web\ -r -np -nH --cut-dirs=3 -R index.html -q --level=0 <%= medium_uri %>/theme/ +%WGET% <%= proxy_string %> -P C:\Windows\Web\ -r -np -nH --cut-dirs=3 -R index.html -q --level=0 "<%= medium_uri %>/theme/" -echo Stage the Unattend.xml file for dism to apply +echo Staging the Unattend.xml file for dism to apply echo Downloading unattend.xml %WGET% --no-verbose <%= foreman_url("provision") -%> -O c:\Windows\Panther\unattend.xml -echo Apply Unattend.xml +echo Applying Unattend.xml dism.exe /Image:C:\ /Apply-Unattend:C:\Windows\Panther\unattend.xml /ScratchDir:C:\MININT\Scratch/ -echo copy tools +echo Copying tools copy x:\windows\system32\wget64.exe C:\deploy\ copy x:\windows\system32\wget64.exe C:\Windows\wget.exe copy x:\windows\system32\sdelete.exe C:\Windows\ IF not exist C:\Windows\Setup\Scripts (md C:\Windows\Setup\Scripts) echo call C:\deploy\foreman-finish.bat ^> c:\foreman.log 2^>^&1 > C:\Windows\Setup\Scripts\SetupComplete.cmd -<% if foreman_url('user_data') %> -echo Downloading user data script -%WGET% <%= foreman_url('user_data') %> -O c:\deploy\user_data.ps1 +<% unless host_param('foremanDebug') -%> +sdelete.exe -accepteula -p 2 c:\foreman.log <% end -%> -echo Apply Drivers +echo Applying drivers dism.exe /Image:C:\ /Add-Driver /Driver:C:\drivers\ /Recurse /ForceUnsigned -echo Apply Updates +echo Applying updates for /f %%u in ('dir /s/b C:\updates\*.msu') do dism.exe /Image:C:\ /Add-Package /PackagePath:%%u /ScratchDir:C:\MININT\Scratch/ echo Setting the boot sector bootsect.exe /nt60 C: C:\Windows\System32\bcdboot C:\Windows /l en-US -echo Tell foreman build has finished +echo Foreman build has finished %WGET% <%= foreman_url('built') %> exit 0 diff --git a/app/views/unattended/provisioning_templates/snippet/windows_networking_snippet.erb b/app/views/unattended/provisioning_templates/snippet/windows_network.erb similarity index 69% rename from app/views/unattended/provisioning_templates/snippet/windows_networking_snippet.erb rename to app/views/unattended/provisioning_templates/snippet/windows_network.erb index c2633ea197c..bd1f132a9f6 100644 --- a/app/views/unattended/provisioning_templates/snippet/windows_networking_snippet.erb +++ b/app/views/unattended/provisioning_templates/snippet/windows_network.erb @@ -1,8 +1,10 @@ <%# -name: Windows network +name: windows_network model: ProvisioningTemplate snippet: true kind: snippet +test_on: +- windows10_dhcp description: | Configures networking using netsh command on Windows hosts. -%> @@ -25,40 +27,43 @@ for /f "delims=" %%a in ('ipconfig /all') do ( <% @host.managed_interfaces.each do |interface| -%> if "<%= interface.mac %>"=="!mac!" ( - <% if !interface.identifier.empty? %> + <% if (interface.subnet.nil? ? false : interface.subnet.dhcp_boot_mode?) -%> + echo DHCP is active + <% end -%> + <% if !interface.identifier.empty? -%> netsh interface set interface name="!name!" newname="<%= interface.identifier %>" - <% if (interface.subnet.nil? ? false : !interface.subnet.dhcp_boot_mode?) %> + <% if (interface.subnet.nil? ? false : !interface.subnet.dhcp_boot_mode?) -%> netsh interface ip set address "<%= interface.identifier %>" static <%= interface.ip %> <%= interface.subnet.mask %> <%= interface.subnet.gateway %> - <% if (interface.subnet.nil? ? false : interface.subnet.dns_primary.present?) %> + <% if (interface.subnet.nil? ? false : interface.subnet.dns_primary.present?) -%> netsh interface ip add dnsserver "<%= interface.identifier %>" address="<%= interface.subnet.dns_primary %>" index=1 - <% end %> - <% if (interface.subnet.nil? ? false : interface.subnet.dns_secondary.present?) %> + <% end -%> + <% if (interface.subnet.nil? ? false : interface.subnet.dns_secondary.present?) -%> netsh interface ip add dnsserver "<%= interface.identifier %>" address="<%= interface.subnet.dns_secondary %>" index=2 - <% end %> - <% end %> - <% if interface.subnet6 %> + <% end -%> + <% end -%> + <% if interface.subnet6 -%> netsh interface ipv6 add address "<%= interface.identifier %>" <%= interface.ip6 %>/<%= interface.subnet6.cidr %> - <% if interface.subnet6.gateway %> + <% if interface.subnet6.gateway -%> netsh interface ipv6 add route ::/0 "<%= interface.identifier %>" <%= interface.subnet6.gateway %> - <% end %> - <% end %> - <% else %> - <% if !(interface.subnet.nil? ? false : interface.subnet.dhcp_boot_mode?) %> + <% end -%> + <% end -%> + <% else -%> + <% if (interface.subnet.nil? ? false : !interface.subnet.dhcp_boot_mode?) -%> netsh interface ip set address "!name!" static <%= interface.ip %> <%= interface.subnet.mask %> <%= interface.subnet.gateway %> - <% if (interface.subnet.nil? ? false : interface.subnet.dns_primary.present?) %> + <% if (interface.subnet.nil? ? false : interface.subnet.dns_primary.present?) -%> netsh interface ip add dnsserver "!name!" address="<%= interface.subnet.dns_primary %>" index=1 - <% end %> - <% if (interface.subnet.nil? ? false : interface.subnet.dns_secondary.present?) %> + <% end -%> + <% if (interface.subnet.nil? ? false : interface.subnet.dns_secondary.present?) -%> netsh interface ip add dnsserver "!name!" address="<%= interface.subnet.dns_secondary %>" index=2 - <% end %> - <% end %> - <% if interface.subnet6 %> + <% end -%> + <% end -%> + <% if interface.subnet6 -%> netsh interface ipv6 add address "!name!" <%= interface.ip6 %>/<%= interface.subnet6.cidr %> - <% if interface.subnet6.gateway %> + <% if interface.subnet6.gateway -%> netsh interface ipv6 add route ::/0 "!name!" <%= interface.subnet6.gateway %> - <% end %> - <% end %> - <% end %> + <% end -%> + <% end -%> + <% end -%> ) <% end -%> ) diff --git a/app/views/unattended/provisioning_templates/user_data/windows_default_user_data.erb b/app/views/unattended/provisioning_templates/user_data/windows_default_user_data.erb index ad201b24661..d99ce46644c 100644 --- a/app/views/unattended/provisioning_templates/user_data/windows_default_user_data.erb +++ b/app/views/unattended/provisioning_templates/user_data/windows_default_user_data.erb @@ -47,13 +47,13 @@ identity: - "<%= powershell %> -NonInteractive -Command \"winrm set winrm/config/service/auth '@{Certificate=\\\"true\\\"}'\"" <% end %> <% if puppet_enabled %> - - "<%= powershell %> -Command \"invoke-webrequest -Uri <%= host_param('win_puppet_source') %> -OutFile C:\\puppet-agent-x64-latest.msi\"" + - "<%= powershell %> -Command \"invoke-webrequest -Uri <%= host_param('win_puppet_source') %> -OutFile C:\\puppet-agent-latest.msi\"" - "<%= powershell %> -Command \"md C:\\ProgramData\\PuppetLabs\\puppet\\etc\"" - "<%= powershell %> -Command \"echo \"[main]\" | out-file C:\\ProgramData\\PuppetLabs\\puppet\\etc\\puppet.conf -encoding utf8\"" - "<%= powershell %> -Command \"echo \"server=http://<%= foreman_server_fqdn %>:8000/unattended/built?token=cae2cc74-1394-4acb-ad16-1011020b9bbe\" | add-content C:\\ProgramData\\PuppetLabs\\puppet\\etc\\puppet.conf -encoding utf8\"" - "<%= powershell %> -Command \"echo \"autoflush=true\" | add-content C:\\ProgramData\\PuppetLabs\\puppet\\etc\\puppet.conf -encoding utf8\"" - - "<%= powershell %> -Command \"start /wait \"\" msiexec /qn /norestart /i C:\\puppet-agent-x64-latest.msi PUPPET_MASTER_SERVER=<%= @host.puppet_server %>\"" - - "<%= powershell %> -Command \"sdelete.exe -accepteula -p 2 C:\\puppet-agent-x64-latest.msi\"" + - "<%= powershell %> -Command \"start /wait \"\" msiexec /qn /norestart /i C:\\puppet-agent-latest.msi PUPPET_MASTER_SERVER=<%= @host.puppet_server %>\"" + - "<%= powershell %> -Command \"sdelete.exe -accepteula -p 2 C:\\puppet-agent-latest.msi\"" <% end %> guiUnattended: autoLogon: true diff --git a/test/factories/host_related.rb b/test/factories/host_related.rb index b2c8a31b7a7..e929b234c09 100644 --- a/test/factories/host_related.rb +++ b/test/factories/host_related.rb @@ -37,6 +37,12 @@ def set_nic_attributes(host, attributes, evaluator) layout { "<partitioning config:type=\"list\">\n <drive>\n <device>/dev/hda</device>\n <use>all</use>\n </drive>\n</partitioning>" } os_family { 'Suse' } end + + trait :windows do + sequence(:name) { |n| "windows default#{n}" } + layout { "select disk 0\nclean\nconvert gpt\ncreate partition efi size=200\nformat quick fs=fat32 label=\"System\"\nassign letter=\"S\"\ncreate partition msr size=16\ncreate partition primary\nformat quick fs=ntfs label=\"Windows\"\nassign letter=\"W\"\nlist volume\nexit" } + os_family { 'Windows' } + end end factory :parameter do @@ -335,6 +341,10 @@ def set_nic_attributes(host, attributes, evaluator) factory :host_for_snapshots_ipv4_dhcp_rocky9 do operatingsystem { FactoryBot.build(:for_snapshots_rocky9) } end + + factory :host_for_snapshots_ipv4_dhcp_windows10 do + operatingsystem { FactoryBot.build(:for_snapshots_windows10) } + end end trait :with_dhcp_orchestration do diff --git a/test/factories/medium.rb b/test/factories/medium.rb index 5b65684f7cd..363cd514c85 100644 --- a/test/factories/medium.rb +++ b/test/factories/medium.rb @@ -26,6 +26,11 @@ path { 'http://archive.ubuntu.com/ubuntu' } end + factory :windows_for_snapshots do + name { "Windows Mirror" } + path { 'http://archive.example.com/windows' } + end + trait :centos do sequence(:name) { |n| "CentOS Mirror #{n}" } sequence(:path) { 'http://mirror.centos.org/centos/$major/os/x86_64' } diff --git a/test/factories/operatingsystem.rb b/test/factories/operatingsystem.rb index 4004448dc25..8eeb54f7369 100644 --- a/test/factories/operatingsystem.rb +++ b/test/factories/operatingsystem.rb @@ -242,6 +242,17 @@ ptables { [FactoryBot.build(:ptable, name: 'ptable')] } end + factory :for_snapshots_windows10, class: Windows do + name { 'Windows' } + major { '10' } + minor { '0' } + type { 'Windows' } + title { 'Windows 10' } + architectures { [FactoryBot.build(:architecture, :for_snapshots_x86_64)] } + media { [FactoryBot.build(:windows_for_snapshots)] } + ptables { [FactoryBot.build(:ptable, :windows)] } + end + factory :altlinux, class: Altlinux do sequence(:name) { 'Altlinux' } major { '8' } diff --git a/test/unit/foreman/renderer/snapshots.yaml b/test/unit/foreman/renderer/snapshots.yaml index da9d96d6cdc..438efa7552d 100644 --- a/test/unit/foreman/renderer/snapshots.yaml +++ b/test/unit/foreman/renderer/snapshots.yaml @@ -79,3 +79,7 @@ files: - iPXE/kickstart_default_ipxe.erb - iPXE/preseed_default_ipxe.erb - iPXE/preseed_default_ipxe_autoinstall.erb + - provision/windows_default_provisioning.erb + - finish/windows_default_finish.erb + - script/windows_default_script.erb + - snippet/windows_network.erb diff --git a/test/unit/foreman/renderer/snapshots/ProvisioningTemplate/finish/Windows_default_finish.windows10_dhcp.snap.txt b/test/unit/foreman/renderer/snapshots/ProvisioningTemplate/finish/Windows_default_finish.windows10_dhcp.snap.txt new file mode 100644 index 00000000000..fee6e46538d --- /dev/null +++ b/test/unit/foreman/renderer/snapshots/ProvisioningTemplate/finish/Windows_default_finish.windows10_dhcp.snap.txt @@ -0,0 +1,77 @@ + + +@echo off +echo Activating administrator +net user administrator /active:yes + +set ctr=0 +set nettimeout=10 + +@echo off +setlocal enableDelayedExpansion + +for /f "delims=" %%a in ('ipconfig /all') do ( + set line=%%a + if not "!line:~0,1!"==" " if not "!line:adapter=!"=="!line!" ( + set name=!line:*adapter =! + set name=!name::=! + ) + + for /f "tokens=1,2,*" %%b in ("%%a") do ( + if "%%b %%c"=="Physical Address." ( + set mac=%%d + set mac=!mac:*: =! + set mac=!mac:-=:! + call :tolower mac + + ) + ) +) +call :done + +:tolower +for %%L IN (a b c d e f g h i j k l m n o p q r s t u v w x y z) DO SET %1=!%1:%%L=%%L! +goto :EOF + +:done + + + +echo Syncing time +w32tm /resync + + + + +powershell /c "Get-NetConnectionProfile -InterfaceAlias \"Ethernet0\" | Set-NetConnectionProfile -NetworkCategory Private" + + + + +echo Downloading Puppet installer +wget "" -O C:\puppet-agent-latest.msi +echo Installing Puppet +start /w "" msiexec /qn /i C:\puppet-agent-latest.msi PUPPET_AGENT_STARTUP_MODE=Manual PUPPET_SERVER= PUPPET_CA_SERVER= PUPPET_AGENT_ACCOUNT_DOMAIN=snap.example.com PUPPET_AGENT_ACCOUNT_USER=administrator PUPPET_AGENT_ACCOUNT_PASSWORD="" +echo Setting Puppet to auto start +sc config puppet start= auto +sc query puppet + +echo Rebooting in 60 sec +shutdown /r /t 60 + +echo Removing wimaging files +rd /s /q c:\wimaging +sdelete.exe -accepteula -p 2 c:\Windows\Panther\unattend.xml +sdelete.exe -accepteula -p 2 C:\Windows\Setup\Scripts\SetupComplete.cmd + +echo Removing leftover directories +rd /s /q c:\MININT +rd /s /q c:\drivers +rd /s /q c:\updates + +echo Removing Puppet installer +sdelete.exe -accepteula -p 2 C:\puppet-agent-latest.msi + +echo Removing deploy directory +rd /s /q c:\deploy + diff --git a/test/unit/foreman/renderer/snapshots/ProvisioningTemplate/provision/Windows_default_provision.windows10_dhcp.snap.txt b/test/unit/foreman/renderer/snapshots/ProvisioningTemplate/provision/Windows_default_provision.windows10_dhcp.snap.txt new file mode 100644 index 00000000000..0d0a6ddc492 --- /dev/null +++ b/test/unit/foreman/renderer/snapshots/ProvisioningTemplate/provision/Windows_default_provision.windows10_dhcp.snap.txt @@ -0,0 +1,102 @@ +<?xml version="1.0" encoding="utf-8"?> +<unattend xmlns="urn:schemas-microsoft-com:unattend"> + <servicing></servicing> + <settings pass="offlineServicing"> + <component name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <EnableLUA>false</EnableLUA> + </component> + </settings> + <settings pass="windowsPE"> + <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <EnableFirewall>true</EnableFirewall> + <EnableNetwork>true</EnableNetwork> + <Restart>Restart</Restart> + <ImageInstall> + <OSImage> + <InstallFrom> + <MetaData wcm:action="add"> + <Value></Value> + </MetaData> + </InstallFrom> + <InstallToAvailablePartition>true</InstallToAvailablePartition> + <WillShowUI>OnError</WillShowUI> + </OSImage> + </ImageInstall> + <UserData> + <AcceptEula>true</AcceptEula> + </UserData> + </component> + <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <SetupUILanguage> + <UILanguage>en-US</UILanguage> + </SetupUILanguage> + <InputLocale>en-US</InputLocale> + <SystemLocale>en-US</SystemLocale> + <UILanguageFallback>en-US</UILanguageFallback> + <UILanguage>en-US</UILanguage> + <UserLocale>en-US</UserLocale> + </component> + </settings> + <settings pass="oobeSystem"> + <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <InputLocale>en-US</InputLocale> + <SystemLocale>en-US</SystemLocale> + <UILanguageFallback>en-US</UILanguageFallback> + <UILanguage>en-US</UILanguage> + <UserLocale>en-US</UserLocale> + </component> + <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <UserAccounts> + <AdministratorPassword> + <Value>$1$rtd8Ub7R$5Ohzuy8WXlkaK9cA2T1wb0</Value> + <PlainText>false</PlainText> + </AdministratorPassword> + </UserAccounts> + <TimeZone>GMT Standard Time</TimeZone> + <OOBE> + <HideEULAPage>true</HideEULAPage> + <NetworkLocation>Home</NetworkLocation> + <ProtectYourPC>1</ProtectYourPC> + <SkipUserOOBE>true</SkipUserOOBE> + <SkipMachineOOBE>true</SkipMachineOOBE> + <HideLocalAccountScreen>true</HideLocalAccountScreen> + <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> + <HideOnlineAccountScreens>true</HideOnlineAccountScreens> + <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> + </OOBE> + <ShowWindowsLive>false</ShowWindowsLive> + </component> + </settings> + <settings pass="specialize"> + <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <InputLocale>en-US</InputLocale> + <SystemLocale>en-US</SystemLocale> + <UILanguageFallback>en-US</UILanguageFallback> + <UILanguage>en-US</UILanguage> + <UserLocale>en-US</UserLocale> + </component> + <component name="Microsoft-Windows-IE-ESC" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <IEHardenAdmin>false</IEHardenAdmin> + </component> + <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <ComputerName></ComputerName> + <TimeZone>GMT Standard Time</TimeZone> + </component> + <component name="Networking-MPSSVC-Svc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <DomainProfile_EnableFirewall>true</DomainProfile_EnableFirewall> + <PrivateProfile_EnableFirewall>true</PrivateProfile_EnableFirewall> + <PublicProfile_EnableFirewall>true</PublicProfile_EnableFirewall> + </component> + <component name="Microsoft-Windows-DNS-Client" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <DNSDomain>snap.example.com</DNSDomain> + </component> + <component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <fDenyTSConnections>false</fDenyTSConnections> + </component> + <component name="Microsoft-Windows-TerminalServices-RDP-WinStationExtensions" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <SecurityLayer>1</SecurityLayer> + <UserAuthentication>0</UserAuthentication> + </component> + </settings> + <cpi:offlineImage cpi:source="catalog:c:/deploy/wimaging/sources/win81x64/sources/install_windows 8.1 pro.clg" xmlns:cpi="urn:schemas-microsoft-com:cpi" /> +</unattend> diff --git a/test/unit/foreman/renderer/snapshots/ProvisioningTemplate/script/Windows_peSetup.cmd.windows10_dhcp.snap.txt b/test/unit/foreman/renderer/snapshots/ProvisioningTemplate/script/Windows_peSetup.cmd.windows10_dhcp.snap.txt new file mode 100644 index 00000000000..a0171b0d98f --- /dev/null +++ b/test/unit/foreman/renderer/snapshots/ProvisioningTemplate/script/Windows_peSetup.cmd.windows10_dhcp.snap.txt @@ -0,0 +1,104 @@ + +@setlocal enableextensions enabledelayedexpansion +@echo off +set WGET=wget64.exe + +select disk 0 +clean +convert gpt +create partition efi size=200 +format quick fs=fat32 label="System" +assign letter="S" +create partition msr size=16 +create partition primary +format quick fs=ntfs label="Windows" +assign letter="W" +list volume +exit + + + +echo Downloading main WIM + +%WGET% "http://archive.example.com/windowssources/images.ini" -O X:\images.ini +if %ERRORLEVEL% == 0 goto :lookup_image + +echo WARNING: Couldn't download the images.ini, falling back to legacy mode! +%WGET% "http://archive.example.com/windowssources/install.wim" -O C:\install.wim +goto :install + +:lookup_image +set file=X:\images.ini +set key= +for /f "usebackq delims=" %%a in ("!file!") do ( + set ln=%%a + for /f "tokens=1,2 delims==" %%b in ("!ln!") do ( + set currkey=%%b + set currval=%%c + if "x!key!"=="x!currkey!" ( + %WGET% http://archive.example.com/windowssources/!currval! -O C:\install.wim + ) + ) + ) +) + +:install +echo Writing install image to partition while downloading additional files + +( + start /min cmd /C "echo Writing the install image to the partition + dism.exe /apply-image /imagefile:C:\install.wim /Name:"" /ApplyDir:C:\ + echo Removing install.wim + del /q /s C:\install.wim" + start /min cmd /C "echo Downloading the drivers + md c:\drivers + %WGET% -P c:\drivers -r -np -nH --cut-dirs=3 -R index.html -q --level=0 http://archive.example.com/windows/drivers/" + start /min cmd /C "echo Downloading additional updates + md c:\updates + %WGET% -P c:\updates\ -r -np -nH --cut-dirs=3 -R index.html -q --level=0 http://archive.example.com/windows/updates/" + start /min cmd /C "echo Downloading finsh script and activating SetupComplete.cmd + md c:\deploy + %WGET% --no-verbose http://foreman.example.com/unattended/finish -O C:\deploy\foreman-finish.bat" +) | pause + +echo Creating a temp staging folder for DISM +md c:\MININT\Scratch + +echo Creating the Panther directory if needed +set PantherDirectory=C:\Windows\Panther\ +IF not exist %PantherDirectory% (mkdir %PantherDirectory%) + +echo Finalizing installation... + +echo Downloading custom theme +%WGET% -P C:\Windows\Web\ -r -np -nH --cut-dirs=3 -R index.html -q --level=0 "http://archive.example.com/windows/theme/" + +echo Staging the Unattend.xml file for dism to apply +echo Downloading unattend.xml +%WGET% --no-verbose http://foreman.example.com/unattended/provision -O c:\Windows\Panther\unattend.xml +echo Applying Unattend.xml +dism.exe /Image:C:\ /Apply-Unattend:C:\Windows\Panther\unattend.xml /ScratchDir:C:\MININT\Scratch/ + +echo Copying tools +copy x:\windows\system32\wget64.exe C:\deploy\ +copy x:\windows\system32\wget64.exe C:\Windows\wget.exe +copy x:\windows\system32\sdelete.exe C:\Windows\ +IF not exist C:\Windows\Setup\Scripts (md C:\Windows\Setup\Scripts) +echo call C:\deploy\foreman-finish.bat ^> c:\foreman.log 2^>^&1 > C:\Windows\Setup\Scripts\SetupComplete.cmd + +sdelete.exe -accepteula -p 2 c:\foreman.log + +echo Applying drivers +dism.exe /Image:C:\ /Add-Driver /Driver:C:\drivers\ /Recurse /ForceUnsigned + +echo Applying updates +for /f %%u in ('dir /s/b C:\updates\*.msu') do dism.exe /Image:C:\ /Add-Package /PackagePath:%%u /ScratchDir:C:\MININT\Scratch/ + +echo Setting the boot sector +bootsect.exe /nt60 C: +C:\Windows\System32\bcdboot C:\Windows /l en-US + +echo Foreman build has finished +%WGET% http://foreman.example.com/unattended/built + +exit 0 diff --git a/test/unit/foreman/renderer/snapshots/ProvisioningTemplate/snippet/windows_network.windows10_dhcp.snap.txt b/test/unit/foreman/renderer/snapshots/ProvisioningTemplate/snippet/windows_network.windows10_dhcp.snap.txt new file mode 100644 index 00000000000..94e57f1ec62 --- /dev/null +++ b/test/unit/foreman/renderer/snapshots/ProvisioningTemplate/snippet/windows_network.windows10_dhcp.snap.txt @@ -0,0 +1,27 @@ +@echo off +setlocal enableDelayedExpansion + +for /f "delims=" %%a in ('ipconfig /all') do ( + set line=%%a + if not "!line:~0,1!"==" " if not "!line:adapter=!"=="!line!" ( + set name=!line:*adapter =! + set name=!name::=! + ) + + for /f "tokens=1,2,*" %%b in ("%%a") do ( + if "%%b %%c"=="Physical Address." ( + set mac=%%d + set mac=!mac:*: =! + set mac=!mac:-=:! + call :tolower mac + + ) + ) +) +call :done + +:tolower +for %%L IN (a b c d e f g h i j k l m n o p q r s t u v w x y z) DO SET %1=!%1:%%L=%%L! +goto :EOF + +:done