Monday, June 2, 2014

Using Powershell to provision hyper-v VMs.

Hello folks,  I want to share with you this piece of script.
My goal is to make a provisioning script for VM that would take care of :

  • Configuring basic VM setup such as RAM, CPUs for each VM
  • Deploying multiple VM based on a sysprep master.
  • Configuring network and performing domain joins and AD setup
  • Running post sysprep provisioning tasks, such as role and feature installations.

The scripts are provided as is, without warranty, and may be improved in the future.
At the present moment, they are alpha quality.

Use at your own risk.

There are several pieces of scripts to make this all work :

#SERVER SCRIPT  : to be put on the provisioning hypervisor (createvm.ps1)
#CLIENT SCRIPT 1 : save it as canalwr2.ps1 under c:\scripts
#CLIENT SCRIPT 2 : save it as winrmconf.ps1 under c:\scripts
#CLIENT SCHEDULED TASK  : to be put imported on the sysprepped VM before sysprep
#DATA : Q:\securestring.txt : contains the credentials to access the VM through a remote powershell session (place it along the server script so it can be accessed by it)
#UNATTEND.XML : to be used as a sysprep argument to configure the syprep process properly, need some edits with Windows AIK. save it in c:\scripts
#SYSPREP COMMAND : to run sysprep


Basically you put the server script on the hypervisor, and configure the pathes so it can access your master VHDs
Before launching it, you will need  to sysprep a VM using the supplied unattend.xml and place the client scripts in c:\scripts and register a scheduled task using the administrator credentials and use the password that will be set by sysprep (so it will have a chance to run).
Once the VM is ready, sysprep it with the command supplied at the end of this article and export the master VHD you just created once the vm is stopped. It will be the reference image.

On the hypervisor, you can invoke the creation of  VMs with the following command :

createvm.ps1 <OS_MASTER_MONIKER> < NUM_OF_VMs> <RAM_IN_GB> <CORES>

it is a bit silly that you cannot customize the parameters to have different hardware setups for each VM but I am working on it...

enjoy, and comment.

#########################################################
#SERVER SCRIPT : (createvm.ps1)
#########################################################

 param (
    [string]$serverformula =  $(throw "-server formula is required.")
    #[string]$domainformula = $(throw "-domainformula is required."),
    #[string]$roleformula = $(throw "-roleformula is required.")
 )


$runINSTVM = {
             param($a, $b, $c, $d)

             #Function Instantiate-VM($OSName2, $NumOfVMs2, $RAM2, $Cores2)
             $OSName2 = $a
             $NumOfVMs2  =  $b
             $RAM2 = $c
             $Cores2 = $d

             echo $OSName2 | Out-File -FilePath "c:\Log$OSName2.txt" -Append -width 50

             $runFACVM = {
                        param($e, $f, $g, $h)

                        $OSName = $e
                        $VMIndex = $f
                        $RAM = $g
                        $Cores = $h
                        $i = 0

                        [string]$vmName = $OSName + "_" + $VMIndex;

                        Function GetVMInfo($PipeName)
                            {  
                                $HashVMInfo = @{}
                                do {
                                   
                                    $pipe=new-object System.IO.Pipes.NamedPipeClientStream -ArgumentList ".",$PipeName,1,0;
                                    echo "Created client side of $PipeName" |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;

                                    $pipe.Connect();

                                    echo "Connected client side of $PipeName" |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;

                                    $sr = new-object System.IO.StreamReader($pipe);

                                    echo "Connected stream reader" |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;

                                    $IPaddr = $null;
                                    $CompN = $null;


                                    do {
   
                                            echo "entering main loop" |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;
                                            $line = $sr.readline()
                                            $tmp1 = $line -match "#IPADDR=(\d+\.\d+\.\d+\.\d+)#"
                                            echo "matching ipaddr first" |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;

                                            if ($tmp1)
                                                {
                                                $IPaddr = $matches[1];
                                                $line = $sr.readline()
                                                $tmp2 = $line -match "#COMPN=([\d\w\-_]+)#"
                                                echo "matching compn next" |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;
                                                if ($tmp2)
                                                    {
                                                    $CompN = $matches[1];   
                                                    }
                                                }
                                            else
                                                {
                                                $tmp2 = $line -match "#COMPN=([\d\w\-_]+)#"
                                                if ($tmp2)
                                                    {
                                                    echo "matching compn first" |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;;
                                                    $CompN = $matches[1];
                                                    $line = $sr.readline()
                                                    $tmp1 = $line -match "#IPADDR=(\d+\.\d+\.\d+\.\d+)#"
                                                    if ($tmp1)
                                                        {
                                                        $IPaddr = $matches[1];
                                                        echo "matching ipaddr next" |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;;   
                                                        }
                                                    }
                                                }
                                            $i++;
                                            echo "incrementing i, $i $IPaddr $CompN" |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;
                                            start-sleep -Seconds 1;
                                        } while ([String]::Isnullorempty($IPaddr) -or [String]::Isnullorempty($CompN) -and ($i -le 10))

                                    echo $ipaddr |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;
                                    echo $CompN |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;

                                    $sr.Dispose();
                                    $pipe.Dispose();

                                    } while ([String]::Isnullorempty($IPaddr) -or [String]::Isnullorempty($CompN))
                           
                            $HashVMInfo.add("IPADDR",$ipaddr)
                            $HashVMInfo.add("COMPN",$CompN)
                            echo "Both values set : $ipaddr" |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;
                            echo "Both values set : $CompN" |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50;
                            return $HashVMInfo
                            } #Close function

                        #start-sleep -Seconds 10
 
                        #Set variables

                        echo $OSName $VMIndex | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50

                        $OSIDtoMasterVHDfilename = @{};

                        $OSIDtoMasterVHDfilename.Add("W2K8R2","MASTER-2K8R2-ENT-FR-VL-SP1-disk0.vhdx");
                        $OSIDtoMasterVHDfilename.Add("W2K3R2","MASTER-2K3R2-ENT-FR-VL-SP1-disk0.vhdx");
                        $OSIDtoMasterVHDfilename.Add("W2K12","MASTER-2K12-STD-FR-VL-disk0.vhdx");
                        $OSIDtoMasterVHDfilename.Add("W2K12R2","MASTER-2K12R2-DAT-FR-VL-disk0.vhdx");

                        [string]$vmSwitch = "VS1"; #Change this to your preferred NIC.
                        [string]$vmSwitch2 = "PROVISION"; #Change this to your preferred NIC.
                       
                        $OSVHD = $OSIDtoMasterVHDfilename.Get_Item($OSName);
                        [string]$parentVHD = "C:\Hyper-V\MASTERS\MASTER-2K8R2-ENT-FR-VL-SP1-AVT2-SYSPREP\Virtual Hard Disks\" + $OSVHD  #Change this to your preferred Parent VHD.
                        [string]$vmPath = "C:\ClusterStorage\Volume1";  #Change this to your preferred VM Store.           

                        [string]$vmMemory = concat($RAM, " GB")
                        <#
                        Trap [Exception]
                        {
                        Write-Host -BackgroundColor Red -ForegroundColor White "Error, The memory amount should be an integer!"
                        break
                        } #CloseTrap           

                        [int]$vmCPU = $Cores
                        Trap [Exception]
                        {
                        Write-Host -BackgroundColor Red -ForegroundColor White "Error, The memory amount should be an integer!"
                        break
                        } #CloseTrap           
                        #>

                        #Create Raw Virtual Machine
                        $logfile = "c:\logfile_" + $vmName + ".txt"
                        $NewVHD = $vmPath + "\" + $vmName + "-disk0.vhdx"
                        #New-VM -Name $vmName


                        #echo $OSName $VMIndex | Out-File -FilePath "c:\LogB$OSName$VMIndex.txt" -Append -width 50

                        New-VM -Name $vmName -Generation 2 -Path $vmPath -NoVHD | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                        Set-VMFirmware -VMName $vmName -EnableSecureBoot off
                        start-sleep -Seconds 5
                        Set-VMProcessor -VMName $vmName -Count 2 | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                        start-sleep -Seconds 5
                        Set-VMMemory -VMName $vmName -StartupBytes 2147483648 #| Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                        start-sleep -Seconds 5
                        Add-VMNetworkAdapter -VMName $vmName -SwitchName $vmSwitch | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50           
                        Add-VMNetworkAdapter -VMName $vmName -SwitchName $vmSwitch2 | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50        
                        Set-VMComPort -VMName $vmName -Number 1 -Path "\\.\pipe\$vmName" | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                        ##Create a Differencing VHD
                        ##New-VHD -VHDPaths $vmPath\$vmName.vhd -ParentVHDPath $parentVHD | Out-File -FilePath .\Log.txt -Append -width 50           
                        Copy-Item $parentVHD $NewVHD
                        ##Check if the VHD has been created and attach it on success
 
 
                        $VHDExists = Test-Path $NewVHD

                        if ($VHDExists -eq $True)
                            {
   
                            Add-VMHardDiskDrive -VMName $vmName -ControllerType "SCSI" -Path $NewVHD | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                            #Write-Host -BackgroundColor Green -ForegroundColor Black "Virtual Machine $vmName has been successfully created"            
                            echo "VM+DISK OK" | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                           
                            $snaploc = $vmPath + "\" + $vmName + "\Snapshots"
                            $smartpage = $vmPath + "\" + $vmName + "\SmartPaging"
                       
                            Set-VM -name $vmName -SnapshotFileLocation $snaploc -SmartPagingFilePath $smartpage
                            $bootorder = (Get-VMFirmware $vmName).BootOrder
                            $bootorder | fl Device |  Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                            $disk1 = $bootorder[2]
                            $net1 = $bootorder[0]
                            $net2 = $bootorder[1]
                            Set-VMFirmware -VMName $vmName -BootOrder $disk1,$net1,$net2
                           
                            } #Close If
                        else
                            {
                            #Write-Host -BackgroundColor Red -ForegroundColor White "It seems the disk creation job has not completed, attach it manually once it's done"
                            echo "VM+DISK PB" | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
   
                            } #Close Else
 
                        $InstallAD = {       }
                        $InstallExchange = { }
                        #$displaycomputername =
                        #                        { gc env:path | out-file -FilePath C:\scripts\remote-log.txt -Append;
                        #                          gc env:computername | out-file -FilePath C:\scripts\remote-log.txt -Append;
                        #                        }   
             
                        #Start the machine
                        $startMachine = "Y"
                   
                        if ($startMachine.toUpper() -eq "Y")
                            {
                            $VMInfo = @{}
                            New-VMConnectSession -VMName $vmName
                            echo "will start vm $vmName" | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                            Start-VM -VMName $vmName
                            echo "vm $vmName will wait for start to complete" | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                            Start-Sleep -Seconds 30
                            echo "vm $vmName started, will wait for serial data" | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                            $VMinfo = GetVMInfo($vmName)
                            echo "vm $vmName got serial data $VMinfo" | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                            Start-Sleep -Seconds 180
                            echo "vm $vmName will wait 180 sec for winrm client script to finish" | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                            $IPADDR = $VMinfo.Item("IPADDR")
                            echo $IPADDR | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                           
                            $username = "administrator"
                            $passwordPath = "Q:\securestring.txt"
                            echo "vm $vmName loaded username and secure password string" | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50

                            $pwd = ConvertTo-SecureString (Get-Content -Literalpath $passwordPath)
                            $cred = New-Object System.Management.Automation.PSCredential -ArgumentList @($username,$pwd )
                            echo "vm $vmName credentials loaded" | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50

                            $sessionopt = New-PSSessionOption -SkipCACheck -SkipCNCheck
                            echo "vm $vmName remote ps session options loaded, will start remote session on $IPADDR" | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50

                            #Invoke-command -ComputerName $VMinfo.Get_Item("IPADDR") -ScriptBlock $displaycomputername -UseSSL -Credential $cred -SessionOption $sessionopt | Out-File -FilePath "c:\Log-commande.txt" -Append -width 50
                            Invoke-command -ComputerName $VMinfo.Item("IPADDR") -ScriptBlock { gc env:computername | out-file -FilePath C:\scripts\remote-log.txt -Append; } -UseSSL -Credential $cred -SessionOption $sessionopt | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                           
                      

                            # Start-Job -FilePath "$((Get-Location).path)\runremote.ps1" -ArgumentList @($IPADDR)
                            # & runremote.ps1 $VMinfo.Item("IPADDR")

                            echo "vm $vmName remote ps session ended" | Out-File -FilePath "c:\Log$OSName$VMIndex.txt" -Append -width 50
                            } #Close If
   

                         return 0
                         } #close block RUNFACVM
 
             $erroractionpreference = 0
 
             for($i=1;$i -le $numOfVMs2;$i++)
                       
                {
 
                Start-Job -Name "runFACVM" -ScriptBlock $runFACVM -ArgumentList $OSName2, $i, $RAM2, $Cores2
   
                } #Close for

                #Start-Job -Name "runFACVM" -ScriptBlock $runFACVM -ArgumentList $OSName2, $i, $RAM2, $Cores2
 
             Get-Job -Name "runFACVM" | Wait-Job -Timeout 1800
             Get-Job -Name "runFACVM" | Receive-Job
         

            return 0

            }


$HashOS = @{}
$HashOSParam = @{}

$ARRserverformula =  $serverformula.split(";")

foreach($server in $ARRserverformula)

        {

        $ARR2serverformula = $server.split(":")
        $HashOS.add($ARR2serverformula[0],$ARR2serverformula[1])
        $HashOSParam.add($ARR2serverformula[0],@($ARR2serverformula[2],$ARR2serverformula[3]))

        write-host $ARR2serverformula[0]
        write-host $ARR2serverformula[1]
        write-host $ARR2serverformula[2]
        write-host $ARR2serverformula[3]


        Start-Job -Name "runINSTVM" -ScriptBlock $runINSTVM -ArgumentList $ARR2serverformula[0], $ARR2serverformula[1], $ARR2serverformula[2], $ARR2serverformula[3]

        }

        Get-Job -Name "runINSTVM" | Wait-Job -Timeout 3600

        #Instantiate-VM $ARR2serverformula[0] $ARR2serverformula[1] $ARR2serverformula[2] $ARR2serverformula[3]

        Get-Job -Name "runINSTVM" | Receive-Job




#########################################################
# END SERVER SCRIPT
#########################################################
#########################################################
# CLIENT SCRIPT 1 (PROVIDES INFO to the hypervisor) save it as canalwr2.ps1 in C:\scripts
#########################################################

[System.IO.Ports.SerialPort]::getportnames()

$ipres = Get-WMIObject -Class 'Win32_NetworkAdapterConfiguration' -Filter "IPEnabled = True AND DNSDOmain = 'provision.local'"
$computername = gc env:computername

$port = new-Object System.IO.Ports.SerialPort COM1,9600,None,8,one
$port.open()
$port.WriteLine("#IPADDR=" + $ipres.IPAddress[0] + "#")
Start-Sleep -Seconds 10
$port.WriteLine("#COMPN=" + $computername +  "#")

$port.close()

#########################################################
# END CLIENT SCRIPT 1
#########################################################

#########################################################
# CLIENT SCRIPT 2 (configures WinRM and powershell on the VM to allow remote provisioning)
# requires a special unattend.xml to make it run after sysprep and requires makecert.
#Save as winrmconf.ps1 in C:\scripts
#########################################################

#$compname = gc env:computername;
$computerdata = Get-WmiObject -Class 'Win32_ComputerSystem'
$compname = $computerdata.Name

$hvname =  "PROVISION-HYPERV";
[string]$stopparser = '--%';

& "c:\scripts\makecert.exe" $stopparser "-sk "makecert" -ss my -sr localmachine -r -n "CN=$compname" -eku 1.3.6.1.5.5.7.3.1"  | Out-File "c:\scripts\logwinrm.log" -Append

$cert = Get-ChildItem cert:\Localmachine\my | Where-Object {$_.Subject -eq "CN=$compname"}


[string]$trustedhosts = [system.string]::Concat("@{TrustedHosts=`"",$hvname,"`"}");
write-host $trustedhosts;

& "winrm" $stopparser "s winrm/config/client $trustedhosts"  | Out-File "c:\scripts\logwinrm.log" -Append

[string]$winrmparams = [system.string]::Concat("@{Hostname=`"",$compname,"`";CertificateThumbprint=`"",$cert.thumbprint,"`"}");
write-host $winrmparams;
start-sleep -Seconds 10;
& "winrm" $stopparser "delete winrm/config/Listener?Address=*+Transport=HTTPS" | Out-File "c:\scripts\logwinrm.log" -Append
start-sleep -Seconds 10;
& "winrm" $stopparser "create winrm/config/Listener?Address=*+Transport=HTTPS $winrmparams" | Out-File "c:\scripts\logwinrm.log" -Append

#########################################################
# END CLIENT SCRIPT 2
#########################################################

#########################################################
# SCHEDULED TASK XML (launches c:\scripts\canalwr2.ps1 on computer startup after the syprep has done it's work - reports IP and name of the VM to the hypervisor thru the com port)
#########################################################

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2014-01-16T11:22:12.486875</Date>
    <Author>COMPUTERNAME\Administrator</Author>
  </RegistrationInfo>
  <Triggers>
    <BootTrigger>
      <Repetition>
        <Interval>PT5M</Interval>
        <Duration>P1D</Duration>
        <StopAtDurationEnd>false</StopAtDurationEnd>
      </Repetition>
      <ExecutionTimeLimit>PT30M</ExecutionTimeLimit>
      <Enabled>true</Enabled>
    </BootTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>COMPUTERNAME\Administrator</UserId>
      <LogonType>Password</LogonType>
      <RunLevel>LeastPrivilege</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
    <UseUnifiedSchedulingEngine>false</UseUnifiedSchedulingEngine>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command>
      <Arguments>C:\Scripts\canalwr2.ps1</Arguments>
    </Exec>
  </Actions>
</Task>

#########################################################
# END SCHEDULED TASK XML
#########################################################


#########################################################
# UNATTEND.XML (launches c:\scripts\winrmconf.ps1 on computer startup at the specialize pass and autologon)
#########################################################

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
    <settings pass="generalize">
        <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">
            <DoNotCleanTaskBar>true</DoNotCleanTaskBar>
            <RegisteredOrganization>YOUR ORGANIZATION</RegisteredOrganization>
            <RegisteredOwner>YOUR ORGANIZATION</RegisteredOwner>
        </component>
    </settings>
    <settings pass="specialize">
        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
            <ComputerName></ComputerName>
            <ProductKey>Windows product key here</ProductKey>
            <RegisteredOrganization>YOUR ORGANIZATION</RegisteredOrganization>
            <RegisteredOwner>YOUR ORGANIZATION</RegisteredOwner>
            <TimeZone>Romance Standard Time</TimeZone>
            <CopyProfile>true</CopyProfile>
        </component>
        <component name="Microsoft-Windows-Deployment" 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">
            <RunSynchronous>
                <RunSynchronousCommand wcm:action="add">
                    <Description>EnableAdmin</Description>
                    <Order>1</Order>
                    <Path>cmd /c net user Administrator /active:yes</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Description>UnfilterAdministratorToken</Description>
                    <Order>2</Order>
                    <Path>cmd /c reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v FilterAdministratorToken /t REG_DWORD /d 0 /f</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Description>disable user account page</Description>
                    <Order>3</Order>
                    <Path>cmd /c reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Setup\OOBE /v UnattendCreatedUser /t REG_DWORD /d 1 /f</Path>
                </RunSynchronousCommand>
            </RunSynchronous>
        </component>
        <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>040C:0000040C</InputLocale>
            <SystemLocale>fr-FR</SystemLocale>
            <UILanguage>fr-FR</UILanguage>
            <UserLocale>fr-FR</UserLocale>
        </component>
    </settings>
    <settings pass="oobeSystem">
        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
            <UserAccounts>
                <AdministratorPassword>
                    <Value>crypted admin password</Value>
                    <PlainText>false</PlainText>
                </AdministratorPassword>
            </UserAccounts>
            <AutoLogon>
                <Enabled>true</Enabled>
                <Username>Administrator</Username>
                <Domain>.</Domain>
                <Password>
                    <Value>crypted admin password</Value>
                    <PlainText>false</PlainText>
                </Password>
                <LogonCount>5</LogonCount>
            </AutoLogon>
            <Display>
                <ColorDepth>32</ColorDepth>
                <HorizontalResolution>1024</HorizontalResolution>
                <RefreshRate>60</RefreshRate>
                <VerticalResolution>768</VerticalResolution>
            </Display>
            <OOBE>
                <HideEULAPage>true</HideEULAPage>
                <NetworkLocation>Work</NetworkLocation>
                <ProtectYourPC>1</ProtectYourPC>
            </OOBE>
            <RegisteredOrganization>YOUR ORGANIZATION</RegisteredOrganization>
            <RegisteredOwner>YOUR ORGANIZATION</RegisteredOwner>
            <TimeZone>Romance Standard Time</TimeZone>
            <FirstLogonCommands>
                <SynchronousCommand wcm:action="add">
                    <Description>configure winrm remoting ssl listerner and certificate</Description>
                    <CommandLine>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe &quot;c:\scripts\winrmconf.ps1&quot;</CommandLine>
                    <Order>1</Order>
                    <RequiresUserInput>false</RequiresUserInput>
                </SynchronousCommand>
            </FirstLogonCommands>
        </component>
        <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>040C:0000040C</InputLocale>
            <SystemLocale>fr-FR</SystemLocale>
            <UILanguage>fr-FR</UILanguage>
            <UserLocale>fr-FR</UserLocale>
        </component>
    </settings>
    <settings pass="offlineServicing">
        <component name="Microsoft-Windows-PnpCustomizationsNonWinPE" 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">
            <DriverPaths>
                <PathAndCredentials wcm:keyValue="1" wcm:action="add">
                    <Path>\Drivers</Path>
                </PathAndCredentials>
            </DriverPaths>
        </component>
    </settings>
    <cpi:offlineImage cpi:source="wim://srv-backup2/magasin/images-cd-os/windows%202008%20r2/fr_windows_server_2008_r2_with_sp1_vl_build_x64_dvd_617392/sources/install.wim#Windows Server 2008 R2 SERVERENTERPRISE" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>

#########################################################
# END UNATTEND.XML
#########################################################


#########################################################
# SYSPREP COMMAND
#########################################################



c:\windows\system32\sysprep\sysprep.exe /unattend:c:\scripts\unattend.xml

#########################################################
# END SYPREP COMMAND
#########################################################



No comments:

Post a Comment

Fell free to comment : share your opinion and experienced, provide feedback, help me to correct mistakes, and ask for help if you need any !