Deploy Multi VM’s based on Windows Template

I love powershell. I created a little script to deploy multi VM based on a Windows Template throug CSV file.

It’s create a computer account at the specfified ou. He greates also a Domain Local Group for management. (It used in the customization not specified here)

TempVMlist.csv

server,cpu,memory,DestinationCluster,OSCustomizationSpec,VMtemplate,adgroup

WARDTEST01,2,8,CLUSTER01,W2012R2_Demo,TPL_W2012R2_STD,ServerAdmin

MultiVM.ps1

#Filename: MultiVM.ps1

#Author: W. Vissers

#Source:

#Version: 1.1

#Date: 08-05-2018

#ChangeLog:

# V1.0 – Module Active Directory

#      – Module VMware PowerCli

#      – Active Directory Computer Account, Group

#      – Host Selected from Cluster with Least Memory

#      – Storage selection based on volume with most free space

# V1.1 – Added Harddisk 1&2

#      – Changed porte group other vlan

#

<#

.SYNOPSIS

Script to create a virtual machine from template

.DESCRIPTION

Script to create a virtual machine from template

.EXAMPLE

MultiVM.ps1

#>

################################## INIT #################################################

# LoadModule Active Directory

if (!(Get-Module “activedirectory”)) {Import-module activedirectory}

Else {Write-Host “Module Active Directory is al ready loaded”}

# LoadModule VMware PowerCLI

# if (!(Get-Module “VMware.PowerCLI”)) {

#    Find-Module VMware.PowerCLI

#    Install-Module -Name VMware.PowerCLI -Scope CurrentUser

#}

#Else

# {

# Write-Host “Module PowerCLI is al ready loaded”

# }

#Config

$ouservers=”OU=Servers,DC=wardvissers.nl,DC=nl”

$ougroup=”OU=GroepObjecten,DC=wardvissers,DC=nl”

$folder=”Applicatie Servers”

$DestinationVC =”vcenter01.wardvissers.nl

#Username

if (!$username ) { $username = Read-Host “Give vCenter username ‘umcn\manz'”}

#Password

if ( -NOT $Password ) {

$PasswordSec = Read-Host “Give vCenter password” -AsSecureString

$Password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($PasswordSec))

}

#Connect vCenter

$ConnectVC = Connect-VIServer $DestinationVC -Username $Username -Password $Password -AllLinked

$AllVMs = @()

$AllVMs = Import-Csv “D:\TempVMlist.csv”

foreach ($vm in $AllVMs) {

#Haal De Gegevens op

$server=$($vm.server)

$memory=$($vm.memory)

$cpu=$($vm.cpu)

$DestinationCluster=$($vm.DestinationCluster)

$OSSpec=”$($vm.OSCustomizationSpec)”

$VMtemplate=$($vm.VMtemplate)

$group=$($vm.adgroup)

$harddisk1=$($vm.harddisk1)

$harddisk2=$($vm.harddisk2)

Write-Host “$server heeft $memory GB memory en $cpu cpu(‘s)”

if ($server.length -gt 15) {

Write-Output “Hostname cannot contain more than 15 characters.”

$server = Read-Host “Re-enter hostname for host $server”}

Else

{

Write-Host “Server is umc server”

#Maak AD Groep aan en Computer Account

New-ADComputer -Name $server -Path $ouservers -Enabled $true

New-ADGroup -Name “DLG.$server” -SamAccountName “DLG.$server” -GroupCategory Security -GroupScope DomainLocal -DisplayName “DLG.$server” -Path $ougroup

Add-ADGroupMember -Identity “DLG.$server” -Members $group

}

# Rol server uit van Template

# Select the host with the less used memory

$DestinationHost = Get-Cluster –Name $DestinationCluster –Server $DestinationVC | Get-VMhost -State Connected | Sort-Object -Property MemoryUsageGB | Select-Object -First1

# Select DataStore with the most free space and not in maintance

$destinationDatastore = Get-Cluster $DestinationCluster | Get-Datastore | Where {$_.State -ne “Maintenance”} | Sort-Object -Property FreeSpaceGB -Descending | Select-Object -First 1

# Finally, I deploy my VM with the New-VM cmdlet using my template and OS specs. I place the VM on the ESXi host and store the VM on the datastore.

New-VM -Name $server -Template $VMTemplate -OSCustomizationSpec $OSSpec -VMHost $DestinationHOST -Datastore $DestinationDatastore -Location $folder

Get-VM $server | Set-VM -NumCpu $cpu -MemoryGB $memory -Confirm:$false

if ($harddisk1 -gt 60){Get-HardDisk -vm $server | Where {$_.Name -eq “Hard disk 1”} | Set-HardDisk -CapacityGB $harddisk1 -Confirm:$false}

if ($harddisk2 -gt 20) {Get-HardDisk -vm $server | Where {$_.Name -eq “Hard disk 2”} | Set-HardDisk -CapacityGB $harddisk2 -Confirm:$false}

Get-VM $server | Start-VM -Confirm:$false

Get-VM $Server | Get-NetworkAdapter | Set-NetworkAdapter -Connected $true -Confirm:$false

}

Install VMware PowerCli

1. Install the Powershell Get Module

Installing items from the Gallery requires the latest version of the PowerShellGet module, which is available in Windows 10, in Windows Management Framework (WMF) 5.0, or in the MSI-based installer (for PowerShell 3 and 4).

With the latest PowerShellGet module, you can:

Supported Operating Systems

The PowerShellGet module requires PowerShell 3.0 or newer.

Therefore, PowerShellGet requires one of the following operating systems:

  • Windows 10
  • Windows 8.1 Pro
  • Windows 8.1 Enterprise
  • Windows 7 SP1
  • Windows Server 2016
  • Windows Server 2012 R2
  • Windows Server 2008 R2 SP1

PowerShellGet also requires .NET Framework 4.5 or above. You can install .NET Framework 4.5 or above from here.

2. Find-Module -Name VMware.PowerCLI

3. Install-Module -Name VMware.PowerCLI -Scope CurrentUser

4. When you start Powershell VMware.Powershell is automatically loaded