Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
publicScripts/powerCLI/New-UbuntuVM.ps1
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
269 lines (238 sloc)
10.6 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
Create a new Ubuntu 18 Virtual Machine on a vCenter server. | |
.DESCRIPTION | |
The New-UbuntuVM.ps1 function will create a new Ubuntu 18 Virtual Machine in vCenter | |
if the name does not already exist in the inventory. | |
You will present with two credential prompts. The first is to connect to vCenter and the second is local credentials on the template with sudo privileges. | |
The local account on the template must have NOPASSWD sudo access. | |
.EXAMPLE | |
.\New-UbuntuVM.ps1 -vCenterServer vCenter.fqdn -VMHostname VM.fqdn -VMIPv4 192.168.1.10/24 -VMGateway 192.168.1.1 -template OStemplate -datastore DS01 -Location "DataCenter01/VirtualMachines/Linux" -VMMemory 1024 -VMCPU 2 -VMDiskSize 30 | |
.EXAMPLE | |
.\New-UbuntuVM.ps1 -vCenterServer vCenter.fqdn -VMHostname VM.fqdn -VMHost vsphere1.fqdn -VMIPv4 192.168.1.10/24 -VMGateway 192.168.1.1 -template OStemplate -datastore DS01 -Location "DataCenter01/VirtualMachines/Linux" -VMMemory 1024 -VMCPU 2 -VMDiskSize 30 | |
.EXAMPLE | |
$VMArguments = @{ | |
vCenterServer = "vCenter.fqdn" | |
VMHostname = "VM.fqdn" | |
VMHost = "vsphere1.fqdn" | |
VMIPv4 = "192.168.1.10/24" | |
VMGateway = "192.168.1.1" | |
template = "OStemplate" | |
datastore = "DS01" | |
Location = "DataCenter01/VirtualMachines/Linux" | |
VMMemory = "1024" | |
VMCPU = "2" | |
VMDiskSize = "30" | |
} | |
.\New-UbuntuVM.ps1 @VMArguments | |
#> | |
Param( | |
#vCenter Server FQDN or IP Address | |
[Parameter( Mandatory=$True, HelpMessage="vCenter Server", Position=0 )] | |
[ValidateNotNullOrEmpty()][string]$vCenterServer | |
, #VMHost | |
[Parameter( HelpMessage="vSphere Host. Leave blank to auto-select", Position=1 )] | |
[string]$VMHost="*" | |
, #VM Hostname | |
[Parameter( Mandatory=$True, HelpMessage="VM Hostname", Position=2 )] | |
[ValidateNotNullOrEmpty()][string]$VMHostname | |
, #VM IPv4 Address and CIDR Subnet prefix | |
[Parameter( Mandatory=$True, HelpMessage="Vm IPv4 IP Address and prefix", Position=3 )] | |
[ValidateNotNullOrEmpty()][string]$VMIPv4 | |
, #VM IPv4 Default Gateway | |
[Parameter( Mandatory=$True, HelpMessage="VM IPv4 Gateway", Position=4 )] | |
[ValidateNotNullOrEmpty()][string]$VMGateway | |
, #Define DNS Servers for the VM | |
[Parameter( HelpMessage="VM DNS Servers", Position=5 )] | |
[string]$DNSNameServers="128.113.0.9, 128.113.28.67, 128.113.26.77" | |
, #Define the template that will be cloned | |
[Parameter( Mandatory=$True, HelpMessage="Template Name", Position=6 )] | |
[ValidateNotNullOrEmpty()][string]$template | |
, #Define the VM's datastore | |
[Parameter( Mandatory=$True, HelpMessage="Datastore Name", Position=7 )] | |
[ValidateNotNullOrEmpty()][string]$datastore | |
, #Define the Folder Location for the new VM (including DataCenter) | |
[Parameter( Mandatory=$True, HelpMessage="VM Location", Position=8 )] | |
[ValidateNotNullOrEmpty()][string]$Location | |
, #VM Memory | |
[Parameter( Mandatory=$True, HelpMessage="Memory [MB]", Position=9 )] | |
[ValidateNotNullOrEmpty()][int]$VMMemory | |
, #VM CPU | |
[Parameter( Mandatory=$True, HelpMessage="vCPU [count]", Position=10 )] | |
[ValidateNotNullOrEmpty()][int]$VMCPU | |
, #VM Disk Size | |
[Parameter( Mandatory=$True, HelpMessage="Disk [GB]", Position=11 )] | |
[ValidateRange(20,300)] | |
[ValidateNotNullOrEmpty()][int]$VMDiskSize | |
) | |
#$PSBoundParameters | |
function Get-IPv4SubnetMask { | |
param([Parameter( | |
ValueFromPipeline=$true)] | |
[int[]] | |
[ValidateRange(0, 32)] | |
$NetworkLength | |
) | |
process { | |
foreach ($Length in $NetworkLength) { | |
$MaskBinary = ('1' * $Length).PadRight(32, '0') | |
$DottedMaskBinary = $MaskBinary -replace '(.{8}(?!\z))', '${1}.' | |
$SubnetMask = ($DottedMaskBinary.Split('.') | ForEach-Object { [Convert]::ToInt32($_, 2) }) -join '.' | |
$SubnetMask | |
} | |
} | |
} | |
function Test-IPAddress($IPAddress) { | |
$Octet = '(?:0?0?[0-9]|0?[1-9][0-9]|1[0-9]{2}|2[0-5][0-5]|2[0-4][0-9])' | |
$IPv4Regex = "^(?:$Octet\.){3}$Octet$" | |
if (!($IPAddress.Contains('/'))) { | |
throw "No CIDR prefix found" | |
} | |
elseif (!(Get-IPv4SubnetMask $IPAddress.Split('/')[1])){ | |
throw "CIDR Prefix is formatted incorrectly" | |
} | |
elseif (!($IPAddress.Split("/")[0] -match $IPv4Regex)){ | |
throw "IP Address is formatted incorrectly" | |
} | |
} | |
function Start-VMPower { | |
param ([string] $VM) | |
if ((Get-VM $VM).powerstate -eq "PoweredOn"){ | |
Write-Output "------ $VM is already powered on. ------" | |
} else { | |
Write-Output "------ Starting $VM now. ------" | |
Start-VM $VM -Confirm:$false | |
do { | |
$status = (Get-VM $VM | Get-View).Guest.ToolsRunningStatus | |
Start-Sleep 10 | |
} until ($status -eq "guestToolsRunning") | |
return "ok" | |
} | |
} | |
function Get-VMPath { | |
param ([string] $VMPath) | |
$LocationArray = $VMPath.Split("/\\") # Split string using '/' or '\' | |
$command = "Get-Datacenter -name `""+$LocationArray[0]+"`"" | |
if (Invoke-Expression $command) { | |
for ($Location=1; $Location -lt $LocationArray.Length; $Location++) { | |
$command = $command+" | Get-Folder -Name `""+$LocationArray[$Location]+"`"" | |
} | |
return Invoke-Expression $command | |
}else{ throw } | |
} | |
function New-UbuntuVM { | |
# Validate $VMIPv4 | |
try { | |
Test-IPAddress( $VMIPv4 ) | |
}catch{ | |
Write-Error "VMIPv4: $_" | |
exit | |
} | |
# Check if PowerCLI is installed | |
if (!(Get-Module -Name VMware* -ListAvailable)) { | |
Write-Warning "VMware PowerCLI Module does not exist" | |
Write-Warning "Please Install PowerCLI With the below command" | |
Write-Output "-------------------------------------------------------------" | |
Write-Output "Install-Module VMware.PowerCLI -AllowClobber -Scope CurrentUser" | |
#Install-Module VMware.PowerCLI -AllowClobber -Scope CurrentUser | |
#Save-Module -Name VMware.PowerCLI -Path $home\Documents\WindowsPowerShell\Modules | |
Write-Output "-------------------------------------------------------------" | |
Exit | |
} | |
## Connect to vCenter | |
$VCSCred = $Host.UI.PromptForCredential("Please enter vCenter credentials", "Enter Credentials for $vCenterServer", "", "") | |
Write-Output "------ Connecting to vCenter Server ------" | |
if(!$(Connect-VIServer $vCenterServer -Credential $VCSCred)){ | |
throw | |
} | |
# Get VM settings | |
$VMShortHostname = $VMHostname.Split('.')[0] | |
$SubnetMask = Get-IPv4SubnetMask $VMIPv4.Split('/')[1] | |
$IPAddress = $VMIPv4.Split('/')[0] | |
$VMGuestCredential = $Host.UI.PromptForCredential("Please enter VM Guest Credentials", "Enter Credentials for $VMHostname", "", "") | |
if($VMGuestCredential -eq $null){ Write-Error "No VM Guest Credentials provided"; exit} | |
Write-Output "------ Variable Values ------" | |
Write-Output "`$VMHostname: $VMHostname" | |
Write-Output "`$VMShortHostname: $VMShortHostname" | |
Write-Output "`$vCenterServer: $vCenterServer" | |
Write-Output "`$VMHost: $VMHost" | |
Write-Output "`$VMIPv4: $VMIPv4" | |
Write-Output "`$IPAddress: $IPAddress" | |
Write-Output "`$SubnetMask: $SubnetMask" | |
Write-Output "`$VMGateway: $VMGateway" | |
Write-Output "`$template: $template" | |
Write-Output "`$datastore: $datastore" | |
Write-Output "`$Location: $Location" | |
Write-Output "`$VMMemory: $VMMemory" | |
Write-Output "`$VMCPU: $VMCPU" | |
Write-Output "`$VMDiskSize: $VMDiskSize" | |
Write-Output "`$VMGuestCred: $VMGuestCredential" | |
#Uncomment below to debug variables | |
#Disconnect-VIServer -Server $vCenterServer -Confirm:$false | |
#exit 0 | |
# Check if VM exists | |
if(Get-VM -name $VMHostname -ErrorAction SilentlyContinue){ | |
Write-Error "VM $VMHostname Already Exists" | |
exit | |
} | |
## Create VM | |
Write-Output "------ Creating Virtual Machine ------" | |
$NewVMHost = Get-VMHost $VMHost | Sort-Object -Property MemoryusageGB | Select-Object -First 1 | |
$NewVMLocation = Get-VMPath $Location | |
New-VM -Name $VMHostname -Template $template -VMHost $NewVMHost -Location $NewVMLocation -Datastore $datastore | |
## Set Resources | |
Write-Output "------ Setting Virtual Machine Memory and CPU ------" | |
Set-VM $VMHostname -MemoryMB $VMMemory -NumCpu $VMCPU -Confirm:$false | |
Write-Output "------ Setting Virtual Machine Hard Disk ------" | |
Get-HardDisk -VM $VMHostname|Set-HardDisk -CapacityGB $VMDiskSize -Confirm:$false | |
## Power on VM if not running | |
$VM_Power_State = Start-VMPower $VMHostname | |
if ($VM_Power_State -eq "ok"){ | |
Write-Output "------ $VMHostname Started ------" | |
} | |
## Run VM-Commands | |
$VMNetwork = " | |
# This file describes the network interfaces available on your system | |
# For more information, see netplan(5). | |
network: | |
version: 2 | |
renderer: networkd | |
ethernets: | |
ens192: | |
dhcp4: no | |
dhcp6: no | |
addresses: [$VMIPv4, ] | |
gateway4: $VMGateway | |
nameservers: | |
addresses: [$DNSNameServers] | |
" | |
$ConfigNetwork = " | |
sudo netplan generate | |
echo `"$VMNetwork`" | sudo tee /etc/netplan/01-netcfg.yaml | |
sudo netplan apply | |
sudo rm -f /etc/ssh/ssh_host_* | |
sudo dpkg-reconfigure openssh-server | |
" | |
Write-Output "------ Setting Virtual Machine Networking ------" | |
Invoke-VMScript -ScriptType bash -VM $VMHostname -ScriptText $ConfigNetwork -GuestCredential $VMGuestCredential | |
Write-Output "------ Updating Virtual Machine Packages ------" | |
$UpdateOS = "sudo apt-get update && sudo apt-get -y dist-upgrade" | |
Invoke-VMScript -ScriptType bash -VM $VMHostname -ScriptText $UpdateOS -GuestCredential $VMGuestCredential | |
$VMHostsFile = " | |
127.0.0.1 $VMhostname $VMShortHostname localhost | |
# The following lines are desirable for IPv6 capable hosts | |
::1 localhost ip6-localhost ip6-loopback | |
ff02::1 ip6-allnodes | |
ff02::2 ip6-allrouters | |
" | |
Write-Output "------ Setting Virtual Machine Hostname ------" | |
$ConfigHostsFile = "echo `"$VMHostsFile`" | sudo tee /etc/hosts && sudo hostnamectl set-hostname $VMShortHostname && echo $VMShortHostname | sudo tee /etc/hostname" | |
Invoke-VMScript -ScriptType bash -VM $VMHostname -ScriptText $ConfigHostsFile -GuestCredential $VMGuestCredential | |
## Restart VM | |
Write-Output "------ Restarting Virtual Machine ------" | |
Restart-VMGuest -VM $VMHostname -Confirm:$false | |
## Disconnect from vCenter | |
Write-Output "------ Disconnecting to vCenter Server ------" | |
Disconnect-VIServer -Server $vCenterServer -Confirm:$false | |
} | |
New-UbuntuVM | |