├── FILES └── .gitignore ├── ISO └── .gitignore ├── VM └── .gitignore ├── .gitignore ├── Example-privatedata.json ├── scripts ├── sysprep-shutdown.ps1 ├── SetupComplete-qemu.ps1 ├── tools-winrm.ps1 ├── SetupComplete-vmw.ps1 ├── cloudbase-init.ps1 ├── bootstrap-win.ps1 ├── cleanup-compact.ps1 ├── configure-win.ps1 ├── configure-windows-local-policy.ps1 └── windows-update-winrm.ps1 ├── cloud_init ├── cloudbase-init.conf ├── cloudbase-init-unattend.conf └── cloudbase-init-firstboot.ps1 ├── LICENSE ├── README.md ├── answer_files ├── vmw │ └── 10 │ │ └── Autounattend.xml └── qemu │ └── 10 │ └── Autounattend.xml └── Win10.json /FILES/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /ISO/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /VM/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | privatedata.json 3 | -------------------------------------------------------------------------------- /Example-privatedata.json: -------------------------------------------------------------------------------- 1 | { 2 | "localuser_win_pass": "localuser-10" 3 | } -------------------------------------------------------------------------------- /scripts/sysprep-shutdown.ps1: -------------------------------------------------------------------------------- 1 | # Kick off sysprep 2 | start-process -FilePath 'C:/windows/System32/Sysprep/sysprep.exe' -ArgumentList '/oobe /generalize /shutdown "/unattend:C:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf\Unattend.xml"' 3 | exit 0 -------------------------------------------------------------------------------- /scripts/SetupComplete-qemu.ps1: -------------------------------------------------------------------------------- 1 | 2 | # start cloudbase-init service and set to auto-start 3 | start-process -nonewwindow -FilePath "C:/Windows/system32/sc.exe" -ArgumentList "config cloudbase-init start= auto" -wait 4 | start-process -nonewwindow -FilePath "C:/Windows/system32/sc.exe" -ArgumentList "start cloudbase-init" -wait 5 | 6 | exit 0 7 | -------------------------------------------------------------------------------- /scripts/tools-winrm.ps1: -------------------------------------------------------------------------------- 1 | # install vmware tools 2 | write-output "Starting VMare Tools install" 3 | 4 | ## Download vmware tools 5 | $client = new-object System.Net.WebClient 6 | $client.DownloadFile("https://packages.vmware.com/tools/releases/latest/windows/x64/VMware-tools-10.0.9-3917699-x86_64.exe", "C:\windows\temp\setup64.exe" ) 7 | 8 | #Write-host "Installing VMware Tools..." 9 | start-process -FilePath 'C:/Windows/Temp/setup64.exe' -ArgumentList '/S /v "/qn /l*v ""C:\windows\temp\vmwtoolsinstall.log"" ADDLOCAL=ALL REMOVE=Hgfs REBOOT=R"' -------------------------------------------------------------------------------- /scripts/SetupComplete-vmw.ps1: -------------------------------------------------------------------------------- 1 | # if you create custom ovfEnv properties in your template you can easily turn them into Environment variables for fun automation possibiliites. 2 | 3 | # read properties from vmware tools and store as xml 4 | & "C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" --cmd "info-get guestinfo.ovfEnv" 2>&1 | tee-object -variable vmtoolsxml | out-null 5 | [xml]$vmtoolsxml = $vmtoolsxml 6 | 7 | # turn all properties into ps Environment variables 8 | foreach( $property in $vmtoolsxml.Environment.PropertySection.SelectNodes("*")){ 9 | $ps_varname = ($property.key | %{$_ -replace "vm.",""} | %{$_ -replace "\.","_"} ) 10 | new-variable -name $ps_varname -value $property.value 11 | } 12 | 13 | 14 | 15 | exit 0 -------------------------------------------------------------------------------- /cloud_init/cloudbase-init.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | bsdtar_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\bsdtar.exe 3 | mtools_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\ 4 | verbose=true 5 | debug=false 6 | logdir=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\log\ 7 | logfile=cloudbase-init.log 8 | default_log_levels=comtypes=INFO,suds=INFO,iso8601=WARN,requests=WARN 9 | logging_serial_port_settings=COM1,115200,N,8 10 | local_scripts_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\ 11 | metadata_services=cloudbaseinit.metadata.services.httpservice.HttpService 12 | plugins=cloudbaseinit.plugins.common.localscripts.LocalScriptsPlugin,cloudbaseinit.plugins.common.userdata.UserDataPlugin 13 | allow_reboot=true 14 | stop_service_on_exit=false 15 | check_latest_version=false -------------------------------------------------------------------------------- /cloud_init/cloudbase-init-unattend.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | username=Administrator 3 | inject_user_password=true 4 | first_logon_behaviour=no 5 | bsdtar_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\bsdtar.exe 6 | mtools_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\ 7 | verbose=true 8 | debug=false 9 | logdir=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\log\ 10 | logfile=cloudbase-init-unattend.log 11 | default_log_levels=comtypes=INFO,suds=INFO,iso8601=WARN,requests=WARN 12 | logging_serial_port_settings=COM1,115200,N,8 13 | local_scripts_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\ 14 | metadata_services=cloudbaseinit.metadata.services.httpservice.HttpService 15 | plugins=cloudbaseinit.plugins.common.setuserpassword.SetUserPasswordPlugin 16 | allow_reboot=true 17 | stop_service_on_exit=false 18 | check_latest_version=false -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Blake Garner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /scripts/cloudbase-init.ps1: -------------------------------------------------------------------------------- 1 | #download installer 2 | $client = new-object System.Net.WebClient 3 | $client.DownloadFile("https://cloudbase.it/downloads/CloudbaseInitSetup_Stable_x64.msi", "C:\windows\temp\CloudbaseInitSetup_Stable_x64.msi" ) 4 | 5 | # install the payload 6 | start-process -FilePath 'c:\Windows\temp\CloudbaseInitSetup_Stable_x64.msi' -ArgumentList '/qn /l*v C:\windows\temp\cloud-init.log LOGGINGSERIALPORTNAME=COM1 USERNAME=admin' -passthru | wait-process 7 | 8 | # verify that cloudbase-init tools exists 9 | if (-not(test-path -path "C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts")){ 10 | Write-output "cloudbase-init not installed exiting..." 11 | exit 1 12 | } 13 | 14 | move-item C:\Windows\Temp\cloudbase-init-unattend.conf "C:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf\cloudbase-init-unattend.conf" -force 15 | move-item C:\Windows\Temp\cloudbase-init.conf "C:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf\cloudbase-init.conf" -force 16 | move-item C:\Windows\Temp\cloudbase-init-firstboot.ps1 "C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\cloudbase-init-firstboot.ps1" -force 17 | start-process -nonewwindow -FilePath "C:/Windows/system32/sc.exe" -ArgumentList "config cloudbase-init start= demand" -wait 18 | -------------------------------------------------------------------------------- /scripts/bootstrap-win.ps1: -------------------------------------------------------------------------------- 1 | # windows powershell bootstrap script 2 | $host.ui.RawUI.WindowTitle = "Bootstrapping Windows" 3 | 4 | ## Identify the version of windows 5 | 6 | # test to see if this is a desktop version of windows 7 | $windesktop = (gwmi win32_operatingsystem).OperatingSystemSKU -notmatch "(\b[7-9]|10|1[2-5]|1[7-9]|2[0-5])" 8 | if ($windesktop) 9 | { 10 | write-output "This is a desktop version of windows" 11 | } 12 | 13 | # get the windows kernel version 14 | $KERNELVERSION = [Environment]::OSVersion.Version 15 | 16 | # example test for reference. 17 | # 6.1 = Windows 7 & 2008 R2 18 | # 6.2 = Windows 8 & Server 2012 19 | # 6.3 = Windows 8.1 & Server 2012 R2 20 | # 10.0 = Windows 10 & Server 2016 21 | #if ($KERNELVERSION -ge (new-object 'Version' 10,0)) { 22 | # write-output "Windows 10 kernel version" 23 | #} 24 | 25 | # supress network location Prompt 26 | New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Network\NewNetworkWindowOff" -Force 27 | 28 | # set network to private 29 | $ifaceinfo = Get-NetConnectionProfile 30 | Set-NetConnectionProfile -InterfaceIndex $ifaceinfo.InterfaceIndex -NetworkCategory Private 31 | #need to test below 32 | #Get-NetAdapter | Set-NetConnectionProfile -NetworkCategory Private 33 | 34 | # Make administrator user active for desktop OS 35 | net user administrator /active:yes 36 | 37 | # disable windows defender If you install your own AV later 38 | #if ($KERNELVERSION -ge (new-object 'Version' 10,0)) { 39 | # Set-MpPreference -DisableRealtimeMonitoring $true -DisableArchiveScanning $true -DisableIOAVProtection $true 40 | #} 41 | 42 | # enable winrm on http 43 | set-wsmanquickconfig -force 44 | 45 | # config winrm settings to work with packer 46 | winrm set winrm/config '@{MaxTimeoutms="1800000"}' 47 | winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="2048"}' 48 | winrm set winrm/config/service '@{AllowUnencrypted="true"}' 49 | winrm set winrm/config/service/auth '@{Basic="true"}' 50 | winrm set winrm/config/client/auth '@{Basic="true"}' 51 | winrm set winrm/config/listener?Address=*+Transport=HTTP '@{Port="5985"}' 52 | winrm set winrm/config/winrs '@{MaxConcurrentUsers="200"}' 53 | winrm set winrm/config/winrs '@{MaxShellsPerUser="200"}' 54 | 55 | # configure powersaving and screen saver 56 | powercfg -setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 57 | powercfg -change -monitor-timeout-ac 0 58 | powercfg -hibernate OFF 59 | 60 | New-Itemproperty -Path "registry::HKCU\Control Panel\Desktop" -Name ScreenSaveActive -Value 0 -PropertyType "DWord" -Force 61 | New-Itemproperty -Path "registry::HKCU\Control Panel\Desktop" -Name ScreenSaveTimeOut -Value 0 -PropertyType "DWord" -Force 62 | New-Itemproperty -Path "registry::HKU\.DEFAULT\Control Panel\Desktop" -Name ScreenSaveActive -Value 0 -PropertyType "DWord" -Force 63 | New-Itemproperty -Path "registry::HKU\.DEFAULT\Control Panel\Desktop" -Name ScreenSaveTimeOut -Value 0 -PropertyType "DWord" -Force 64 | 65 | #Stop windows updtes from starting immediatly 66 | $WUSettings = (New-Object -com "Microsoft.Update.AutoUpdate").Settings 67 | $WUSettings.NotificationLevel=1 68 | $WUSettings.save() 69 | -------------------------------------------------------------------------------- /scripts/cleanup-compact.ps1: -------------------------------------------------------------------------------- 1 | #Powershell version of install cleanup_compact 2 | 3 | # get the windows kernel version 4 | $KERNELVERSION = [Environment]::OSVersion.Version 5 | 6 | get-packageprovider -name chocolatey -ForceBootstrap 7 | install-package sdelete -force 8 | #install-package ultradefrag -force 9 | 10 | # unzip function 11 | function punzip( $zipfile, $outdir ) { 12 | If(-not(Test-Path -path $zipfile)){return "zipfile " + $zipfile + " not found!"} 13 | If(-not(Test-Path -path $outdir)){return "output dir " + $outdir + " not found!"} 14 | $shell = new-object -com shell.application 15 | $zip = $shell.NameSpace($zipfile) 16 | foreach($item in $zip.items()) 17 | { 18 | $shell.Namespace($outdir).copyhere($item) 19 | } 20 | } 21 | 22 | ## Download the FILES 23 | $client = new-object System.Net.WebClient 24 | $client.DownloadFile("http://downloads.sourceforge.net/project/ultradefrag/stable-release/7.0.1/ultradefrag-portable-7.0.1.bin.amd64.zip", "C:\windows\temp\ultradefrag-portable-7.0.1.bin.amd64.zip" ) 25 | 26 | # Stops the windows update service. 27 | Stop-Service -Name wuauserv -Force -EA 0 28 | Get-Service -Name wuauserv 29 | 30 | # Delete the contents of windows software distribution. 31 | write-output "Delete the contents of windows software distribution" 32 | Get-ChildItem "C:\Windows\SoftwareDistribution\*" -Recurse -Force -Verbose -ErrorAction SilentlyContinue | remove-item -force -recurse -ErrorAction SilentlyContinue 33 | 34 | # Delete the contents of localuser apps. 35 | write-output "Delete the contents of localuser apps" 36 | Get-ChildItem "C:\users\localuser\AppData\Local\Packages\*" -Recurse -Force -Verbose -ErrorAction SilentlyContinue | remove-item -force -recurse -ErrorAction SilentlyContinue 37 | 38 | # Delete the contents of user template desktop. 39 | write-output "Delete the contents of user template desktop" 40 | Get-ChildItem "C:\Users\Public\Desktop\*" -Recurse -Force -Verbose -ErrorAction SilentlyContinue | remove-item -force -recurse -ErrorAction SilentlyContinue 41 | 42 | # Starts the Windows Update Service 43 | Start-Service -Name wuauserv -EA 0 44 | 45 | # use dism to cleanup windows sxs. This only works on 2012r2 and 8.1 and above. 46 | # bumped up to windows 10 only as was failing on 2012r2 47 | if ([Environment]::OSVersion.Version -ge [Version]"10.0") { 48 | write-output "Cleaning up winSXS with dism" 49 | dism /online /cleanup-image /startcomponentcleanup /resetbase /quiet 50 | } 51 | 52 | # extract ultradefrag archive 53 | write-output "extracting ultradefrag archive" 54 | punzip ("C:\windows\temp\ultradefrag-portable-7.0.1.bin.amd64.zip") ("C:\Windows\temp") 55 | 56 | # Defragment the virtual disk blocks 57 | write-output "Starting to Defragment Disk" 58 | start-process -FilePath 'C:\Windows\Temp\ultradefrag-portable-7.0.1.amd64\udefrag.exe' -ArgumentList '--optimize --repeat C:' -wait -verb RunAs 59 | 60 | # Zero dirty blocks 61 | write-output "Starting to Zero blocks" 62 | #New-Item -Path "HKCU:\Software\Sysinternals\SDelete" -force -ErrorAction SilentlyContinue 63 | #Set-ItemProperty -Path "HKCU:\Software\Sysinternals\SDelete" -Name EulaAccepted -Value "1" -Type DWORD -force 64 | start-process -FilePath 'C:\Chocolatey\bin\sdelete64.bat' -ArgumentList '-q -z C:' -wait -EA 0 65 | uninstall-package sdelete -force 66 | 67 | exit 0 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # packer-win-pc 2 | ***packer.io templates & scripts for building private cloud optimized Windows OS images.*** 3 | If your unclear what packer templates are about check http://packer.io 4 | 5 | This template is used to create both VMware ESXi and OpenStack/KVM templates of Windows 10. It utilzes Windows RM and PowerShell scripts to build the latest OS with the modern tools. These images use virtio/pvscsi intefaces for the boot disk for optimized IO. 6 | 7 | ***Google Groups thread*** 8 | If you want to discuss this project please use this thread. 9 | https://groups.google.com/forum/#!topic/packer-tool/6evwAHomcaA 10 | 11 | **Prerequsits** 12 | 13 | You will need to have http://packer.io installed and the appropriate hypervisor. QEMU/KVM and VMware Workstation/Fusion/Player are ones you should have avialable. Linux systems that can have Workstation and QEMU/KVM are ideal as you can build both images at the same time given enough system resrouces. 14 | 15 | Extract the pvscsi and vmxnet3 drivers from VMware tools installer and popluate the FILES directory. 16 | https://kb.vmware.com/kb/2032184 17 | 18 | Aquire a set of virtio windows drivers. Ideally install the virtio-win package on redhat and extract those as they are signed drivers. 19 | 20 | Populate the FILES with the drivers as shown below. These get written to a flopy image before the sysetem is booted. Downloading them after boot is not realistic. 21 |
22 | FILES
23 | ├── pvscsi
24 | │   ├── pvscsi.cat
25 | │   ├── pvscsi.inf
26 | │   ├── pvscsi.sys
27 | │   ├── pvscsiver.dll
28 | │   └── txtsetup.oem
29 | ├── virtio-win
30 | │   └── Win8.1
31 | │       ├── netkvm.cat
32 | │       ├── netkvm.inf
33 | │       ├── netkvm.sys
34 | │       ├── vioscsi.cat
35 | │       ├── vioscsi.inf
36 | │       ├── vioscsi.sys
37 | │       ├── viostor.cat
38 | │       ├── viostor.inf
39 | │       └── viostor.sys
40 | └── vmxnet3
41 |     ├── vmxnet3n61x64.sys
42 |     ├── vmxnet3n61x86.sys
43 |     ├── vmxnet3ndis6.cat
44 |     ├── vmxnet3ndis6.inf
45 |     └── vmxnet3ndis6ver.dll
46 | 
47 | 48 | Grab your installer .iso files and put them in the ISO directory. 49 |
50 | ISO
51 | ├── RELEASE_CLIENTENTERPRISE_OEM_X64FRE_EN-US.ISO
52 | └── RELEASE_SERVER_OEM_X64FRE_EN-US.ISO
53 | 
54 | 55 | ***Required changes to the template file*** 56 | ISO filename 57 | You must edit the Win10.json file to inclued the correct path to your Windows 10 .iso file in both builders. Additionally update the sha256 checksum that matches your .iso. 58 | 59 | ***Private data*** 60 | In this example the only private data is the password used for local administrator and "localuser" user account. Copy the Example-privatedate.json to privatedata.json in the root of the directory. Add your own password here and the file will be ignored by git. Follow this practice for any other data you do not want in your repo. 61 | 62 | ***Building the images*** 63 | After configuring your build system with the required bits and prerequsits use the following commands to build the images. From the root of the git repo run the follwing commands. 64 | 65 | Quick validation of file paths... 66 |
packer validate -var-file privatedata.json Win10.json
67 | 68 | Build both OpenStack and VMware images at the same time 69 |
packer build -force -var-file privatedata.json Win10.json
70 | 71 | Build the VMware image only 72 |
packer build -force -var-file privatedata.json -only vmware-iso Win10.json
73 | 74 | Build the OpenStack image only 75 |
packer build -force -var-file privatedata.json -only qemu Win10.json
76 | 77 | 78 | ***References*** 79 | https://github.com/joefitzgerald/packer-windows 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /scripts/configure-win.ps1: -------------------------------------------------------------------------------- 1 | # windows server cleanup 2 | 3 | # test to see if this is a desktop version of windows 4 | $windesktop = (gwmi win32_operatingsystem).OperatingSystemSKU -notmatch "(\b[7-9]|10|1[2-5]|1[7-9]|2[0-5])" 5 | if ($windesktop) 6 | { 7 | write-output "This is a desktop version of windows" 8 | } 9 | 10 | write-output "Disable Hybernation" 11 | powercfg -hibernate OFF 12 | 13 | write-output "configure screen saver" 14 | Set-ItemProperty -Path "registry::HKEY_USERS\.DEFAULT\Control Panel\Desktop" -Name ScreenSaveActive -Value 0 15 | 16 | write-output "change administrator user pass next login" 17 | # this gets reset by sysprep/guest customization. need to set it again in the guest customization script. 18 | net user localuser /logonpasswordchg:no 19 | 20 | write-output "Enable administrator account" 21 | net user administrator /active:yes 22 | 23 | write-output "Disable firewall" 24 | netsh advfirewall set allprofiles state off 25 | 26 | write-output "supress network location Prompt" 27 | New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Network\NewNetworkWindowOff" -Force 28 | 29 | # remove troublesome 3rd party app store apps that cause sysprep to fail 30 | if ($windesktop) 31 | { 32 | if ([Environment]::OSVersion.Version -ge (new-object 'Version' 10,0)) 33 | { 34 | Get-AppxPackage -user localuser PackageFullName | Remove-AppxPackage -ErrorAction SilentlyContinue 35 | } 36 | } 37 | 38 | ## Optimize IPv6 settings 39 | write-output "disable privacy IPv6 addresses" 40 | netsh interface ipv6 set privacy state=disabled store=active 41 | netsh interface ipv6 set privacy state=disabled store=persistent 42 | 43 | write-output "enable EUI-64 addressing" 44 | netsh interface ipv6 set global randomizeidentifiers=disabled store=active 45 | netsh interface ipv6 set global randomizeidentifiers=disabled store=persistent 46 | 47 | write-output "Enable Remote Desktop" 48 | (Get-WmiObject Win32_TerminalServiceSetting -Namespace root\cimv2\TerminalServices).SetAllowTsConnections(1,1) | Out-Null 49 | (Get-WmiObject -Class "Win32_TSGeneralSetting" -Namespace root\cimv2\TerminalServices -Filter "TerminalName='RDP-tcp'").SetUserAuthenticationRequired(0) | Out-Null 50 | 51 | write-output "Clear windows autologon" 52 | Remove-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultDomainName -EA 0 53 | Remove-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultUserName -EA 0 54 | Remove-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name AutoAdminLogon -EA 0 55 | Remove-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultUserPassword -EA 0 56 | 57 | # not the most secure option here.. 58 | write-output "Enable remote command policy" 59 | Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name LocalAccountTokenFilterPolicy -Value 1 -Type DWord 60 | 61 | # sysprep with wmf 5 fix 62 | Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\StreamProvider -Name LastFullPayloadTime -Value 0 -Type DWord 63 | 64 | # set ntp to sync time before domain join 65 | Write-Output "Setting System Time Zone to UTC `r" 66 | tzutil.exe /s "UTC" 67 | 68 | write-output "setup guest customization shim" 69 | if(!(Test-Path -Path "C:\Windows\Setup\Scripts" )){ 70 | New-Item -ItemType directory -Path "C:\Windows\Setup\Scripts" 71 | } 72 | Set-Content -path C:\windows\setup\scripts\SetupComplete.cmd -value 'powershell -executionpolicy bypass -file C:\windows\setup\scripts\SetupComplete.ps1' 73 | move-item c:\windows\temp\SetupComplete.ps1 c:\windows\setup\scripts\ 74 | 75 | -------------------------------------------------------------------------------- /cloud_init/cloudbase-init-firstboot.ps1: -------------------------------------------------------------------------------- 1 | #ps1_sysnative 2 | # powershell guest customizatin payload script for vcloud and vsphere 3 | 4 | write-output "itc customization started" 5 | 6 | # setup logging 7 | Start-Transcript -path c:\windows\temp\cloudbase-init-firstboot.log -Append -force 8 | 9 | 10 | ## Identify the version of windows 11 | 12 | # test to see if this is a desktop version of windows 13 | $windesktop = (gwmi win32_operatingsystem).OperatingSystemSKU -notmatch "(\b[7-9]|10|1[2-5]|1[7-9]|2[0-5])" 14 | if ($windesktop) 15 | { 16 | write-output "This is a desktop version of windows" 17 | } 18 | 19 | # get the windows kernel version 20 | $KERNELVERSION = [Environment]::OSVersion.Version 21 | 22 | # example test for reference. 23 | # 6.1 = Windows 7 & 2008 R2 24 | # 6.2 = Windows 8 & Server 2012 25 | # 6.3 = Windows 8.1 & Server 2012 R2 26 | # 10.0 = Windows 10 & Server 2016 27 | if ($KERNELVERSION -ge (new-object 'Version' 10,0)) { 28 | write-output "Windows 10 kernel version" 29 | } 30 | 31 | ## Set windows computer/hostname from the primary IP reverse DNS record 32 | # get default gateway IP 33 | $gateway=(gwmi Win32_networkAdapterConfiguration | ?{$_.IPEnabled}).DefaultIPGateway 34 | 35 | # trim to the first two octets of default route 36 | $gatewaynet = $gateway.split('.') 37 | $gatewaynet = $gatewaynet[0,1] 38 | $gatewaynet = $gatewaynet -join '.' 39 | 40 | # get list of IPv4 addresses 41 | $localipaddr=(gwmi Win32_NetworkAdapterConfiguration | ? { $_.IPAddress -ne $null }).ipaddress 42 | 43 | # match IPv4 address to default gateway and make sure it's only one IP 44 | $primaryip = $localipaddr -like "$gatewaynet*" | Select-Object -first 1 45 | 46 | # lookup reverse dns record for that IP 47 | $reversefqdn=(nslookup "$primaryip") -match "Name" | select-object -last 1 48 | $reversefqdn = ($reversefqdn).split(" ") | select-object -last 1 49 | 50 | # get the shortname 51 | $new_hostname = $reversefqdn.split('.') 52 | $new_hostname = $new_hostname[0] 53 | 54 | # use primary IP reverse DNS name to rename the host 55 | write-output "Changing Windows hostname to $new_hostname" 56 | $ComputerInfo = Get-WmiObject -Class Win32_ComputerSystem 57 | $ComputerInfo.Rename($new_hostname) 58 | 59 | # set dns search suffix 60 | Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -name "NV Domain" -value "example.com" -type string -Force 61 | Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -name "SyncDomainWithMembership" -value "0" -type dword -Force 62 | 63 | # Set time zone and sync clock with ntp 64 | Write-Output "Setting System Time Zone to UTC `r" 65 | tzutil.exe /s "UTC" 66 | 67 | # configure NTP for local site 68 | Write-Output "Setting System Time via NTP `r" 69 | $DNS_SERVER = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "IPEnabled = 'True'").DNSServerSearchOrder | Select-Object -first 1 70 | Set-Service -Name "w32time" -StartupType Automatic -Status stopped 71 | w32tm /config /manualpeerlist:$DNS_SERVER /syncfromflags:MANUAL 72 | start-Service "w32time" 73 | w32tm /resync 74 | 75 | # Disable firewall 76 | Write-Output "Configuring firewall... `r" 77 | netsh advfirewall set allprofiles state off 78 | 79 | # Set activation server 80 | Write-Output "Setting KMS for CORP `r" 81 | cscript C:\Windows\System32\slmgr.vbs /skms kms.example.com 82 | 83 | # Clear windows autologon 84 | Remove-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultDomainName -ea Silentlycontinue 85 | Remove-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultUserName -ea Silentlycontinue 86 | Remove-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name AutoAdminLogon -ea Silentlycontinue 87 | 88 | # Make administrator user active for desktop OS 89 | net user administrator /active:yes 90 | 91 | # disable password never expires on administrator account 92 | Get-WmiObject -Class Win32_UserAccount -Filter "name = 'administrator'" | Set-WmiInstance -Argument @{PasswordExpires = 1} 93 | 94 | # set localuser user to not have expiring password. Sysprep resets this after customization 95 | Write-Output "Setting localuser user to no-expire password `r" 96 | net user localuser /expires:never /active:yes /logonpasswordchg:no 97 | 98 | # extend disk 99 | $extendvolume=@( 100 | 'select volume 1', 101 | 'extend', 102 | 'exit' 103 | ) 104 | $extendvolume | diskpart 105 | 106 | # stop logging 107 | stop-transcript 108 | 109 | # exit with return code 1001 110 | exit 1001 111 | -------------------------------------------------------------------------------- /scripts/configure-windows-local-policy.ps1: -------------------------------------------------------------------------------- 1 | $ProgressPreference="SilentlyContinue" 2 | 3 | # test to see if this is a desktop version of windows 4 | $windesktop = (gwmi win32_operatingsystem).OperatingSystemSKU -notmatch "(\b[7-9]|10|1[2-5]|1[7-9]|2[0-5])" 5 | if ($windesktop) 6 | { 7 | write-output "This is a desktop version of windows" 8 | } 9 | 10 | # get the windows kernel version 11 | $KERNELVERSION = [Environment]::OSVersion.Version 12 | 13 | # example test for reference. 14 | # 6.1 = Windows 7 & 2008 R2 15 | # 6.2 = Windows 8 & Server 2012 16 | # 6.3 = Windows 8.1 & Server 2012 R2 17 | # 10.0 = Windows 10 & Server 2016 18 | #if ($KERNELVERSION -ge (new-object 'Version' 10,0)) { 19 | # write-output "Windows 10 kernel version" 20 | #} 21 | 22 | # install PolicyFileEditor 23 | Install-Module -Name PolicyFileEditor -Confirm:$false 24 | 25 | # disable windows defender 26 | Set-PolicyFileEntry -Path $env:systemroot\system32\GroupPolicy\Machine\registry.pol -Key "Software\Policies\Microsoft\Windows Defender" -ValueName DisableAntiSpyware -Data 1 -Type DWord 27 | 28 | # reg unload 29 | Set-PolicyFileEntry -Path $env:systemroot\system32\GroupPolicy\Machine\registry.pol -Key "Software\Policies\Microsoft\Windows\System" -ValueName DisableForceUnload -Data 1 -Type DWord 30 | 31 | # ProcessCreationIncludeCmdLine_Enabled 32 | Set-PolicyFileEntry -Path $env:systemroot\system32\GroupPolicy\Machine\registry.pol -Key "Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit" -ValueName ProcessCreationIncludeCmdLine_Enabled -Data 1 -Type DWord 33 | 34 | # set RDP Min encryption level 35 | Set-PolicyFileEntry -Path $env:systemroot\system32\GroupPolicy\Machine\registry.pol -Key "Software\Policies\Microsoft\Windows NT\Terminal Services" -ValueName MinEncryptionLevel -Data 3 -Type DWord 36 | 37 | # set RPC encryption 38 | Set-PolicyFileEntry -Path $env:systemroot\system32\GroupPolicy\Machine\registry.pol -Key "Software\Policies\Microsoft\Windows NT\Terminal Services" -ValueName fEncryptRPCTraffic -Data 1 -Type DWord 39 | 40 | Set-PolicyFileEntry -Path $env:systemroot\system32\GroupPolicy\Machine\registry.pol -Key "Software\Policies\Microsoft\Windows NT\Terminal Services" -ValueName fPromptForPassword -Data 1 -Type DWord 41 | 42 | # limit log size 43 | limit-eventlog -logname Security -MaximumSize 1048576kb 44 | 45 | # Windows 81 & 2012r2 or newer 46 | if ($KERNELVERSION -ge (new-object 'Version' 6,3)) { 47 | Set-PolicyFileEntry -Path $env:systemroot\system32\GroupPolicy\Machine\registry.pol -Key "Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging" -ValueName EnableModuleLogging -Data 1 -Type DWord 48 | Set-PolicyFileEntry -Path $env:systemroot\system32\GroupPolicy\Machine\registry.pol -Key "Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames" -ValueName **delvals. -Data 1 -Type String 49 | Set-PolicyFileEntry -Path $env:systemroot\system32\GroupPolicy\Machine\registry.pol -Key "Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames" -ValueName Microsoft.Powershell.* -Data Microsoft.Powershell.* -Type String 50 | } 51 | 52 | # Windows 10 specific policy 53 | if ($KERNELVERSION -ge (new-object 'Version' 10,0)) { 54 | write-output "Setting Windows Kernel Version 10 Policy" 55 | # disable web results search bar 56 | Set-PolicyFileEntry -Path $env:systemroot\system32\GroupPolicy\Machine\registry.pol -Key "Software\Policies\Microsoft\Windows\Windows Search" -ValueName ConnectedSearchUseWeb -Data 0 -Type DWord 57 | # disable Cortana 58 | Set-PolicyFileEntry -Path $env:systemroot\system32\GroupPolicy\Machine\registry.pol -Key "SOFTWARE\Policies\Microsoft\Windows\Windows Search" -ValueName AllowCortana -Data 0 -Type DWord 59 | } 60 | 61 | # show results 62 | write-output "Listing configured local windows policies" 63 | Get-PolicyFileEntry -Path $env:systemroot\system32\GroupPolicy\Machine\registry.pol -All 64 | 65 | 66 | write-output "Configure local security policy" 67 | secedit /export /cfg c:\windows\temp\secpol.cfg 68 | (get-content c:\windows\temp\secpol.cfg).replace('PasswordComplexity = 0', 'PasswordComplexity = 1') | Out-File c:\windows\temp\secpol.cfg 69 | (get-content c:\windows\temp\secpol.cfg).replace('MaximumPasswordAge = 42', 'MaximumPasswordAge = 90') | Out-File c:\windows\temp\secpol.cfg 70 | (get-content c:\windows\temp\secpol.cfg).replace('MaximumPasswordAge = 0', 'MaximumPasswordAge = 90') | Out-File c:\windows\temp\secpol.cfg 71 | (get-content c:\windows\temp\secpol.cfg).replace('PasswordHistorySize = 0', 'PasswordHistorySize = 10') | Out-File c:\windows\temp\secpol.cfg 72 | (get-content c:\windows\temp\secpol.cfg).replace('DontDisplayLastUserName=4,0', 'DontDisplayLastUserName=4,1') | Out-File c:\windows\temp\secpol.cfg 73 | (get-content c:\windows\temp\secpol.cfg).replace('CachedLogonsCount=1,"10"', 'CachedLogonsCount=1,"4"') | Out-File c:\windows\temp\secpol.cfg 74 | (get-content c:\windows\temp\secpol.cfg).replace('RestrictAnonymous=4,0', 'RestrictAnonymous=4,1') | Out-File c:\windows\temp\secpol.cfg 75 | (get-content c:\windows\temp\secpol.cfg).replace('FilterAdministratorToken=4,0', 'FilterAdministratorToken=4,1') | Out-File c:\windows\temp\secpol.cfg 76 | (get-content c:\windows\temp\secpol.cfg).replace('LockoutBadCount = 0', "LockoutBadCount = 5`nResetLockoutCount = 15`nLockoutDuration = 15`n") | Out-File c:\windows\temp\secpol.cfg 77 | (get-content c:\windows\temp\secpol.cfg).replace('MinimumPasswordLength = 8', 'MinimumPasswordLength = 12') | Out-File c:\windows\temp\secpol.cfg 78 | (get-content c:\windows\temp\secpol.cfg).replace('MinimumPasswordLength = 0', 'MinimumPasswordLength = 12') | Out-File c:\windows\temp\secpol.cfg 79 | (get-content c:\windows\temp\secpol.cfg).replace('FilterAdministratorToken=4,0', 'FilterAdministratorToken=4,1') | Out-File c:\windows\temp\secpol.cfg 80 | get-content c:\windows\temp\secpol.cfg 81 | secedit /configure /db c:\windows\security\local.sdb /cfg c:\windows\temp\secpol.cfg /areas SECURITYPOLICY 82 | 83 | #audit policy 84 | write-output "Configure local audit policy" 85 | auditpol /set /subcategory:"Credential Validation" /failure:enable /success:enable 86 | auditpol /set /subcategory:"Application Group Management" /failure:enable /success:enable 87 | auditpol /set /subcategory:"Computer Account Management" /failure:enable /success:enable 88 | auditpol /set /subcategory:"Distribution Group Management" /failure:enable /success:enable 89 | auditpol /set /subcategory:"Other Account Management Events" /failure:enable /success:enable 90 | auditpol /set /subcategory:"Security Group Management" /failure:enable /success:enable 91 | auditpol /set /subcategory:"User Account Management" /failure:enable /success:enable 92 | auditpol /set /subcategory:"Process Creation" /success:enable 93 | auditpol /set /subcategory:"Account Lockout" /failure:enable /success:enable 94 | auditpol /set /subcategory:"File Share" /failure:enable 95 | auditpol /set /subcategory:"Registry" /failure:enable 96 | auditpol /set /subcategory:"Removable Storage" /failure:enable /success:enable 97 | auditpol /set /subcategory:"SAM" /failure:enable /success:enable 98 | auditpol /set /subcategory:"Audit Policy Change" /failure:enable /success:enable 99 | auditpol /set /subcategory:"Authentication Policy Change" /failure:enable /success:enable 100 | auditpol /set /subcategory:"Sensitive Privilege Use" /success:enable 101 | auditpol /set /subcategory:"Security State Change" /failure:enable /success:enable 102 | auditpol /set /subcategory:"Security System Extension" /failure:enable /success:enable 103 | auditpol /set /subcategory:"Process Termination" /failure:enable /success:enable 104 | 105 | # report audit policy 106 | auditpol.exe /get /category:* 107 | -------------------------------------------------------------------------------- /scripts/windows-update-winrm.ps1: -------------------------------------------------------------------------------- 1 | # Powershell version of install windows update via task scheduler 2 | # This script creates a logon task to run windows updates. 3 | # Depends on packer windows-restart to start the taks and stop winrm. 4 | # After all updaets are instaled winrm is started and the login task is removed. 5 | 6 | # setup window name and script name variable 7 | $scriptname="windows-update-winrm.ps1" 8 | $host.ui.RawUI.WindowTitle = "$scriptname" 9 | 10 | # start logging 11 | start-transcript -path c:\windows\temp\windows-update-winrm.log -append 12 | 13 | # Report the IE version Installed 14 | Write-output ("Installed IE Version currently is " + (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Internet Explorer').Version) 15 | 16 | # Report the powershell version installed 17 | $powershellversion=$PSVersionTable.PSVersion 18 | write-output "Powershell version $powershellversion installed" 19 | if ($PSVersionTable.PSVersion.Major -lt 5) { 20 | write-output "Powershell upgrade in previous step failed!!" 21 | get-content "C:\Windows\wsusofflineupdate.log" 22 | exit 1 23 | } 24 | 25 | # Report the version of windows update agent 26 | $wu_agent=(get-command C:\windows\system32\wups2.dll).version 27 | if ($wu_agent -ge [Version]"7.6.7601.19161") { 28 | write-output "Windows Update agent is current! $wu_agent" 29 | } else { 30 | write-output "Windows Update agent out of date! $wu_agent" 31 | } 32 | 33 | # Check to see if scheduled task called $scriptname exists 34 | if (schtasks /query /tn $scriptname 2>$null ) { 35 | write-output "Checking for updates...." 36 | Get-WUInstallerStatus 37 | # hack to get buggy windows 7 to show updates 38 | #if ([Environment]::OSVersion.Version -le [Version]"6.1.7601.65536") { 39 | #if ((gwmi win32_operatingsystem).OperatingSystemSKU -notmatch "(\b[7-9]|10|1[2-5]|1[7-9]|2[0-5])") { 40 | if ([Version](Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Internet Explorer').Version -le [Version]"9.11.9600.18231") { 41 | write-output "Forcing Windows to search for updates until it finds some...." 42 | while (-not(Get-WindowsUpdate -notCategory "Windows 7 Language Packs")) { 43 | write-output "Still looking for updates...." 44 | } 45 | Write-output "Win Found some updates" 46 | } 47 | #} 48 | #} 49 | # Actually install the updates starts here.. 50 | if (Get-WindowsUpdate -notCategory "Windows 7 Language Packs" -NotTitle "Printer") 51 | { 52 | write-output "Starting Windows update installation..." 53 | # run windows updates 54 | Install-WindowsUpdate -IgnoreUserInput -AcceptALL -IgnoreReboot -verbose -notCategory "Windows 7 Language Packs" 55 | # restart after every insstall of updates 56 | stop-transcript 57 | restart-computer 58 | } else { 59 | write-output "No updates found..." 60 | # maybe check for systems that still show zero installed updates and reboot 61 | #if (Get-WUList -IsInstalled) {write-output "updates have been installed"} 62 | #remove scheduled task 63 | schtasks /delete /tn $scriptname /f 64 | # stop logging & dump to console so it gets recorded in packer log 65 | #get-content c:\windows\temp\windows-update-winrm.log 66 | # start winrm service and set to autostart 67 | start-process -nonewwindow -FilePath "C:/Windows/system32/sc.exe" -ArgumentList "config WinRM start= delayed-auto" -wait 68 | #start-process -nonewwindow -FilePath "C:/Windows/system32/sc.exe" -ArgumentList "start WinRM" -wait 69 | stop-transcript 70 | restart-computer 71 | } 72 | } else { 73 | # first run of script 74 | # setup windows updater components 75 | $ErrorActionPreference = 'Stop' 76 | # install nuget 77 | write-output "Installing NuGet" 78 | 79 | [int]$attempts = 0 80 | do { 81 | try { 82 | $attempts +=1 83 | Get-PackageProvider -Name NuGet -ForceBootstrap 84 | if (-not([string](Get-PackageProvider).name -match "NuGet")) { throw "Error installing NuGet" } 85 | break 86 | } catch { 87 | write-host "Problem installing NuGet `tAttempt $attempts ` 88 | `n`tException: " $_.Exception.Message 89 | start-sleep -s 20 90 | } 91 | } 92 | while ($attempts -lt 10) 93 | if ($attempts -ge 10) { 94 | write-host "NuGet failed to install!!" 95 | exit 1 96 | } 97 | 98 | # allow repo install 99 | write-output "adding PSGallery repo" 100 | Set-PSRepository -Name PSGallery -InstallationPolicy Trusted 101 | 102 | # install PSWindowsUpdate 103 | write-output "Installing PSWindowsUpdate" 104 | Install-Module -Name PSWindowsUpdate -Confirm:$false | out-null 105 | write-output "Installed PSWindowsUpdate" 106 | 107 | # attempt install early for debugging 108 | #Get-WUInstallerStatus 109 | 110 | #Get-WindowsUpdate -notCategory "Windows 7 Language Packs" 111 | write-output "Modern windows update tools installed..." 112 | 113 | ##### Debugging BS for windows 7 below.. 114 | #start-process -nonewwindow -FilePath "C:/Windows/system32/sc.exe" -ArgumentList "config bits start= auto" -wait 115 | #start-process -nonewwindow -FilePath "C:/Windows/system32/sc.exe" -ArgumentList "config wuauserv start= auto" -wait 116 | #start-process -nonewwindow -FilePath "C:/Windows/system32/sc.exe" -ArgumentList "config appidsvc start= auto" -wait 117 | #start-process -nonewwindow -FilePath "C:/Windows/system32/sc.exe" -ArgumentList "config cryptsvc start= auto" -wait 118 | 119 | #if ([Environment]::OSVersion.Version -le [Version]"6.2") { 120 | # Write-output "Installing KB KB2966583" 121 | # Install-WindowsUpdate -KBArticleID KB2966583 -acceptall 122 | #} 123 | 124 | # Stops the windows update service. 125 | # Get-Service -Name wuauserv | Stop-Service -Force -Verbose -ErrorAction SilentlyContinue 126 | 127 | # Delete the contents of windows software distribution. 128 | #write-output "Delete the contents of windows software distribution" 129 | #Get-ChildItem "C:\Windows\SoftwareDistribution\*" -Recurse -Force -Verbose -ErrorAction SilentlyContinue | remove-item -force -recurse -ErrorAction SilentlyContinue 130 | 131 | # setup windows update server from envrionment variables 132 | #write-output "Windows Update Group $env:wsus_group" 133 | #write-output "Windows Update Server $env:wsus_server" 134 | # check if you can reach the wsus server 135 | #If (test-connection -quiet $env:wsus_server) { 136 | #$wsusserver="http://" + $env:wsus_server + ":8530" 137 | #} elseif (test-connection -quiet 10.122.168.21) { 138 | #$wsusserver="http://10.122.168.21:8530" 139 | #} else { 140 | #write-output "Unable to contact the wsus server. Using microsoft.com" 141 | #} 142 | # set windows updates to pull from local wsus server 143 | #if ($wsusserver) { 144 | #write-output "WSUS server contacted " $wsusserver 145 | #New-Item -Path "HKLM:Software\Policies\Microsoft\Windows\WindowsUpdate\AU" -force -ErrorAction SilentlyContinue 146 | #Set-ItemProperty -Path "HKLM:\software\policies\Microsoft\Windows\WindowsUpdate" -Name WUServer -Value $wsusserver -Type String -force 147 | #Set-ItemProperty -Path "HKLM:\software\policies\Microsoft\Windows\WindowsUpdate" -Name WUStatusServer -Value $wsusserver -Type String -force 148 | #Set-ItemProperty -Path "HKLM:\software\policies\Microsoft\Windows\WindowsUpdate\AU" -Name UseWUServer -Value "1" -Type DWORD -force 149 | #Set-ItemProperty -Path "HKLM:\software\policies\Microsoft\Windows\WindowsUpdate" -Name TargetGroupEnabled -Value "1" -Type DWORD -force 150 | #Set-ItemProperty -Path "HKLM:\software\policies\Microsoft\Windows\WindowsUpdate" -Name TargetGroup -Value $env:wsus_group -Type String -force 151 | #} 152 | # set winrm to manual start to prevent packer from connecting on reboot 153 | Set-Service -Name winrm -StartupType Manual 154 | # if schedled task does not exist create it 155 | Write-output "Creating scheduled task to start $scriptname with proper elevation" 156 | # setup task scheduler login item to process this script next boot 157 | schtasks /create /ru "BUILTIN\administrators" /sc ONLOGON /tn $scriptname /tr "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File C:\windows\temp\$scriptname" /rl highest /f /np 158 | } 159 | stop-transcript 160 | exit 0 -------------------------------------------------------------------------------- /answer_files/vmw/10/Autounattend.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | a:\ 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Primary 18 | 1 19 | 350 20 | 21 | 22 | 2 23 | Primary 24 | true 25 | 26 | 27 | 28 | 29 | true 30 | NTFS 31 | 32 | 1 33 | 1 34 | 35 | 36 | NTFS 37 | 38 | C 39 | 2 40 | 2 41 | 42 | 43 | 0 44 | true 45 | 46 | 47 | 48 | true 49 | localuser Administrator 50 | localuser 51 | 52 | 53 | NPPR9-FWDCX-D2C8J-H872K-2YT43 54 | Never 55 | 56 | 57 | 58 | 59 | 60 | 0 61 | 2 62 | 63 | OnError 64 | false 65 | 66 | 67 | /IMAGE/NAME 68 | Windows 10 Enterprise 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | en-US 77 | 78 | en-US 79 | en-US 80 | en-US 81 | en-US 82 | en-US 83 | 84 | 85 | 86 | 87 | true 88 | 89 | 90 | 91 | 92 | 93 | 94 | localuser-10 95 | true</PlainText> 96 | </AdministratorPassword> 97 | <LocalAccounts> 98 | <LocalAccount wcm:action="add"> 99 | <Password> 100 | <Value>localuser-10</Value> 101 | <PlainText>true</PlainText> 102 | </Password> 103 | <Description>localuser</Description> 104 | <DisplayName>localuser</DisplayName> 105 | <Group>administrators</Group> 106 | <Name>localuser</Name> 107 | </LocalAccount> 108 | </LocalAccounts> 109 | </UserAccounts> 110 | <OOBE> 111 | <HideEULAPage>true</HideEULAPage> 112 | <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> 113 | <NetworkLocation>Home</NetworkLocation> 114 | <ProtectYourPC>1</ProtectYourPC> 115 | </OOBE> 116 | <AutoLogon> 117 | <Password> 118 | <Value>localuser-10</Value> 119 | <PlainText>true</PlainText> 120 | </Password> 121 | <Username>localuser</Username> 122 | <Enabled>true</Enabled> 123 | </AutoLogon> 124 | <FirstLogonCommands> 125 | <SynchronousCommand wcm:action="add"> 126 | <CommandLine>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine> 127 | <Description>Set Execution Policy 64 Bit</Description> 128 | <Order>1</Order> 129 | <RequiresUserInput>true</RequiresUserInput> 130 | </SynchronousCommand> 131 | <SynchronousCommand wcm:action="add"> 132 | <CommandLine>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\bootstrap-win.ps1</CommandLine> 133 | <Description>Bootstrap Windows</Description> 134 | <Order>2</Order> 135 | <RequiresUserInput>true</RequiresUserInput> 136 | </SynchronousCommand> 137 | </FirstLogonCommands> 138 | <ShowWindowsLive>false</ShowWindowsLive> 139 | </component> 140 | </settings> 141 | <settings pass="specialize"> 142 | <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> 143 | <OEMInformation> 144 | <HelpCustomized>false</HelpCustomized> 145 | </OEMInformation> 146 | <!-- Rename computer here. --> 147 | <ComputerName>localuser-10</ComputerName> 148 | <TimeZone>Coordinated Universal Time</TimeZone> 149 | <RegisteredOwner/> 150 | </component> 151 | <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> 152 | <SkipAutoActivation>true</SkipAutoActivation> 153 | </component> 154 | </settings> 155 | </unattend> 156 | -------------------------------------------------------------------------------- /Win10.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": { 3 | "blob_webserver": "{{env `BLOB_WEBSERVER`}}", 4 | "localuser_win_pass": "{{env `LOCALUSER_WIN_PASS`}}" 5 | }, 6 | "builders": [ 7 | { 8 | "type": "vmware-iso", 9 | "communicator": "winrm", 10 | "skip_compaction": "false", 11 | "output_directory": "VM/Win10-vmware", 12 | "vm_name": "Win10", 13 | "vmdk_name": "Win10", 14 | "iso_url": "ISO/RELEASE_CLIENTENTERPRISE_OEM_X64FRE_EN-US.ISO", 15 | "iso_checksum_type": "sha256", 16 | "iso_checksum": "65de98708a7016d76e1a25ae387f64da8a4e9c9d4f165bea1711d6872330316a", 17 | "boot_wait": "6m", 18 | "winrm_username": "administrator", 19 | "winrm_password": "{{user `localuser_win_pass`}}", 20 | "winrm_timeout": "2h", 21 | "shutdown_command": "shutdown /s /t 5 /f /d p:4:1", 22 | "shutdown_timeout": "5m", 23 | "guest_os_type": "windows9-64", 24 | "disk_size": "20480", 25 | "disk_type_id": "0", 26 | "floppy_files": [ 27 | "answer_files/vmw/10/Autounattend.xml", 28 | "FILES/pvscsi", 29 | "scripts/bootstrap-win.ps1", 30 | "FILES/vmxnet3" 31 | ], 32 | "headless": false, 33 | "vmx_data": { 34 | "ethernet0.virtualdev": "vmxnet3", 35 | "virtualhw.productcompatibility": "esx", 36 | "virtualhw.version": "10", 37 | "vcpu.hotadd": "TRUE", 38 | "mem.hotadd": "TRUE", 39 | "memsize": "4096", 40 | "scsi0.virtualDev": "pvscsi", 41 | "numvcpus": "2", 42 | "cpuid.coresPerSocket": "2", 43 | "hypervisor.cpuid.v1": "FALSE", 44 | "tools.upgrade.policy": "manual", 45 | "tools.syncTime": "0", 46 | "time.synchronize.continue": "1", 47 | "time.synchronize.restore": "1", 48 | "time.synchronize.resume.disk": "1", 49 | "time.synchronize.shrink": "1", 50 | "time.synchronize.tools.startup": "1", 51 | "time.synchronize.tools.enable": "1", 52 | "time.synchronize.resume.host": "1" 53 | }, 54 | "vmx_data_post": { 55 | "memsize": "4096", 56 | "numvcpus": "1", 57 | "cpuid.coresPerSocket": "1", 58 | "ide1:0.startConnected": "FALSE", 59 | "ide1:0.deviceType": "atapi-cdrom", 60 | "ide1:0.fileName": "cdrom0", 61 | "ide1:0.present": "TRUE" 62 | } 63 | }, 64 | { 65 | "type": "qemu", 66 | "communicator": "winrm", 67 | "winrm_port": "5985", 68 | "skip_compaction": "false", 69 | "output_directory": "VM/Win10-qemu", 70 | "format": "qcow2", 71 | "accelerator": "kvm", 72 | "qemuargs": [ 73 | [ 74 | "-m", 75 | "4096" 76 | ], 77 | [ 78 | "-usbdevice", 79 | "tablet" 80 | ], 81 | [ 82 | "-smp", 83 | "2" 84 | ], 85 | [ 86 | "-cpu", 87 | "Westmere" 88 | ] 89 | ], 90 | "net_device": "virtio-net", 91 | "disk_interface": "virtio-scsi", 92 | "disk_cache": "unsafe", 93 | "vm_name": "Win10.qcow2", 94 | "iso_url": "ISO/RELEASE_CLIENTENTERPRISE_OEM_X64FRE_EN-US.ISO", 95 | "iso_checksum_type": "sha256", 96 | "iso_checksum": "65de98708a7016d76e1a25ae387f64da8a4e9c9d4f165bea1711d6872330316a", 97 | "boot_wait": "6m", 98 | "winrm_username": "administrator", 99 | "winrm_password": "{{user `localuser_win_pass`}}", 100 | "winrm_timeout": "2h", 101 | "shutdown_command": "exit 0", 102 | "shutdown_timeout": "30m", 103 | "disk_size": "20480", 104 | "floppy_files": [ 105 | "answer_files/qemu/10/Autounattend.xml", 106 | "FILES/virtio-win/Win8.1/", 107 | "scripts/bootstrap-win.ps1" 108 | ], 109 | "headless": false 110 | } 111 | ], 112 | "provisioners": [ 113 | { 114 | "type": "file", 115 | "only": [ 116 | "vmware-iso" 117 | ], 118 | "pause_before": "5m", 119 | "source": "scripts/SetupComplete-vmw.ps1", 120 | "destination": "C:/Windows/Temp/SetupComplete.ps1" 121 | }, 122 | { 123 | "type": "file", 124 | "only": [ 125 | "qemu" 126 | ], 127 | "source": "scripts/SetupComplete-qemu.ps1", 128 | "destination": "C:/Windows/Temp/SetupComplete.ps1" 129 | }, 130 | { 131 | "type": "powershell", 132 | "only": [ 133 | "vmware-iso" 134 | ], 135 | "elevated_user": "administrator", 136 | "elevated_password": "{{user `localuser_win_pass`}}", 137 | "script": "scripts/tools-winrm.ps1", 138 | "remote_path": "c:/Windows/temp/tools-winrm.ps1" 139 | }, 140 | { 141 | "pause_before": "5m", 142 | "only": [ 143 | "vmware-iso" 144 | ], 145 | "restart_timeout": "1h", 146 | "type": "windows-restart" 147 | }, 148 | { 149 | "type": "file", 150 | "only": [ 151 | "qemu" 152 | ], 153 | "source": "cloud_init/cloudbase-init.conf", 154 | "destination": "C:/Windows/Temp/cloudbase-init.conf" 155 | }, 156 | { 157 | "type": "file", 158 | "only": [ 159 | "qemu" 160 | ], 161 | "source": "cloud_init/cloudbase-init-unattend.conf", 162 | "destination": "C:/Windows/Temp/cloudbase-init-unattend.conf" 163 | }, 164 | { 165 | "type": "file", 166 | "only": [ 167 | "qemu" 168 | ], 169 | "source": "cloud_init/cloudbase-init-firstboot.ps1", 170 | "destination": "C:/Windows/Temp/cloudbase-init-firstboot.ps1" 171 | }, 172 | { 173 | "type": "powershell", 174 | "elevated_user": "administrator", 175 | "elevated_password": "{{user `localuser_win_pass`}}", 176 | "only": [ 177 | "qemu" 178 | ], 179 | "script": "scripts/cloudbase-init.ps1", 180 | "remote_path": "c:/Windows/temp/cloudbase-init.ps1" 181 | }, 182 | { 183 | "type": "windows-restart", 184 | "restart_timeout": "10h" 185 | }, 186 | { 187 | "type": "powershell", 188 | "elevated_user": "administrator", 189 | "elevated_password": "{{user `localuser_win_pass`}}", 190 | "environment_vars": [ 191 | "wsus_server={{user `wsus_server`}}", 192 | "wsus_group={{user `wsus_group`}}" 193 | ], 194 | "remote_path": "c:/Windows/temp/windows-update-winrm.ps1", 195 | "script": "scripts/windows-update-winrm.ps1" 196 | }, 197 | { 198 | "type": "windows-restart", 199 | "restart_timeout": "10h" 200 | }, 201 | { 202 | "type": "powershell", 203 | "inline": "get-content c:/windows/temp/windows-update-winrm.log | format-wide | write-output", 204 | "remote_path": "c:/Windows/temp/get_wulist.ps1" 205 | }, 206 | { 207 | "type": "powershell", 208 | "elevated_user": "administrator", 209 | "elevated_password": "{{user `localuser_win_pass`}}", 210 | "inline": "net user localuser {{user `localuser_win_pass`}}", 211 | "remote_path": "c:/Windows/temp/setpass.ps1" 212 | }, 213 | { 214 | "type": "powershell", 215 | "elevated_user": "administrator", 216 | "start_retry_timeout": "8h", 217 | "elevated_password": "{{user `localuser_win_pass`}}", 218 | "script": "scripts/configure-windows-local-policy.ps1", 219 | "remote_path": "c:/Windows/temp/configure-windows-local-policy.ps1" 220 | }, 221 | { 222 | "type": "powershell", 223 | "elevated_user": "administrator", 224 | "start_retry_timeout": "8h", 225 | "elevated_password": "{{user `localuser_win_pass`}}", 226 | "script": "scripts/configure-win.ps1", 227 | "remote_path": "c:/Windows/temp/configure-win.ps1" 228 | }, 229 | { 230 | "type": "powershell", 231 | "elevated_user": "administrator", 232 | "start_retry_timeout": "8h", 233 | "elevated_password": "{{user `localuser_win_pass`}}", 234 | "script": "scripts/cleanup-compact.ps1", 235 | "remote_path": "c:/Windows/temp/cleanup-compact.ps1" 236 | }, 237 | { 238 | "elevated_user": "administrator", 239 | "elevated_password": "{{user `localuser_win_pass`}}", 240 | "type": "powershell", 241 | "inline": "get-childitem -Recurse \"C:/Windows/Panther\" | remove-item -Recurse -Force -ErrorAction SilentlyContinue", 242 | "remote_path": "c:/Windows/temp/clean_panther.ps1" 243 | }, 244 | { 245 | "elevated_user": "administrator", 246 | "elevated_password": "{{user `localuser_win_pass`}}", 247 | "type": "powershell", 248 | "inline": "get-childitem -Recurse \"C:/Windows/Temp\" | remove-item -Recurse -Force -ErrorAction SilentlyContinue", 249 | "remote_path": "c:/Windows/temp/clean_temp.ps1" 250 | }, 251 | { 252 | "elevated_user": "administrator", 253 | "elevated_password": "{{user `localuser_win_pass`}}", 254 | "type": "powershell", 255 | "inline": "start-process powershell -argumentlist \"Get-ScheduledTask | Where TaskPath -eq '\\' | Unregister-ScheduledTask -Confirm:`$false\"", 256 | "remote_path": "c:/Windows/temp/purge_tasks.ps1" 257 | }, 258 | { 259 | "elevated_user": "administrator", 260 | "elevated_password": "{{user `localuser_win_pass`}}", 261 | "only": [ 262 | "qemu" 263 | ], 264 | "type": "powershell", 265 | "script": "scripts/sysprep-shutdown.ps1", 266 | "remote_path": "c:/Windows/temp/sysprep-shutdown.ps1" 267 | } 268 | ] 269 | } 270 | -------------------------------------------------------------------------------- /answer_files/qemu/10/Autounattend.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <unattend xmlns="urn:schemas-microsoft-com:unattend"> 3 | <servicing/> 4 | <settings pass="windowsPE"> 5 | <component name="Microsoft-Windows-PnpCustomizationsWinPE" 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"> 6 | <DriverPaths> 7 | <PathAndCredentials wcm:keyValue="1" wcm:action="add"> 8 | <Path>a:\</Path> 9 | </PathAndCredentials> 10 | </DriverPaths> 11 | </component> 12 | <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> 13 | <DiskConfiguration> 14 | <Disk wcm:action="add"> 15 | <CreatePartitions> 16 | <CreatePartition wcm:action="add"> 17 | <Type>Primary</Type> 18 | <Order>1</Order> 19 | <Size>350</Size> 20 | </CreatePartition> 21 | <CreatePartition wcm:action="add"> 22 | <Order>2</Order> 23 | <Type>Primary</Type> 24 | <Extend>true</Extend> 25 | </CreatePartition> 26 | </CreatePartitions> 27 | <ModifyPartitions> 28 | <ModifyPartition wcm:action="add"> 29 | <Active>true</Active> 30 | <Format>NTFS</Format> 31 | <Label>boot</Label> 32 | <Order>1</Order> 33 | <PartitionID>1</PartitionID> 34 | </ModifyPartition> 35 | <ModifyPartition wcm:action="add"> 36 | <Format>NTFS</Format> 37 | <Label>Windows 10</Label> 38 | <Letter>C</Letter> 39 | <Order>2</Order> 40 | <PartitionID>2</PartitionID> 41 | </ModifyPartition> 42 | </ModifyPartitions> 43 | <DiskID>0</DiskID> 44 | <WillWipeDisk>true</WillWipeDisk> 45 | </Disk> 46 | </DiskConfiguration> 47 | <UserData> 48 | <AcceptEula>true</AcceptEula> 49 | <FullName>localuser Administrator</FullName> 50 | <Organization>localuser</Organization> 51 | <!-- Product Key from http://technet.microsoft.com/en-us/library/ff793406.aspx --> 52 | <ProductKey> 53 | <Key>NPPR9-FWDCX-D2C8J-H872K-2YT43</Key> 54 | <WillShowUI>Never</WillShowUI> 55 | </ProductKey> 56 | </UserData> 57 | <ImageInstall> 58 | <OSImage> 59 | <InstallTo> 60 | <DiskID>0</DiskID> 61 | <PartitionID>2</PartitionID> 62 | </InstallTo> 63 | <WillShowUI>OnError</WillShowUI> 64 | <InstallToAvailablePartition>false</InstallToAvailablePartition> 65 | <InstallFrom> 66 | <MetaData wcm:action="add"> 67 | <Key>/IMAGE/NAME</Key> 68 | <Value>Windows 10 Enterprise</Value> 69 | </MetaData> 70 | </InstallFrom> 71 | </OSImage> 72 | </ImageInstall> 73 | </component> 74 | <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> 75 | <SetupUILanguage> 76 | <UILanguage>en-US</UILanguage> 77 | </SetupUILanguage> 78 | <InputLocale>en-US</InputLocale> 79 | <SystemLocale>en-US</SystemLocale> 80 | <UILanguage>en-US</UILanguage> 81 | <UILanguageFallback>en-US</UILanguageFallback> 82 | <UserLocale>en-US</UserLocale> 83 | </component> 84 | </settings> 85 | <settings pass="offlineServicing"> 86 | <component name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> 87 | <EnableLUA>true</EnableLUA> 88 | </component> 89 | </settings> 90 | <settings pass="oobeSystem"> 91 | <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> 92 | <UserAccounts> 93 | <AdministratorPassword> 94 | <Value>localuser-10</Value> 95 | <PlainText>true</PlainText> 96 | </AdministratorPassword> 97 | <LocalAccounts> 98 | <LocalAccount wcm:action="add"> 99 | <Password> 100 | <Value>localuser-10</Value> 101 | <PlainText>true</PlainText> 102 | </Password> 103 | <Description>localuser User</Description> 104 | <DisplayName>localuser</DisplayName> 105 | <Group>administrators</Group> 106 | <Name>localuser</Name> 107 | </LocalAccount> 108 | </LocalAccounts> 109 | </UserAccounts> 110 | <OOBE> 111 | <HideEULAPage>true</HideEULAPage> 112 | <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> 113 | <NetworkLocation>Home</NetworkLocation> 114 | <ProtectYourPC>1</ProtectYourPC> 115 | </OOBE> 116 | <AutoLogon> 117 | <Password> 118 | <Value>localuser-10</Value> 119 | <PlainText>true</PlainText> 120 | </Password> 121 | <Username>localuser</Username> 122 | <Enabled>true</Enabled> 123 | </AutoLogon> 124 | <FirstLogonCommands> 125 | <SynchronousCommand wcm:action="add"> 126 | <CommandLine>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine> 127 | <Description>Set Execution Policy 64 Bit</Description> 128 | <Order>1</Order> 129 | <RequiresUserInput>true</RequiresUserInput> 130 | </SynchronousCommand> 131 | <SynchronousCommand wcm:action="add"> 132 | <CommandLine>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\bootstrap-win.ps1</CommandLine> 133 | <Description>Bootstrap Windows</Description> 134 | <Order>2</Order> 135 | <RequiresUserInput>true</RequiresUserInput> 136 | </SynchronousCommand> 137 | <SynchronousCommand wcm:action="add"> 138 | <CommandLine>cmd.exe /c pnputil -i -a a:\netkvm.inf</CommandLine> 139 | <Order>96</Order> 140 | <Description>Install netkvm</Description> 141 | </SynchronousCommand> 142 | <SynchronousCommand wcm:action="add"> 143 | <CommandLine>cmd.exe /c pnputil -i -a a:\vioscsi.inf</CommandLine> 144 | <Order>97</Order> 145 | <Description>Install netkvm</Description> 146 | </SynchronousCommand> 147 | <SynchronousCommand wcm:action="add"> 148 | <CommandLine>cmd.exe /c pnputil -i -a a:\viostor.inf</CommandLine> 149 | <Order>98</Order> 150 | <Description>Install netkvm</Description> 151 | </SynchronousCommand> 152 | </FirstLogonCommands> 153 | <ShowWindowsLive>false</ShowWindowsLive> 154 | </component> 155 | </settings> 156 | <settings pass="specialize"> 157 | <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> 158 | <OEMInformation> 159 | <HelpCustomized>false</HelpCustomized> 160 | </OEMInformation> 161 | <!-- Rename computer here. --> 162 | <ComputerName>localuser-10</ComputerName> 163 | <TimeZone>Pacific Standard Time</TimeZone> 164 | <RegisteredOwner/> 165 | </component> 166 | <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> 167 | <SkipAutoActivation>true</SkipAutoActivation> 168 | </component> 169 | </settings> 170 | <cpi:offlineImage xmlns:cpi="urn:schemas-microsoft-com:cpi" cpi:source="catalog:d:/sources/install_windows 7 ENTERPRISE.clg"/> 171 | </unattend> 172 | --------------------------------------------------------------------------------