├── LICENSE ├── README.md ├── centos7 └── customize_ic_centos7.sh ├── esxi65-67 ├── InstantClone-ESXi.ps1 └── customize.sh ├── macos10.14 ├── InstantClone-MacOS.ps1 └── customize.sh ├── ubuntu16 └── customize.sh ├── vcsa67 ├── InstantClone-VCHA.ps1 └── customize.sh ├── windows2000 ├── instantclone-windows-2000.ps1 ├── ip.vbs ├── nic.vbs └── run.bat └── windows98 ├── instantclone-windows-98.ps1 └── run.bat /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 William Lam 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # "Parentless" Instant Clone Community Customization Scripts 2 | 3 | This repository contains a collection of community contributed OS customization scripts that can be used with the new "Parentless" Instant Clone 4 | 5 | ## Requirements 6 | 7 | * [vSphere 6.7 (vCenter Server + ESXi 6.7)](https://my.vmware.com/web/vmware/info/slug/datacenter_cloud_infrastructure/vmware_vsphere/6_7) 8 | * [PowerCLI 10.1](https://code.vmware.com/web/dp/tool/vmware-powercli/10.1.0) 9 | 10 | ## How it works 11 | 12 | Please see this blog post [here](https://www.virtuallyghetto.com/2018/04/new-instant-clone-architecture-in-vsphere-6-7-part-2.html) for more details. 13 | 14 | ## Contribution 15 | 16 | Feel free to submit a pull request for either bug fixes or adding additional OS customization scripts. 17 | -------------------------------------------------------------------------------- /centos7/customize_ic_centos7.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #(C) Copyright 2019 Hewlett Packard Enterprise Development LP. 3 | # Author: Russell Briggs (github: briggr1) 4 | # Instant Clone Pre Customization Script 5 | # OS: CentOS Linux release 7.6.1810 (Core) 6 | 7 | set -x 8 | touch /root/ic-customization.log 9 | exec > /root/ic-customization.log 2>&1 10 | 11 | echo -e "\n=== Start Pre-Freeze ===" 12 | 13 | # Disable ens192 14 | echo "Disabling ens192 interface ..." 15 | mv /etc/sysconfig/network-scripts/ifcfg-ens192 /etc/sysconfig/network-scripts/ifcfg-ens192.bak 16 | ip link set ens192 down 17 | 18 | echo -e "=== End of Pre-Freeze ===\n" 19 | 20 | echo -e "Freezing ...\n" 21 | 22 | vmware-rpctool "instantclone.freeze" 23 | 24 | ###################################################### 25 | # All commands past this point are run on the clones 26 | ###################################################### 27 | 28 | echo -e "\n=== Start Post-Freeze ===" 29 | # retrieve networking info passed from script 30 | HOSTNAME=$(vmware-rpctool "info-get guestinfo.ic.hostname") 31 | IPV4=$(vmware-rpctool "info-get guestinfo.ic.ipv4") 32 | NETMASK=$(vmware-rpctool "info-get guestinfo.ic.netmask") 33 | GATEWAY=$(vmware-rpctool "info-get guestinfo.ic.gateway") 34 | DNS=$(vmware-rpctool "info-get guestinfo.ic.dns") 35 | 36 | echo "Updating MAC Address ..." 37 | if lsmod | grep vmxnet3 > /dev/null 2>&1 ; then 38 | NIC_MODULE=vmxnet3 39 | elif lsmod | grep e1000e > /dev/null 2>&1 ; then 40 | NIC_MODULE=e1000e 41 | elif lsmod | grep e1000 > /dev/null 2>&1 ; then 42 | NIC_MODULE=e1000 43 | fi 44 | modprobe -r ${NIC_MODULE};modprobe ${NIC_MODULE} 45 | 46 | sleep 5 # 47 | 48 | UUID=`uuidgen ens192` 49 | ENS192MAC=`cat /sys/class/net/ens192/address` 50 | 51 | echo "Updating IP Address ..." 52 | cat > /etc/sysconfig/network-scripts/ifcfg-ens192 << CENTOS_NET 53 | HWADDR=${ENS192MAC} 54 | NM_CONTROLLED="no" 55 | ONBOOT=yes 56 | BOOTPROTO=static 57 | IPADDR=${IPV4} 58 | NETMASK=${NETMASK} 59 | GATEWAY=${GATEWAY} 60 | DNS1=${DNS} 61 | DEFROUTE=yes 62 | IPV6INIT=no 63 | NAME=ens192 64 | UUID=${UUID} 65 | DEVICE=ens192 66 | HOSTNAME=${HOSTNAME} 67 | CENTOS_NET 68 | 69 | chmod 777 /etc/sysconfig/network-scripts/ifcfg-ens192 70 | 71 | echo "Enabling ens192 interface ..." 72 | ip link set ens192 up 73 | 74 | echo "Updating Hostname ..." 75 | hostnamectl set-hostname ${HOSTNAME} 76 | 77 | echo "Enabling networking ..." 78 | systemctl restart network 79 | 80 | echo "Updating Hardware Clock on the system ..." 81 | hwclock --hctosys 82 | 83 | echo "=== End of Post-Freeze ===" -------------------------------------------------------------------------------- /esxi65-67/InstantClone-ESXi.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS Script to deploy Nested ESXi Instasnt Clones 3 | .NOTES Author: William Lam 4 | .NOTES Site: www.virtuallyghetto.com 5 | .NOTES Reference: http://www.virtuallyghetto.com/2018/05/leveraging-instant-clone-in-vsphere-6-7-for-extremely-fast-nested-esxi-provisioning.html 6 | #> 7 | 8 | Import-Module InstantClone.psm1 9 | 10 | $SourceVM = "Nested_ESXi6.7_Appliance_Template" 11 | 12 | $numOfVMs = 3 13 | 14 | $ipNetwork = "192.168.30" 15 | $ipStartingCount=50 16 | $netmask = "255.255.255.0" 17 | $dns = "192.168.30.1" 18 | $gw = "192.168.30.1" 19 | $networktype = "static" # static or dhcp 20 | 21 | ### DO NOT EDIT BEYOND HERE ### 22 | 23 | $StartTime = Get-Date 24 | Write-host "" 25 | foreach ($i in 1..$numOfVMs) { 26 | $newVMName = "esxi-0$i" 27 | 28 | # Generate random UUID which will be used to update 29 | # ESXi Host & VSAN Node UUID 30 | $uuid = [guid]::NewGuid() 31 | # Changing ESXi Host UUID requires format to be in hex 32 | $uuidHex = ($uuid.ToByteArray() | %{"0x{0:x}" -f $_}) -join " " 33 | 34 | $guestCustomizationValues = @{ 35 | "guestinfo.ic.hostname" = "$newVMName" 36 | "guestinfo.ic.ipaddress" = "$ipNetwork.$ipStartingCount" 37 | "guestinfo.ic.netmask" = "$netmask" 38 | "guestinfo.ic.gateway" = "$gw" 39 | "guestinfo.ic.dns" = "$dns" 40 | "guestinfo.ic.sourcevm" = "$SourceVM" 41 | "guestinfo.ic.networktype" = "$networktype" 42 | "guestinfo.ic.uuid" = "$uuid" 43 | "guestinfo.ic.uuidHex" = "$uuidHex" 44 | } 45 | $ipStartingCount++ 46 | 47 | # Create Instant Clone 48 | New-InstantClone -SourceVM $SourceVM -DestinationVM $newVMName -CustomizationFields $guestCustomizationValues 49 | 50 | # Retrieve newly created Instant Clone 51 | $VM = Get-VM -Name $newVMName 52 | 53 | # Hot Add 2 VMDKs for use w/VSAN 54 | Write-Host "`tHot-Add 4 & 8 GB VMDK for use with VSAN" 55 | New-HardDisk -VM $VM -CapacityGB 4 -StorageFormat Thin -Confirm:$false | Out-Null 56 | New-HardDisk -VM $VM -CapacityGB 8 -StorageFormat Thin -Confirm:$false | Out-Null 57 | } 58 | 59 | $EndTime = Get-Date 60 | $duration = [math]::Round((New-TimeSpan -Start $StartTime -End $EndTime).TotalMinutes,2) 61 | 62 | Write-Host -ForegroundColor Cyan "`nTotal Instant Clones: $numOfVMs" 63 | Write-Host -ForegroundColor Cyan "StartTime: $StartTime" 64 | Write-Host -ForegroundColor Cyan " EndTime: $EndTime" 65 | Write-Host -ForegroundColor Green " Duration: $duration minutes" -------------------------------------------------------------------------------- /esxi65-67/customize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Author: William Lam 3 | # Contact: @lamw 4 | # Description: Tested on ESXi 6.5 Update 2 & 6.7 5 | 6 | set -x 7 | exec 2>/ic-customization.log 8 | 9 | echo -e "\n=== Start Pre-Freeze ===" 10 | 11 | # Disable VSAN traffic if enabled & vmnic0 12 | echo "Disabling vmnic0 ..." 13 | esxcli vsan network remove -i vmk0 14 | esxcli network nic down -n vmnic0 15 | 16 | # Stop hostd 17 | echo "Stopping hostd ..." 18 | /etc/init.d/hostd stop 19 | 20 | # Remove any exisitng VMkernel interfaces which would have associationg with existing MAC Addresses 21 | echo "Removing vmk0 interface ..." 22 | localcli network ip interface set -e false -i vmk0 23 | localcli network ip interface remove -i vmk0 24 | localcli network vswitch standard portgroup remove -p "Management Network" -v "vSwitch0" 25 | 26 | # Ensure the new MAC Address is automatically picked up once cloned 27 | echo "Enable MAC Address updates ..." 28 | localcli system settings advanced set -o /Net/FollowHardwareMac -i 1 29 | 30 | # Remove any potential old DHCP leases 31 | echo "Clearing DHCP leases ..." 32 | rm -f /etc/dhclient*leases 33 | 34 | # Ensure new system UUID is generated 35 | echo "Clearing UUID ..." 36 | sed -i 's#/system/uuid.*##g' /etc/vmware/esx.conf 37 | 38 | echo -e "=== End of Pre-Freeze ===\n" 39 | 40 | echo -e "Freezing ...\n" 41 | 42 | vmtoolsd --cmd "instantclone.freeze" 43 | 44 | echo -e "\n=== Start Post-Freeze ===" 45 | 46 | # retrieve VM customization info passed from vSphere API 47 | HOSTNAME=$(vmtoolsd --cmd "info-get guestinfo.ic.hostname") 48 | IP_ADDRESS=$(vmtoolsd --cmd "info-get guestinfo.ic.ipaddress") 49 | NETMASK=$(vmtoolsd --cmd "info-get guestinfo.ic.netmask") 50 | GATEWAY=$(vmtoolsd --cmd "info-get guestinfo.ic.gateway") 51 | DNS=$(vmtoolsd --cmd "info-get guestinfo.ic.dns") 52 | NETWORK_TYPE=$(vmtoolsd --cmd "info-get guestinfo.ic.networktype") 53 | UUID=$(vmtoolsd --cmd "info-get guestinfo.ic.uuid") 54 | UUIDHEX=$(vmtoolsd --cmd "info-get guestinfo.ic.uuidhex") 55 | 56 | # Updating ESXi Host UUID 57 | echo "Updating ESXi Host UUID ..." 58 | vsish -e set /system/systemUuid ${UUIDHEX} 59 | echo "/system/uuid = \"${UUID}\"" >> /etc/vmware/esx.conf 60 | 61 | # Updating VSAN Node UUID to match Host UUID 62 | echo "Updating VSAN Node UUID ..." 63 | localcli system settings advanced set -o /VSAN/NodeUuid -s ${UUID} 64 | 65 | # setup vmk0 66 | echo "Configuring Management Network (vmk0) ..." 67 | localcli network nic up -n vmnic0 68 | localcli network vswitch standard portgroup add -p "Management Network" -v "vSwitch0" 69 | localcli network ip interface add -i vmk0 -p "Management Network" 70 | if [ ${NETWORK_TYPE} == "static" ]; then 71 | localcli network ip interface ipv4 set -i vmk0 -I ${IP_ADDRESS} -N ${NETMASK} -t static 72 | localcli network ip route ipv4 add -g ${GATEWAY} -n default 73 | else 74 | localcli network ip interface ipv4 set -i vmk0 -t dhcp 75 | fi 76 | localcli system hostname set -f ${HOSTNAME} 77 | 78 | # Start hostd 79 | echo "Starting hostd ..." 80 | /etc/init.d/hostd start & 81 | 82 | echo "Wait for hostd to be ready & then rescan storage adapter ..." 83 | # Ensure hostd is ready 84 | while ! vim-cmd hostsvc/hostsummary > /dev/null; do 85 | sleep 15 86 | done 87 | esxcli storage core adapter rescan -a 88 | esxcli vsan network ip add -i vmk0 89 | echo "=== End of Post-Freeze ===" 90 | 91 | echo -e "\nCheck /root/ic-customization.log for details\n\n" 92 | -------------------------------------------------------------------------------- /macos10.14/InstantClone-MacOS.ps1: -------------------------------------------------------------------------------- 1 | # William Lam 2 | # www.virtuallyghetto.com 3 | # Script to deploy MacOS 10.14 (Mojave) Instant Clones 4 | 5 | $SourceVM = "MacOS-Mojave-Template" 6 | 7 | $numOfVMs = 5 8 | $ipNetwork = "192.168.30" 9 | $ipStartingCount=50 10 | $netmask = "255.255.255.0" 11 | $dns = "192.168.30.1" 12 | $gw = "192.168.30.1" 13 | 14 | ### DO NOT EDIT BEYOND HERE ### 15 | 16 | if ( ! (Get-VM -Name $SourceVM).ExtensionData.Summary.Runtime.InstantCloneFrozen ) { 17 | Write-Host -ForegroundColor "`n$($SourceVM) has not gone into frozen state yet, please try again in a moment`n" 18 | break 19 | } 20 | 21 | If ( ! (Get-module InstantClone )) { 22 | Write-Host -ForegroundColor Red "`nInstant Clone Module not loaded`n" 23 | break 24 | } 25 | 26 | $StartTime = Get-Date 27 | Write-host "" 28 | foreach ($i in 1..$numOfVMs) { 29 | $newVMName = "MacOS-Mojave-IC-$i" 30 | 31 | $guestCustomizationValues = @{ 32 | "guestinfo.ic.hostname" = "$newVMName" 33 | "guestinfo.ic.ipaddress" = "$ipNetwork.$ipStartingCount" 34 | "guestinfo.ic.netmask" = "$netmask" 35 | "guestinfo.ic.gateway" = "$gw" 36 | "guestinfo.ic.dns" = "$dns" 37 | } 38 | $ipStartingCount++ 39 | New-InstantClone -SourceVM $SourceVM -DestinationVM $newVMName -CustomizationFields $guestCustomizationValues 40 | } 41 | 42 | $EndTime = Get-Date 43 | $duration = [math]::Round((New-TimeSpan -Start $StartTime -End $EndTime).TotalMinutes,2) 44 | 45 | Write-Host -ForegroundColor Cyan "`nTotal Instant Clones: $numOfVMs" 46 | Write-Host -ForegroundColor Cyan "StartTime: $StartTime" 47 | Write-Host -ForegroundColor Cyan " EndTime: $EndTime" 48 | Write-Host -ForegroundColor Green " Duration: $duration minutes" -------------------------------------------------------------------------------- /macos10.14/customize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Author: William Lam 3 | # Contact: @lamw 4 | # Description: Tested on MacOS 10.14.14 (Mojave) 5 | 6 | set -x 7 | exec 2>/Users/virtuallyghetto/Desktop/ic-customization.log 8 | 9 | echo -e "\n=== Start Pre-Freeze ===" 10 | 11 | # Disable primary network interface by unloading kernel moduile 12 | # Credit goes to https://github.com/mjm for sharing tidbit 13 | echo "Disabling Network Interface" 14 | kextunload /System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns/Intel82574L.kext 15 | sleep 2 16 | 17 | echo -e "=== End of Pre-Freeze ===\n" 18 | 19 | echo -e "Freezing ...\n" 20 | 21 | /Library/Application\ Support/VMware\ Tools/vmware-tools-daemon --cmd="instantclone.freeze" 22 | 23 | echo -e "\n=== Start Post-Freeze ===" 24 | 25 | # Retrieve VM customization info passed from vSphere API 26 | HOSTNAME=$(/Library/Application\ Support/VMware\ Tools/vmware-tools-daemon --cmd "info-get guestinfo.ic.hostname") 27 | IP_ADDRESS=$(/Library/Application\ Support/VMware\ Tools/vmware-tools-daemon --cmd "info-get guestinfo.ic.ipaddress") 28 | NETMASK=$(/Library/Application\ Support/VMware\ Tools/vmware-tools-daemon --cmd "info-get guestinfo.ic.netmask") 29 | GATEWAY=$(/Library/Application\ Support/VMware\ Tools/vmware-tools-daemon --cmd "info-get guestinfo.ic.gateway") 30 | DNS=$(/Library/Application\ Support/VMware\ Tools/vmware-tools-daemon --cmd "info-get guestinfo.ic.dns") 31 | 32 | echo "Re-enabling Network Interface" 33 | kextload /System/Library/Extensions/IONetworkingFamily.kext/Contents/PlugIns/Intel82574L.kext 34 | 35 | # Static Network Assignment 36 | # https://discussions.apple.com/thread/5082299?answerId=5082299021#5082299021 37 | if [[ ! -z ${HOSTNAME} && ! -z ${IP_ADDRESS} && ! -z ${NETMASK} && ! -z ${GATEWAY} && ! -z ${DNS} ]]; then 38 | ETH0_INTERFACE_NAME="Ethernet" 39 | 40 | echo "Configuring Hostname to ${HOSTNAME} ..." 41 | networksetup -setcomputername ${HOSTNAME} 42 | 43 | echo "Configuring Static IP Address ..." 44 | networksetup -setmanual ${ETH0_INTERFACE_NAME} ${IP_ADDRESS} ${NETMASK} ${GATEWAY} 45 | 46 | echo "Configuring DNS Server ..." 47 | networksetup -setdnsservers ${ETH0_INTERFACE_NAME} ${DNS} 48 | fi 49 | 50 | echo "=== End of Post-Freeze ===" 51 | 52 | echo -e "\nCheck /root/ic-customization.log for details\n\n" -------------------------------------------------------------------------------- /ubuntu16/customize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Author: William Lam 3 | # Contact: @lamw 4 | # Description: Tested on Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-31-generic x86_64) 5 | 6 | set -x 7 | exec 2>/root/ic-customization.log 8 | 9 | echo -e "\n=== Start Pre-Freeze ===" 10 | 11 | # Disable assignment of fixed names https://askubuntu.com/a/834201 12 | ln -s /dev/null /etc/udev/rules.d/80-net-setup-link.rules 13 | 14 | # Disable primary network interface (ens160, this may differ from your OS installation) 15 | CURRENT_PRIMARY_INTERFACE_NAME="ens160" 16 | DESIRED_PRIMARY_INTERFACE_NAME="eth0" 17 | echo "Disabling ${CURRENT_PRIMARY_INTERFACE_NAME} interface ..." 18 | ip addr flush dev ${CURRENT_PRIMARY_INTERFACE_NAME} 19 | ip link set ${CURRENT_PRIMARY_INTERFACE_NAME} down 20 | 21 | echo -e "=== End of Pre-Freeze ===\n" 22 | 23 | echo -e "Freezing ...\n" 24 | 25 | vmware-rpctool "instantclone.freeze" 26 | 27 | echo -e "\n=== Start Post-Freeze ===" 28 | 29 | # retrieve VM customization info passed from vSphere API 30 | HOSTNAME=$(vmware-rpctool "info-get guestinfo.ic.hostname") 31 | IP_ADDRESS=$(vmware-rpctool "info-get guestinfo.ic.ipaddress") 32 | NETMASK=$(vmware-rpctool "info-get guestinfo.ic.netmask") 33 | GATEWAY=$(vmware-rpctool "info-get guestinfo.ic.gateway") 34 | DNS=$(vmware-rpctool "info-get guestinfo.ic.dns") 35 | 36 | echo "Updating MAC Address ..." 37 | for NETDEV in /sys/class/net/e* 38 | do 39 | DEVICE_LABEL=$(basename $(readlink -f "$NETDEV/device")) 40 | DEVICE_DRIVER=$(basename $(readlink -f "$NETDEV/device/driver")) 41 | echo $DEVICE_LABEL > /sys/bus/pci/drivers/$DEVICE_DRIVER/unbind 42 | echo $DEVICE_LABEL > /sys/bus/pci/drivers/$DEVICE_DRIVER/bind 43 | done 44 | 45 | echo "Updating IP Address ..." 46 | # Rename interface to eth0 (not necessary) 47 | sed -i "s/${CURRENT_PRIMARY_INTERFACE_NAME}/${DESIRED_PRIMARY_INTERFACE_NAME}/" /etc/network/interfaces 48 | # Update from DHCP to Static 49 | sed -i 's/dhcp/static/' /etc/network/interfaces 50 | cat >> /etc/network/interfaces << NETWORK_INTERFACE 51 | address ${IP_ADDRESS} 52 | netmask ${NETMASK} 53 | gateway ${GATEWAY} 54 | dns-nameservers ${DNS} 55 | NETWORK_INTERFACE 56 | 57 | echo "Updating Hostname ..." 58 | hostnamectl set-hostname ${HOSTNAME} 59 | 60 | echo "Restart networking ..." 61 | systemctl restart networking.service 62 | systemctl restart resolvconf.service 63 | 64 | echo "Updating Hardware Clock on the system ..." 65 | hwclock --hctosys 66 | 67 | echo "=== End of Post-Freeze ===" 68 | 69 | echo -e "\nCheck /root/ic-customization.log for details\n\n" 70 | -------------------------------------------------------------------------------- /vcsa67/InstantClone-VCHA.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS Script to deploy VCHA using Instant Clone (Proof of Concept, not officially supported) 3 | .NOTES Author: William Lam 4 | .NOTES Site: www.virtuallyghetto.com 5 | #> 6 | 7 | Import-Module .\InstantClone.psm1 8 | 9 | $SourceVCSAName = "VCSA-Active" 10 | $SourceVCSAAddress = "10.20.120.25" 11 | $SourceVCSAVIUsername = "administrator@vsphere.local" 12 | $SourceVCSAVIPassword = "VMware1!" 13 | $SourceVCSAOSUsername = "root" 14 | $SourceVCSAOSPassword = "VMware1!" 15 | 16 | $VCAHANetworkName = "Private" 17 | $SourceVCSAHAIpAddress = "172.30.0.25" 18 | $PassiveVCSAName = "VCSA-Passive" 19 | $PassiveVCSAHAIpAddress = "172.30.0.26" 20 | $WitnessVCSAName = "VCSA-Witness" 21 | $WitnessVCSAHAIpAddress = "172.30.0.27" 22 | $VCSANetworkmask = "255.255.255.0" # API expects netmask format 23 | $VCSANetworkPrefix = "24" # PhotonOS expects CIDR format 24 | 25 | ### DO NOT EDIT BEYOND HERE ### 26 | 27 | $StartTime = Get-Date 28 | Write-Host -ForegroundColor Cyan "Starting VCHA Instant Clone ..." 29 | 30 | $vm = Get-VM -Name $SourceVCSAName 31 | 32 | # Add second NIC and configure for VCHA network 33 | Write-Host -ForegroundColor Cyan "Adding eth1 to $SourceVCSAAddress for VCHA Network ..." 34 | New-NetworkAdapter -VM $vm -Portgroup (Get-VirtualPortGroup -Name $VCAHANetworkName) -StartConnected -Type Vmxnet3 -Confirm:$false | Out-Null 35 | 36 | # Configure Second NIC for VCHA network 37 | Write-Host -ForegroundColor Cyan "Configuring eth1 for VCHA Network ..." 38 | 39 | $vchaCisService = Connect-CisServer -Server $SourceVCSAAddress -User $SourceVCSAVIUsername -Password $SourceVCSAVIPassword | Out-Null 40 | $ipv4NetworkSerice = Get-CisService com.vmware.appliance.networking.interfaces.ipv4 41 | $networkConfig = $ipv4NetworkSerice.Help.set.config.Create() 42 | $networkConfig.mode = "STATIC" 43 | $networkConfig.address = $SourceVCSAHAIpAddress 44 | $networkConfig.prefix = $VCSANetworkPrefix 45 | $ipv4NetworkSerice.set("nic1",$networkConfig) 46 | Disconnect-CisServer * -Confirm:$false | Out-Null 47 | 48 | # Prepare for VCHA 49 | $vchaVIConnection = Connect-VIServer -Server $SourceVCSAAddress -User $SourceVCSAVIUsername -Password $SourceVCSAVIPassword 50 | $vcHAClusterConfig = Get-View -Server $vchaVIConnection failoverClusterConfigurator 51 | $vchaNetworkSpec = New-Object VMware.Vim.VchaClusterNetworkSpec 52 | 53 | $passiveNetworkSpec = New-Object VMware.Vim.PassiveNodeNetworkSpec 54 | $passiveIpSettings = New-Object VMware.Vim.CustomizationIPSettings 55 | $fixedIp = New-object VMware.Vim.CustomizationFixedIp 56 | $fixedIp.IpAddress = $PassiveVCSAHAIpAddress 57 | $passiveIpSettings.Ip = $fixedIp 58 | $passiveIpSettings.SubnetMask = $VCSANetworkmask 59 | $passiveNetworkSpec.IpSettings = $passiveIpSettings 60 | $vchaNetworkSpec.PassiveNetworkSpec = $passiveNetworkSpec 61 | 62 | $witnessNetworkSpec = New-Object VMware.Vim.NodeNetworkSpec 63 | $witnessIpSettings = New-Object VMware.Vim.CustomizationIPSettings 64 | $fixedIp = New-object VMware.Vim.CustomizationFixedIp 65 | $fixedIp.IpAddress = $WitnessVCSAHAIpAddress 66 | $witnessIpSettings.Ip = $fixedIp 67 | $witnessIpSettings.SubnetMask = $VCSANetworkmask 68 | $witnessNetworkSpec.IpSettings = $witnessIpSettings 69 | $vchaNetworkSpec.WitnessNetworkSpec = $witnessNetworkSpec 70 | 71 | Write-Host -ForegroundColor Cyan "Preparing VCHA on $SourceVCSAAddress ..." 72 | $vcHAClusterConfig.prepareVcha($vchaNetworkSpec) 73 | 74 | # Instant Clone Passive & Witness 75 | New-InstantClone -SourceVM $SourceVCSAName -DestinationVM $PassiveVCSAName -CustomizationFields @{"guestinfo.ic.sourcevc"="$SourceVCSAName";"guestinfo.ic.ipaddress"="$PassiveVCSAHAIpAddress";"guestinfo.ic.prefix"="$VCSANetworkPrefix"} 76 | New-InstantClone -SourceVM $SourceVCSAName -DestinationVM $WitnessVCSAName -CustomizationFields @{"guestinfo.ic.sourcevc"="$SourceVCSAName";"guestinfo.ic.ipaddress"="$WitnessVCSAHAIpAddress";"guestinfo.ic.prefix"="$VCSANetworkPrefix"} 77 | 78 | # Refresh MAC Address + Configure VCHA IP for Passive & Witness 79 | Write-Host -ForegroundColor Cyan "Running customization script /root/customize.sh on Passive VCSA ..." 80 | Invoke-VMScript -VM (Get-VM -Name $PassiveVCSAName) -ScriptText "/root/customize.sh" -ScriptType Bash -GuestUser $SourceVCSAOSUsername -GuestPassword $SourceVCSAOSPassword | Out-Null 81 | 82 | Write-Host -ForegroundColor Cyan "Running customization script /root/customize.sh on Witness VCSA ..." 83 | Invoke-VMScript -VM (Get-VM -Name $WitnessVCSAName) -ScriptText "/root/customize.sh" -ScriptType Bash -GuestUser $SourceVCSAOSUsername -GuestPassword $SourceVCSAOSPassword | Out-Null 84 | 85 | # Connecting eth1 for Passive & Witness 86 | Write-Host -ForegroundColor Cyan "Connecting eth1 on Passive VCSA .." 87 | Get-VM -Name $PassiveVCSAName | Get-NetworkAdapter | where {$_.Name -eq "Network adapter 2"} | Set-NetworkAdapter -Connected $true -Confirm:$false | Out-Null 88 | 89 | Write-Host -ForegroundColor Cyan "Connecting eth1 on Witness VCSA .." 90 | Get-VM -Name $WitnessVCSAName | Get-NetworkAdapter | where {$_.Name -eq "Network adapter 2"} | Set-NetworkAdapter -Connected $true -Confirm:$false | Out-Null 91 | 92 | # Configure VCHA 93 | $vcHAClusterConfig = Get-View -Server $vchaVIConnection failoverClusterConfigurator 94 | 95 | $vchaConfigSpec = New-Object VMware.Vim.VchaClusterConfigSpec 96 | $vchaConfigSpec.PassiveIp = $PassiveVCSAHAIpAddress 97 | $vchaConfigSpec.WitnessIp = $WitnessVCSAHAIpAddress 98 | 99 | Write-Host -ForegroundColor Cyan "Configuring VCHA on $SourceVCSAAddress ...`n" 100 | $task = $vcHAClusterConfig.configureVcha_Task($vchaConfigSpec) 101 | $task1 = Get-Task -Id ("Task-$($task.value)") 102 | $task1 | Wait-Task 103 | 104 | # Profit 105 | Disconnect-VIServer -Server $vchaVIConnection -Confirm:$false 106 | 107 | $EndTime = Get-Date 108 | $duration = [math]::Round((New-TimeSpan -Start $StartTime -End $EndTime).TotalMinutes,2) 109 | Write-Host -ForegroundColor Cyan "`nStartTime: $StartTime" 110 | Write-Host -ForegroundColor Cyan " EndTime: $EndTime" 111 | Write-Host -ForegroundColor Green " Duration: $duration minutes" -------------------------------------------------------------------------------- /vcsa67/customize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Author: William Lam 3 | # Contact: @lamw 4 | # Description: Tested on VCSA 6.7 5 | 6 | set -x 7 | exec 2>/root/ic-customization.log 8 | 9 | # retrieve VM customization info passed from vSphere API 10 | IP_ADDRESS=$(vmware-rpctool "info-get guestinfo.ic.ipaddress") 11 | PREFIX=$(vmware-rpctool "info-get guestinfo.ic.prefix") 12 | 13 | echo "Updating IP Address for eth1 ..." 14 | sed -i "s#Address.*#Address=${IP_ADDRESS}/${PREFIX}#g" /etc/systemd/network/10-eth1.network 15 | 16 | # bring down both eth0 and eth1 17 | echo "Bringing down eth0 and eth1 ..." 18 | ifdown eth0 19 | ifdown eth1 20 | 21 | echo "Updating MAC Address ..." 22 | for NETDEV in /sys/class/net/e* 23 | do 24 | DEVICE_LABEL=$(basename $(readlink -f "$NETDEV/device")) 25 | DEVICE_DRIVER=$(basename $(readlink -f "$NETDEV/device/driver")) 26 | echo $DEVICE_LABEL > /sys/bus/pci/drivers/$DEVICE_DRIVER/unbind 27 | echo $DEVICE_LABEL > /sys/bus/pci/drivers/$DEVICE_DRIVER/bind 28 | done 29 | 30 | echo "Bringing up eth1 ..." 31 | ifup eth1 32 | 33 | echo -e "\nCheck /root/ic-customization.log for details\n\n" -------------------------------------------------------------------------------- /windows2000/instantclone-windows-2000.ps1: -------------------------------------------------------------------------------- 1 | $SourceVM = "Windows2000" 2 | 3 | $numOfVMs = 10 4 | $ipNetwork = "192.168.30" 5 | $ipStartingCount=60 6 | $netmask = "255.255.255.0" 7 | $dns = "192.168.30.1" 8 | $gw = "192.168.30.1" 9 | 10 | $StartTime = Get-Date 11 | foreach ($i in 1..$numOfVMs) { 12 | $newVMName = "IC-Windows2000-$i" 13 | 14 | $guestCustomizationValues = @{ 15 | "guestinfo.ic.hostname" = "$newVMName" 16 | "guestinfo.ic.ipaddress" = "$ipNetwork.$ipStartingCount" 17 | "guestinfo.ic.netmask" = "$netmask" 18 | "guestinfo.ic.gateway" = "$gw" 19 | "guestinfo.ic.dns" = "$dns" 20 | "guestinfo.ic.sourcevm" = "$SourceVM" 21 | } 22 | $ipStartingCount++ 23 | New-InstantClone -SourceVM $SourceVM -DestinationVM $newVMName -CustomizationFields $guestCustomizationValues 24 | } 25 | 26 | $EndTime = Get-Date 27 | $duration = [math]::Round((New-TimeSpan -Start $StartTime -End $EndTime).TotalMinutes,2) 28 | 29 | Write-Host -ForegroundColor Cyan "`nTotal Instant Clones: $numOfVMs" 30 | Write-Host -ForegroundColor Cyan "StartTime: $StartTime" 31 | Write-Host -ForegroundColor Cyan " EndTime: $EndTime" 32 | Write-Host -ForegroundColor Green " Duration: $duration minutes" -------------------------------------------------------------------------------- /windows2000/ip.vbs: -------------------------------------------------------------------------------- 1 | Set args = Wscript.Arguments 2 | 3 | ip=WScript.Arguments.Item(0) 4 | netmask=WScript.Arguments.Item(1) 5 | gateway=WScript.Arguments.Item(2) 6 | dns=WScript.Arguments.Item(3) 7 | hostname=WScript.Arguments.Item(4) 8 | 9 | strComputer = "." 10 | Set objWMIService = GetObject("winmgmts:" _ 11 | & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 12 | 13 | Set colNetAdapters = objWMIService.ExecQuery _ 14 | ("Select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE") 15 | 16 | strIPAddress = Array(ip) 17 | strSubnetMask = Array(netmask) 18 | strGateway = Array(gateway) 19 | arrDNSServers = Array(dns) 20 | strGatewayMetric = Array(1) 21 | 22 | WScript.Echo "" 23 | WScript.Echo "Applying new Network configurations ..." 24 | WScript.Echo "" 25 | For Each objNetAdapter in colNetAdapters 26 | errEnable = objNetAdapter.EnableStatic(strIPAddress, strSubnetMask) 27 | errGateways = objNetAdapter.SetGateways(strGateway, strGatewaymetric) 28 | errDNS = objNetAdapter.SetDNSServerSearchOrder(arrDNSServers) 29 | If errEnable = 0 Then 30 | WScript.Echo "The IP address has been changed." 31 | Else 32 | WScript.Echo "The IP address could not be changed." 33 | End If 34 | Next 35 | 36 | WScript.Echo "" 37 | WScript.Echo "Updating Hostname ..." 38 | 39 | Set oShell = CreateObject ("WSCript.shell" ) 40 | 41 | sCCS = "HKLM\SYSTEM\CurrentControlSet\" 42 | sTcpipParamsRegPath = sCCS & "Services\Tcpip\Parameters\" 43 | sCompNameRegPath = sCCS & "Control\ComputerName\" 44 | 45 | With oShell 46 | .RegDelete sTcpipParamsRegPath & "Hostname" 47 | .RegDelete sTcpipParamsRegPath & "NV Hostname" 48 | 49 | .RegWrite sCompNameRegPath & "ComputerName\ComputerName", hostname 50 | .RegWrite sCompNameRegPath & "ActiveComputerName\ComputerName", hostname 51 | .RegWrite sTcpipParamsRegPath & "Hostname", hostname 52 | .RegWrite sTcpipParamsRegPath & "NV Hostname", hostname 53 | End With ' oShell -------------------------------------------------------------------------------- /windows2000/nic.vbs: -------------------------------------------------------------------------------- 1 | Const ssfCONTROLS = 3 2 | 3 | sConnectionName = "Local Area Connection" 4 | 5 | sEnableVerb = "En&able" 6 | sDisableVerb = "Disa&ble" 7 | 8 | set shellApp = createobject("shell.application") 9 | set oControlPanel = shellApp.Namespace(ssfCONTROLS) 10 | 11 | set oNetConnections = nothing 12 | for each folderitem in oControlPanel.items 13 | if folderitem.name = "Network and Dial-up Connections" then 14 | set oNetConnections = folderitem.getfolder: exit for 15 | end if 16 | next 17 | 18 | 19 | if oNetConnections is nothing then 20 | msgbox "Couldn't find 'Network and Dial-up Connections' folder" 21 | wscript.quit 22 | end if 23 | 24 | set oLanConnection = nothing 25 | for each folderitem in oNetConnections.items 26 | if lcase(folderitem.name) = lcase(sConnectionName) then 27 | set oLanConnection = folderitem: exit for 28 | end if 29 | next 30 | 31 | if oLanConnection is nothing then 32 | msgbox "Couldn't find '" & sConnectionName & "' item" 33 | wscript.quit 34 | end if 35 | 36 | bEnabled = true 37 | set oEnableVerb = nothing 38 | set oDisableVerb = nothing 39 | s = "Verbs: " & vbcrlf 40 | for each verb in oLanConnection.verbs 41 | s = s & vbcrlf & verb.name 42 | if verb.name = sEnableVerb then 43 | set oEnableVerb = verb 44 | bEnabled = false 45 | end if 46 | if verb.name = sDisableVerb then 47 | set oDisableVerb = verb 48 | end if 49 | next 50 | 51 | if bEnabled then 52 | WScript.Echo "" 53 | WScript.Echo "Disabling Local Area Connection ..." 54 | oDisableVerb.DoIt 55 | else 56 | WScript.Echo "" 57 | WScript.Echo "Enabling Local Area Connection ..." 58 | oEnableVerb.DoIt 59 | end if 60 | 61 | wscript.sleep 1000 -------------------------------------------------------------------------------- /windows2000/run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | pushd %~dp0 3 | 4 | echo( 5 | echo vGhetto Instant Clone Customization - Microsoft Windows 2000 6 | 7 | cscript /nologo nic.vbs 8 | 9 | echo( 10 | echo Freezing ... 11 | "C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" --cmd "instantclone.freeze" 12 | 13 | echo( 14 | echo Resumed from freeze ... 15 | echo( 16 | 17 | set ipcmd=""C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" --cmd "info-get guestinfo.ic.ipaddress"" 18 | 19 | FOR /F "tokens=*" %%i IN (' %ipcmd% ') DO SET IP=%%i 20 | 21 | set netmaskcmd=""C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" --cmd "info-get guestinfo.ic.netmask"" 22 | 23 | FOR /F "tokens=*" %%i IN (' %netmaskcmd% ') DO SET NETMASK=%%i 24 | 25 | set gatewaycmd=""C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" --cmd "info-get guestinfo.ic.gateway"" 26 | 27 | FOR /F "tokens=*" %%i IN (' %gatewaycmd% ') DO SET GATEWAY=%%i 28 | 29 | set dnscmd=""C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" --cmd "info-get guestinfo.ic.dns"" 30 | 31 | FOR /F "tokens=*" %%i IN (' %dnscmd% ') DO SET DNS=%%i 32 | 33 | set hostnamecmd=""C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" --cmd "info-get guestinfo.ic.hostname"" 34 | 35 | FOR /F "tokens=*" %%i IN (' %hostnamecmd% ') DO SET HOSTNAME=%%i 36 | 37 | cscript /nologo nic.vbs 38 | ping 1.1.1.1 -n 1 -w 1000>nul 39 | 40 | cscript /nologo ip.vbs %IP% %NETMASK% %GATEWAY% %DNS% %HOSTNAME% -------------------------------------------------------------------------------- /windows98/instantclone-windows-98.ps1: -------------------------------------------------------------------------------- 1 | Import-Module C:\Users\primp\Desktop\InstantClone.psm1 2 | 3 | Function Set-VMKeystrokes { 4 | <# 5 | .NOTES 6 | =========================================================================== 7 | Created by: William Lam 8 | Organization: VMware 9 | Blog: www.virtuallyghetto.com 10 | Twitter: @lamw 11 | =========================================================================== 12 | .DESCRIPTION 13 | This function sends a series of character keystrokse to a particular VM 14 | .PARAMETER VMName 15 | The name of a VM to send keystrokes to 16 | .PARAMETER StringInput 17 | The string of characters to send to VM 18 | .PARAMETER DebugOn 19 | Enable debugging which will output input charcaters and their mappings 20 | .EXAMPLE 21 | Set-VMKeystrokes -VMName $VM -StringInput "root" 22 | .EXAMPLE 23 | Set-VMKeystrokes -VMName $VM -StringInput "root" -ReturnCarriage $true 24 | .EXAMPLE 25 | Set-VMKeystrokes -VMName $VM -StringInput "root" -DebugOn $true 26 | #> 27 | param( 28 | [Parameter(Mandatory=$true)][String]$VMName, 29 | [Parameter(Mandatory=$false)][String]$StringInput, 30 | [Parameter(Mandatory=$false)][Boolean]$ReturnCarriage, 31 | [Parameter(Mandatory=$false)][Boolean]$DebugOn 32 | ) 33 | 34 | # Map subset of USB HID keyboard scancodes 35 | # https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2 36 | $hidCharacterMap = @{ 37 | "a"="0x04"; 38 | "b"="0x05"; 39 | "c"="0x06"; 40 | "d"="0x07"; 41 | "e"="0x08"; 42 | "f"="0x09"; 43 | "g"="0x0a"; 44 | "h"="0x0b"; 45 | "i"="0x0c"; 46 | "j"="0x0d"; 47 | "k"="0x0e"; 48 | "l"="0x0f"; 49 | "m"="0x10"; 50 | "n"="0x11"; 51 | "o"="0x12"; 52 | "p"="0x13"; 53 | "q"="0x14"; 54 | "r"="0x15"; 55 | "s"="0x16"; 56 | "t"="0x17"; 57 | "u"="0x18"; 58 | "v"="0x19"; 59 | "w"="0x1a"; 60 | "x"="0x1b"; 61 | "y"="0x1c"; 62 | "z"="0x1d"; 63 | "1"="0x1e"; 64 | "2"="0x1f"; 65 | "3"="0x20"; 66 | "4"="0x21"; 67 | "5"="0x22"; 68 | "6"="0x23"; 69 | "7"="0x24"; 70 | "8"="0x25"; 71 | "9"="0x26"; 72 | "0"="0x27"; 73 | "!"="0x1e"; 74 | "@"="0x1f"; 75 | "#"="0x20"; 76 | "$"="0x21"; 77 | "%"="0x22"; 78 | "^"="0x23"; 79 | "&"="0x24"; 80 | "*"="0x25"; 81 | "("="0x26"; 82 | ")"="0x27"; 83 | "_"="0x2d"; 84 | "+"="0x2e"; 85 | "{"="0x2f"; 86 | "}"="0x30"; 87 | "|"="0x31"; 88 | ":"="0x33"; 89 | "`""="0x34"; 90 | "~"="0x35"; 91 | "<"="0x36"; 92 | ">"="0x37"; 93 | "?"="0x38"; 94 | "-"="0x2d"; 95 | "="="0x2e"; 96 | "["="0x2f"; 97 | "]"="0x30"; 98 | "\"="0x31"; 99 | "`;"="0x33"; 100 | "`'"="0x34"; 101 | ","="0x36"; 102 | "."="0x37"; 103 | "/"="0x38"; 104 | " "="0x2c"; 105 | ""="0x28"; 106 | } 107 | 108 | $vm = Get-View -ViewType VirtualMachine -Filter @{"Name"=$VMName} 109 | 110 | # Verify we have a VM or fail 111 | if(!$vm) { 112 | Write-host "Unable to find VM $VMName" 113 | return 114 | } 115 | 116 | if($StringInput -ne "") { 117 | $hidCodesEvents = @() 118 | foreach($character in $StringInput.ToCharArray()) { 119 | # Check to see if we've mapped the character to HID code 120 | if($hidCharacterMap.ContainsKey([string]$character)) { 121 | $hidCode = $hidCharacterMap[[string]$character] 122 | 123 | $tmp = New-Object VMware.Vim.UsbScanCodeSpecKeyEvent 124 | 125 | # Add leftShift modifer for capital letters and/or special characters 126 | if( ($character -cmatch "[A-Z]") -or ($character -match "[!|@|#|$|%|^|&|(|)|_|+|{|}|||:|~|<|>|?]") ) { 127 | $modifer = New-Object Vmware.Vim.UsbScanCodeSpecModifierType 128 | $modifer.LeftShift = $true 129 | $tmp.Modifiers = $modifer 130 | } 131 | 132 | # Convert to expected HID code format 133 | $hidCodeHexToInt = [Convert]::ToInt64($hidCode,"16") 134 | $hidCodeValue = ($hidCodeHexToInt -shl 16) -bor 0007 135 | 136 | $tmp.UsbHidCode = $hidCodeValue 137 | $hidCodesEvents+=$tmp 138 | 139 | if($DebugOn) { 140 | Write-Host "Character: $character -> HIDCode: $hidCode -> HIDCodeValue: $hidCodeValue" 141 | } 142 | } else { 143 | Write-Host "The following character `"$character`" has not been mapped, you will need to manually process this character" 144 | break 145 | } 146 | } 147 | } else { 148 | # Convert return carriage to HID code format 149 | $hidCodeHexToInt = [Convert]::ToInt64("0x58","16") 150 | $hidCodeValue = ($hidCodeHexToInt -shl 16) + 7 151 | 152 | $tmp = New-Object VMware.Vim.UsbScanCodeSpecKeyEvent 153 | $tmp.UsbHidCode = $hidCodeValue 154 | $hidCodesEvents+=$tmp 155 | } 156 | 157 | # Add return carriage to the end of the string input (useful for logins or executing commands) 158 | if($ReturnCarriage) { 159 | # Convert return carriage to HID code format 160 | $hidCodeHexToInt = [Convert]::ToInt64("0x28","16") 161 | $hidCodeValue = ($hidCodeHexToInt -shl 16) + 7 162 | 163 | $tmp = New-Object VMware.Vim.UsbScanCodeSpecKeyEvent 164 | $tmp.UsbHidCode = $hidCodeValue 165 | $hidCodesEvents+=$tmp 166 | } 167 | 168 | # Call API to send keystrokes to VM 169 | $spec = New-Object Vmware.Vim.UsbScanCodeSpec 170 | $spec.KeyEvents = $hidCodesEvents 171 | ##Write-Host "Sending keystroke to $VMName ...`n" 172 | $results = $vm.PutUsbScanCodes($spec) 173 | } 174 | 175 | $SourceVM = "Windows98" 176 | 177 | $numOfVMs = 1 178 | 179 | $StartTime = Get-Date 180 | Write-host "" 181 | foreach ($i in 1..$numOfVMs) { 182 | $newVMName = "IC-Win98-$i" 183 | 184 | $guestCustomizationValues = @{ 185 | "guestinfo.ic.sourcevm" = "$SourceVM" 186 | } 187 | $ipStartingCount++ 188 | New-InstantClone -SourceVM $SourceVM -DestinationVM $newVMName -CustomizationFields $guestCustomizationValues 189 | Start-Sleep -Seconds 2 190 | $VM = Get-VM -Name $newVMName 191 | Write-Host "Hot Adding Flexible Network Adapter ..." 192 | New-NetworkAdapter -VM $vm -NetworkName "VM Network" -Type Flexible -StartConnected | Out-Null 193 | Write-Host "Sending keystrokes to configure adapter ..." 194 | Start-Sleep -Seconds 2 195 | Set-VMKeystrokes -VMName $VM -StringInput "" 196 | Start-Sleep -Seconds 1 197 | Set-VMKeystrokes -VMName $VM -StringInput "" 198 | Start-Sleep -Seconds 1 199 | Set-VMKeystrokes -VMName $VM -StringInput "" 200 | Start-Sleep -Seconds 1 201 | Set-VMKeystrokes -VMName $VM -StringInput "" 202 | Start-Sleep -Seconds 1 203 | Set-VMKeystrokes -VMName $VM -StringInput "" 204 | Write-Host "Sleeping for 23 seconds waiting for adapter to be ready ..." 205 | Start-Sleep -Seconds 23 206 | Set-VMKeystrokes -VMName $VM -StringInput "N" 207 | } 208 | 209 | $EndTime = Get-Date 210 | $duration = [math]::Round((New-TimeSpan -Start $StartTime -End $EndTime).TotalMinutes,2) 211 | 212 | Write-Host -ForegroundColor Cyan "`nTotal Instant Clones: $numOfVMs" 213 | Write-Host -ForegroundColor Cyan "StartTime: $StartTime" 214 | Write-Host -ForegroundColor Cyan " EndTime: $EndTime" 215 | Write-Host -ForegroundColor Green " Duration: $duration minutes" -------------------------------------------------------------------------------- /windows98/run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo( 4 | echo vGhetto Instant Clone Customization - Microsoft Windows 98 5 | 6 | echo( 7 | echo Freezing ... 8 | "C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" --cmd "instantclone.freeze" --------------------------------------------------------------------------------