SolidCP Update Script (PowerShell)
18 - 07 - 2016
How to setup HyperV 2012r2 Server.
31 - 08 - 2016

What we will cover

This manual will show how to create a Windows Server 2012r2 HyperV template. The process will focus on Windows Server 2012R2 but the same guide can be used for other versions such as Windows Server 2008R2 but will require a different sysprep file.

This guide will also assume the following:

  • HyperV is setup and running
  • You have the SolidCP Portal/Enterprise/Server setup and the sever running HyperV has been added but the provider for HyperV2012 is not configured.

Master Virtual Machine

The Master machine is made for you to create templates from. It will have all the updates installed along with the VMConfig software.

 

Create a new machine from inside the HyperV Manager. We generally try to keep the same naming scheme so you know which virtual machine is doing what. This is: Master – [(INSTALLED_APP_1, INSTALLED_APP_2, ...)]

In this guide we will be installing 2012R2 DC so it will be called: Master - Win Server 2012R2 DC

Select a useful location to install the VM into. We recommend that you make a SCP Template location with the master files in.

Hard Drive Size: We recommend you keep this as small as possible as when deployed SolidCP can increase the size but not decrease.

 

Install the Windows operating system as you normally would and download all the updates and programs you require for the template.

 

 

Guest OS Prep

Now you have your Master Virtual Machine setup with the applications you require and programs there are a few other tasks needed:

Enable Remote Desktop: In Server Manager goto Local Server. Enable Remote Desktop by clicking disabled next to the item and then select Allow Remote connections to this computer. You may also wasnt to disable the tick box for Network Level Authentication.

Set Password Policy:

Open Administrative tools > Local   Security Policy > Account Policies > Password Policy

 

Set “Enforce password history” and choose   0.

Set “Maximum password age” and choose 0.

Set “Minimum password age” and choose 0.

Set “Minimum password length” and choose   some desired values. Do not forget to adjust  Control Panel Virtual Private   Servers Policy to the same value.

Set “Password must meet complexity   requirements” and choose Disabled.

Keep “Store passwords using reversible   encryption” with default Disable settings.

SCP VMConfig

The SolidCP Config tool is designed to allow you full control of the Virtual Machine from within SolidCP.

This includes the following functions:

  • Computer name change
  • Administrator Password
  • Network adapter Configuration
  • Real-time Statics

How to install

To install the VMConfig tool you will need to download the files from https://solidcp.com/downloads/ under the tools tab.

  1. Extract the files to C:\Program Files\ on the Master template machine.
  2. Rename the folder to VMConfig.
  3. Open the newly created VMConfig folder and go to Properties of the SolidCP.VmConfig.exe file.
  4. Click Unblock on the general tab if it is shown.
  5. Open CMD - RunAS.
  6. Goto the folder you installed the files in CMD. (For example using CD "C:\Program Files\VMConfig").
  7. Run the install.bat in the installer.
  8. You will now see the SolidCP VM Configuration service in the Services list.

Backup your VHD.

 Shut-down the OS using power off inside the windows guest and make a copy of the VHD/VHDX. This will be your pre-sysprep image. You will need to copy this file and not snapshot. A snapshot will cause issues so they should not be used on the master image.

Sysprep

The sysprep utility is part of Windows which makes the install of Windows unique and causes no issues when using a Domain by creating a new SIDs.

Creating Answer file

To create an answer file you will need to install the Windows System Image Manager (WISM) tool which is part of the Windows Automated Installation Kit (WAIK). You will want to make one for your customer base like if you need a different language.

There is one I have used in the past (Called 2012r2DC-Unattend.xml)

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">

  <!-- Template variables -->
  <ad:set name="architecture" value="amd64" /> <!-- "x86" for 32-bit OS editions and "amd64" for 64-bit OS editions -->

    <settings pass="generalize">
        <component name="Microsoft-Windows-ServerManager-SvrMgrNc" processorArchitecture="#architecture#" 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>
        <component name="Microsoft-Windows-OutOfBoxExperience" processorArchitecture="#architecture#" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DoNotOpenInitialConfigurationTasksAtLogon>true</DoNotOpenInitialConfigurationTasksAtLogon>
        </component>
    </settings>
    <settings pass="specialize">
        <component name="Microsoft-Windows-IE-ESC" processorArchitecture="#architecture#" 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>
            <IEHardenUser>false</IEHardenUser>
        </component>
        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="#architecture#" 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>#vm.Hostname.ToUpper()#</ComputerName>
			<RegisteredOwner>#user.FirstName# #user.LastName#</RegisteredOwner>
			<RegisteredOrganization>#user.CompanyName#</RegisteredOrganization>
            <TimeZone>W. Europe Standard Time</TimeZone>
            <ProductKey>Y4TGP-NPTV9-HTC2H-7MGQ3-DV4TW</ProductKey>
        </component>
        <component name="Microsoft-Windows-TCPIP" processorArchitecture="#architecture#" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <Interfaces>

			        <!-- External network -->
        <ad:if test="#isnotempty(external_nic.MacAddress)#">
          <Interface wcm:action="add">
            <Identifier>#external_nic.MacAddress#</Identifier>
            <Ipv4Settings>
              <DhcpEnabled>#external_nic.IsDHCP.ToString().ToLower()#</DhcpEnabled>
            </Ipv4Settings>
            <ad:if test="#not(external_nic.IsDHCP)#">
              <UnicastIpAddresses>
                <ad:foreach collection="#external_nic.IPAddresses#" var="ip" index="i">
                  <IpAddress wcm:action="add" wcm:keyValue="#i#">#ip.IPAddress#/#ip.SubnetMaskCidr#</IpAddress>
                </ad:foreach>
              </UnicastIpAddresses>
            </ad:if>
            <ad:if test="#isnotempty(external_nic.DefaultGateway)#">
              <Routes>
                <Route wcm:action="add">
                  <Identifier>0</Identifier>
                  <Prefix>0.0.0.0/0</Prefix>
                  <NextHopAddress>#external_nic.DefaultGateway#</NextHopAddress>
                  <Metric>20</Metric>
                </Route>
              </Routes>
            </ad:if>
          </Interface>
        </ad:if>

        <!-- Management network -->
        <ad:if test="#isnotempty(management_nic.MacAddress)#">
          <Interface wcm:action="add">
            <Identifier>#management_nic.MacAddress#</Identifier>
            <Ipv4Settings>
              <DhcpEnabled>#management_nic.IsDHCP.ToString().ToLower()#</DhcpEnabled>
            </Ipv4Settings>
            <ad:if test="#not(management_nic.IsDHCP)#">
              <UnicastIpAddresses>
                <ad:foreach collection="#management_nic.IPAddresses#" var="ip" index="i">
                  <IpAddress wcm:action="add" wcm:keyValue="#i#">#ip.IPAddress#/#ip.SubnetMaskCidr#</IpAddress>
                </ad:foreach>
              </UnicastIpAddresses>
            </ad:if>
            <ad:if test="#isnotempty(management_nic.DefaultGateway)#">
              <Routes>
                <Route wcm:action="add">
                  <Identifier>0</Identifier>
                  <Prefix>0.0.0.0/0</Prefix>
                  <NextHopAddress>#management_nic.DefaultGateway#</NextHopAddress>
                  <Metric>20</Metric>
                </Route>
              </Routes>
            </ad:if>
          </Interface>
        </ad:if>

        <!-- Private network -->
        <ad:if test="#isnotempty(private_nic.MacAddress)#">
          <Interface wcm:action="add">
            <Identifier>#private_nic.MacAddress#</Identifier>
            <Ipv4Settings>
              <DhcpEnabled>#private_nic.IsDHCP.ToString().ToLower()#</DhcpEnabled>
            </Ipv4Settings>
            <ad:if test="#not(private_nic.IsDHCP)#">
              <UnicastIpAddresses>
                <ad:foreach collection="#private_nic.IPAddresses#" var="ip" index="i">
                  <IpAddress wcm:action="add" wcm:keyValue="#i#">#ip.IPAddress#/#ip.SubnetMaskCidr#</IpAddress>
                </ad:foreach>
              </UnicastIpAddresses>
            </ad:if>
            <ad:if test="#isnotempty(private_nic.DefaultGateway)#">
              <Routes>
                <Route wcm:action="add">
                  <Identifier>0</Identifier>
                  <Prefix>0.0.0.0/0</Prefix>
                  <NextHopAddress>#private_nic.DefaultGateway#</NextHopAddress>
                  <Metric>20</Metric>
                </Route>
              </Routes>
            </ad:if>
          </Interface>
        </ad:if>

        </Interfaces>
        </component>
        <component name="Microsoft-Windows-DNS-Client" processorArchitecture="#architecture#" 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>#vm.Domain#</DNSDomain>
      <Interfaces>

        <!-- External network DNS settings -->
        <ad:if test="#isnotempty(external_nic.MacAddress) and (isnotempty(external_nic.PreferredNameServer) or isnotempty(external_nic.AlternateNameServer))#">
          <Interface wcm:action="add">
            <Identifier>#external_nic.MacAddress#</Identifier>
            <DNSServerSearchOrder>
              <ad:if test="#isnotempty(external_nic.PreferredNameServer)#">
                <IpAddress wcm:action="add" wcm:keyValue="1">#external_nic.PreferredNameServer#</IpAddress>
              </ad:if>
              <ad:if test="#isnotempty(external_nic.AlternateNameServer)#">
                <IpAddress wcm:action="add" wcm:keyValue="2">#external_nic.AlternateNameServer#</IpAddress>
              </ad:if>
            </DNSServerSearchOrder>
          </Interface>
        </ad:if>

        <!-- Management network DNS settings -->
        <ad:if test="#isnotempty(management_nic.MacAddress) and (isnotempty(management_nic.PreferredNameServer) or isnotempty(management_nic.AlternateNameServer))#">
          <Interface wcm:action="add">
            <Identifier>#management_nic.MacAddress#</Identifier>
            <DNSServerSearchOrder>
              <ad:if test="#isnotempty(management_nic.PreferredNameServer)#">
                <IpAddress wcm:action="add" wcm:keyValue="1">#management_nic.PreferredNameServer#</IpAddress>
              </ad:if>
              <ad:if test="#isnotempty(management_nic.AlternateNameServer)#">
                <IpAddress wcm:action="add" wcm:keyValue="2">#management_nic.AlternateNameServer#</IpAddress>
              </ad:if>
            </DNSServerSearchOrder>
          </Interface>
        </ad:if>

        <!-- Private network DNS settings -->
        <ad:if test="#isnotempty(private_nic.MacAddress) and (isnotempty(private_nic.PreferredNameServer) or isnotempty(private_nic.AlternateNameServer))#">
          <Interface wcm:action="add">
            <Identifier>#private_nic.MacAddress#</Identifier>
            <DNSServerSearchOrder>
              <ad:if test="#isnotempty(private_nic.PreferredNameServer)#">
                <IpAddress wcm:action="add" wcm:keyValue="1">#private_nic.PreferredNameServer#</IpAddress>
              </ad:if>
              <ad:if test="#isnotempty(private_nic.AlternateNameServer)#">
                <IpAddress wcm:action="add" wcm:keyValue="2">#private_nic.AlternateNameServer#</IpAddress>
              </ad:if>
            </DNSServerSearchOrder>
          </Interface>
        </ad:if>
      </Interfaces>			
	 </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="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">
        <FirewallGroups>
            <FirewallGroup wcm:action="add" wcm:keyValue="EnableRemoteDesktop">
                <Active>true</Active>
                <Group>Remote Desktop</Group>
                <Profile>all</Profile>
            </FirewallGroup>
			<FirewallGroup wcm:action="add" wcm:keyValue="EnableRemoteDesktopDE">
                <Active>true</Active>
                <Group>Remotedesktop</Group>
                <Profile>all</Profile>
            </FirewallGroup>
        </FirewallGroups>
    </component>
    </settings>
    <settings pass="oobeSystem">
        <component name="Microsoft-Windows-International-Core" processorArchitecture="#architecture#" 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>
            <UILanguage>en-US</UILanguage>
            <UserLocale>en-US</UserLocale>
        </component>
        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="#architecture#" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <OOBE>
                <HideEULAPage>true</HideEULAPage>
                <ProtectYourPC>1</ProtectYourPC>
                <NetworkLocation>Work</NetworkLocation>
            </OOBE>
            <UserAccounts>
				<!-- Administrator account password -->
				<AdministratorPassword>
					<Value>#vm.AdministratorPassword#</Value>
					<PlainText>true</PlainText>
                </AdministratorPassword>
            </UserAccounts>
        </component>
    </settings>
    <cpi:offlineImage cpi:source="catalog:c:/install_windows server 2012 r2 serverdatacenter.clg" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>

In the sysprep file you will need to change the TimeZone and Product key (Unless you are using the 2012R2 DC AVMA key)/ Server version name.

 

There is an unattend.xml which is used by the OS to firstly run the sysprep command against:

 

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
    <settings pass="generalize">
        <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>
        <component name="Microsoft-Windows-OutOfBoxExperience" 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">
            <DoNotOpenInitialConfigurationTasksAtLogon>true</DoNotOpenInitialConfigurationTasksAtLogon>
        </component>
    </settings>
    <cpi:offlineImage cpi:source="catalog:c:/install_windows server 2012 r2 serverdatacenter.clg" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>

Now to make sure the VM is ready for the sysprep:

  • The VM has been updated and software required has been installed.
  • The VMConfig tool has been installed
  • All Network config has been reset back to DHCP

 

You need to run the sysprep generalise command with the shorter XML file located above. You copy the file as unattend.xml to %windir%\system32\sysprep ready to generalise the Windows Install

Open a runas cmd so you can run the commands below:

cd c:\Windows\System32\sysprep
sysprep /generalize /oobe /shutdown /unattend:unattend.xml

The virtual machine will now shutdown. DO NOT START.

Mount the VHD(X) file and replace the unattend.xml file with the one called 2012r2DC-Unattend.xml (You will need to rename this).

SolidCP OS Templates

In the SolidCP OS Templates you can give it a path on the server. This will be the path that the vhd/vhdx will be stored.

Name: Give it a useful name that everyone will see in SolidCP.

File Name (With Extension): This is the vhdx file such as Win2012r2DC.vhdx

Index of the volume to expand: This is generally set to 1

Sysprep files: \Windows\System32\sysprep\unattend.xml

Use legacy adapter: Not Ticked

Can set a computer name: Ticked

Can set an Administrator password: Ticked

Can set IP addresses: Ticked

Change Administrator Username

We have been asked about if its possible to change the Administrator username due to various security issues and brute force attempts on this default account.The below method will ensure SolidCP can still change this password.

 

To change this as part of the Sysprep you will need to make the following on your Template image (replace Sysadmin with the username you want to use):

 

\WINDOWS\Setup\Scripts\setupcomplete.cmd

 

With the following code:

wmic useraccount where name='Administrator' call rename name='Sysadmin'
Trevor Robinson
Trevor Robinson
- CTO of Key4ce.
- More then 10 years of experience with Linux and Unix.
- More then 10 years of experience with Windows Servers.
- Open source enthusiast.

Key4ce - IT Professionals :: https://key4ce.com

Leave a Reply