A quick start to VMware automation
Do less to do more
VMware provides tools such as vCenter and vRealize. Here's a quick start on getting you onboarded with scripted tasks!
The CLI
Using the command line simply means that you will perform the same operation as you would with your mouse, but with a few lines of code instead.
Because there are UX people working on visual tools, they are obviously more user-friendly than a console view with no help or tips. If you need to complete a task, you must know the commands or have them saved somewhere as a cheatsheet. However, if you need to perform the same task 100 times, you must perform the same clicks manually each time. Using code allows you to do the same thing through a loop; basically, you just hit enter and the script does the rest.
Scripting takes time but can be repaid over time. This is why, before working on a script, we always consider recurrency. Should you spend 8 hours scripting a 5-minute job that you only do once a year?
The official tool
VMware PowerCLI is an official tool that VMware provides and supports.
This module is available from the PowerShell Gallery and can be easily installed on PowerShell starting with version 5.1 (Windows).
Install-Module -Name VMware.PowerCLI
Once installed, use the following command to connect to your environment.
Connect-VIServer -Server IP/Hostname -Protocol https
If you get a certificate issue, just ignore it with the following command.
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
Here is a list of useful scripts. These scripts work with an input file.
Before making any changes to the VM, check the free space on the Datastore.
This script receives a list of machines, reads them, determines which datastore is in use, and displays the remaining free space. This is useful to run prior to adding additional disks.
Input file
Input.csv with content :
HostName,DiskSize
vmansible001,300
# Check VM listed in the csv file
$tab = @()
$space = @()
$csv = Import-Csv .\input.csv
$csv | ForEach-Object {
$vm = Get-VM -Name $($_.HostName)
$datastore = $vm | Get-Datastore
$tab += $datastore.Name
$space += $datastore.FreeSpaceGB
Write-Output $tab","$space
}
Add a new disk to multiple VM
This script is excellent for attaching new disks to hundreds of virtual machines in a matter of seconds. The size of the disk can vary.
Input file
vCenter_AddDisk.csv with content :
HostName,DiskSize
myvm01,20
myvm02,20
myvm03,50
# Check all lines and ask if we can go on
$csv = Import-Csv .\vCenter_AddDisk.csv
$csv | ForEach-Object {
Write-Host "New disk of $($_.DiskSize)Go will be add to $($_.HostName)."
}
$validate = Read-Host -Prompt "Is this list seems legit ? (y/n)"
if ($validate -eq 'y') {
$csv | ForEach-Object {
Write-Host "Adding $($_.DiskSize)Go to $($_.HostName)..."
Get-VM $_.HostName | New-HardDisk -CapacityGB $_.DiskSize
Get-HardDisk -VM $_.HostName
} | Out-File .\vCenter_AddDisk.log
Write-Host "DONE"
}
else {
Write-Host "Aborting... "
exit
}
Check attached Disk to VM
This one can refer to the previous script to see if all added disks are visible. You can also direct the output to a file, which you provide to the requester.
vCenter_CheckDisk.ps1 > AddedDisk.log
Input file
Input.txt with content :
vmansible001
vmansible002
# Check VM listed in the txt file
function Get-VMDisks {
param(
[string]$VMName
)
$VMObj = Get-VM -Name $VMName
$Disks = Get-Harddisk -VM $VMObj
foreach ($disk in $Disks) {
$DiskName = $Disk.Name
$DisksizeinGB = ($Disk.CapacityKB * 1024) / 1GB
"{0}: {1} | " -f $DiskName, $DisksizeinGB
}
}
foreach ($vmlist in (Get-Content -Path '.\input.txt')) {
$vm = Get-VM -Name $vmlist
$Disk = Get-VMDisks $vmlist
Write-Output "The VM $vm have : $Disk"
}
Check NICs
If you want to export all NIC details used by some hosts, use this one.
Input file
vCenter_CheckNIC.txt with content :
vmansible001
vmansible002
# Check NIC in the txt file
foreach ($vmlist in (Get-Content -Path '.\vCenter_CheckNIC.txt')) {
if ((Get-VM -Name $vmlist).PowerState -ne 'PoweredOff') {
$vm_epg = Get-VM -Name $vmlist | Get-NetworkAdapter
$vm_ip = (Get-VM -Name $vmlist ).Guest.Nics
Write-Host "The VM"$vmlist" have the following adapters ⤵"
foreach ($NIC in $vm_epg) {
Write-Host $NIC.Name "→ Type is" $NIC.Type "| NIC name is" $NIC.NetworkName "► MAC :" $NIC.MacAddress
}
Write-Host "Detail of these adapters :"
foreach ($NIC in $vm_ip) {
Write-Host "○" $NIC.Device "DVPortGroup ‣"$NIC.NetworkName "| Assigned IP :"$NIC.IPAddress
}
Write-Host "------------------------------------------------------------------------------------------------------------------------------------------------------"
}
}
Check VM Status
Used to show quickly the status of a VM, CPU and RAM. This is important to run before and after changes
Input file
vCenter_CheckVM.txt with content :
vmansible001
vmansible002
foreach($vmlist in (Get-Content -Path '.\vCenter_CheckVM.txt')){
$vm = Get-VM -Name $vmlist
$vm
}
Start a list of VM
This one is obviously a must have after the changes
Input file
vCenter_StartVM.txt with content :
vmansible001
vmansible002
# Start VM listed in the txt file
foreach($vmlist in (Get-Content -Path '.\vCenter_StartVM.txt')){
$vm = Get-VM -Name $vmlist
Start-VM -VM $vm -Confirm:$false
}
Shutdown a list of VM
This is obviously another must-have before making changes.
Input file
vCenter_ShutdownVM.txt with content :
vmansible001
vmansible002
# Shutdown VM listed in the txt file
foreach($vmlist in (Get-Content -Path '.\vCenter_ShutdownVM.txt')){
$vm = Get-VM -Name $vmlist
Shutdown-VMGuest -VM $vm -Confirm:$false
}
Move VM from one storage to another
This is useful if you need to move a large number of virtual machines in a single step. The script will determine which VMs are in the source storage and will skip any ExcludedVMs. When the process is finished, the VM will be stopped, moved, and then restarted.
Take care not to shut down vCenter or the VPN VM if you are running it from a remote location.
# Variables
$SourceDatastore = "iscsi_nas10"
$DestinationDatastore = "strnas01b5"
$ExcludedVM = @("myvm01","myvpn01","myvcenter01","myapp01")
$VMToMigrate = @()
# Functions
function Get-InstanceList (){
$VmList = Get-VM -Datastore $SourceDatastore
foreach($VM in $VMList){
if($VM -in $ExcludedVM)
{
Write-Host "The VM"$VM "will not be migrate"
}
else {
$VMToMigrate = $VMToMigrate + $VM
}
}
Write-Host "To migrate :"
foreach($Element in $VMToMigrate){
Write-Host $Element
}
return $VMToMigrate
}
function Set-ShutdownInstance(){
## Shutdown instances
Write-Host "Cheking which instances are Powered On to gracefully shut them down"
foreach($VM in $VMToMigrate){
$VMStatus = @()
$VMStatus = (Get-VM $VM).PowerState
$VMToShutdown = @()
if($VMStatus -eq "PoweredOn"){
Write-Host "Instance" $VM "is PoweredOn"
$VMToShutdown = $VMToShutdown+ $VM
Stop-VM $VM -Confirm:$false
}
else{
Write-Host "Instance" $VM "is already PoweredOff"
}
}
## Verify that all instances are shutdown
Write-Host "Checking that all instances are PoweredOff"
foreach ($VM in $VMToShutdown){
if((Get-VM $VM).PowerState -eq "PoweredOn"){
Do{Stop-VM $VM -Confirm:$false}
Until((Get-VM $VM).PowerState -eq "PoweredOff")
}
}
}
function Set-MoveInstances(){
foreach($VM in $VMToMigrate){
Move-VM $VM -Datastore $DestinationDatastore -Confirm:$false -RunAsync
Start-Sleep -Seconds 3
}
}
function Get-CheckDatastoreRemaining(){
Get-VM -Datastore $SourceDatastore
}
function Set-VMStart(){
foreach ($VM in $VMToShutdown){
Start-VM $VM
}
}
# Code
$VMToMigrate = Get-InstanceList
$Validation = Read-Host -Prompt 'Is the list looking good ? (y/n)'
If($Validation -eq "y"){
Set-ShutdownInstance
Set-MoveInstances
Get-CheckDatastoreRemaining
Set-VMStart
}
Delete a list of VM
When decommissioning is approved, run this to quickly remove the VM. The argument "-DeletePermanently" is used to request removal from the datastore as well.
Input file
vCenter_DeleteVM.txt with content :
vmansible001
vmansible002
# Delete VM listed in the txt file
foreach($vmlist in (Get-Content -Path '.\vCenter_DeleteVM.txt')){
$vm = Get-VM -Name $vmlist
Remove-VM -VM $vm -Confirm:$false -DeletePermanently
}
Change CPU and RAM to a list of VM
Input file
AddCPUandRAM.csv with content :
HostName,oldCPU,oldRAM,CPU,RAM
vm-l-p-customer01,16,64,24,256
vm-l-p-customer02,16,64,24,256
vm-l-p-customer03,16,64,24,256
# Check all lines and ask if we can go on
$csv = Import-Csv .\AddCPUandRAM.csv
$checkOldValues = Read-Host -Prompt "Do you want to run a check on values listed on the file ? (y/n)"
if ($checkOldValues -eq 'y')
{
$csv | ForEach-Object {
$vm = Get-VM $_.HostName
$vCenterVMCPU = $vm | Select-Object NumCpu
$vCenterVMRAM = $vm | Select-Object MemoryGB
Write-Host "Host : $($_.HostName) | CSV CPU = $($_.oldCPU) & RAM = $($_.oldRAM) | vCenter CPU = $vCenterVMCPU & RAM = $vCenterVMRAM."
if ($_.oldCPU -ne $vCenterVMCPU) {
Write-Host "CPU in CSV is not correct" -ForegroundColor Red -BackgroundColor Yellow
}
elseif ($_.oldRAM -ne $vCenterVMRAM) {
Write-Host "RAM in CSV is not correct" -ForegroundColor Red -BackgroundColor Yellow
}
else {
Write-Host "Values are consistent" -ForegroundColor Green
}
}
}
$validate = Read-Host -Prompt "Apply changes ? (y/n)"
if ($validate -eq 'y')
{
$csv | ForEach-Object {
$vm = Get-VM $_.HostName
Write-Host "Processing $($_.HostName) ..."
$vm | Set-VM -MemoryGB $($_.RAM) -NumCpu $($_.CPU)
$vm | Select-Object Name,NumCpu,MemoryGB
} | Out-File .\AddCPUandRAM.log
Write-Host "DONE"
}
else {
Write-Host "Aborting... "
exit
}
The CLI
These are only a few PowerCLI examples; in a future blog post, we may share more advanced scripts made using vRa API calls. So make sure to keep an eye on our social media!