Friday, March 8, 2024

Cluster HA Admission Control

HA Admission control Definition 

vSphere HA uses admission control to ensure that sufficient resources are reserved for virtual machine recovery when a host fails.

Admission control imposes constraints on resource usage. Any action that might violate these constraints is not permitted. Actions that might be disallowed include the following examples:

a)     Powering on a virtual machine

b)     Migrating a virtual machine

c)     Increasing the CPU or memory reservation of a virtual machine

HA Admission control Types

The basis for vSphere HA admission control is how many host failures your cluster is allowed to tolerate and still guarantee failover. The host failover capacity can be set in three ways:

a)     Cluster resource percentage

b)     Slot policy

c)     Dedicated failover hosts

 Cluster resource percentage:

You can configure vSphere HA to perform admission control by reserving a specific percentage of cluster CPU and memory resources for recovery from host failures.

Select the Percentage of Cluster Resources Reserved admission control policy. This policy offers the most flexibility in terms of host and virtual machine sizing. When configuring this policy, choose a percentage for CPU and memory that reflects the number of host failures you want to support. For example, if you want vSphere HA to set aside resources for two host failures and have ten hosts of equal capacity in the cluster, then specify 20% (2/10). 

Connect via vSphere web client > Home > Hosts and clusters > Select your Cluster object > Configure > vSphere Availability > Admission Control > Click the Edit button.

Under Define host failover capacity > Select Cluster resource percentage > Click check box “Override calculated failover capacity” > Click OK 

This is the best practice we are using in our environment. The Cluster failover reservation percentage can be found under this network drive for all the clusters.

Slot policy

In this case, the default is to “cover all powered-on VMs” and basically, it calculates the slot size based on the maximum CPU/Memory reservation and overhead of all powered-on VMs.

You can also change to the second radio button and use a fixed slot size. In this case, the default what vSphere is proposing (but you can override) is:

When you click the Calculate button, you can then click the View link, which opens a pop-up window showing which VMs are not “guaranteed to have unfragmented failover capacity”

Dedicated failover hosts

This option, where you basically dedicate one of your hosts to be reserved for failover, is very little used. VMware, however, still provides this option. It is not very effective as the host cannot run any VMs (normally), and just wait for failover to happen.

When failover occurs, the VMs which were running on the failed host, are restarted on this dedicated host.

Limitations:

1) No VMs can be started on this host

2) DRS cannot use this host for rebalancing operations

3) No vMotions to this host

 

Can I disable VMware vSphere HA admission control?

Yes, you can. However, without it, you have no assurance that your VMs which lives within your cluster, can be restarted after a hardware failure. VMware does not recommend to permanently disable admission control.

Admission control is a very useful function to protect your workloads. Without proper understanding, or even disabling admission control your VMs might not restart at all when a failure occurs. By assuring that there are enough resources within your cluster, depending on how many hosts and resources is present, admission control regulates the resources to make sure that there is enough resources available for restarting all VMs.

By assuring that there are enough resources within your cluster, depending on how many hosts and resources is present, admission control regulates the resources to make sure that there is enough resources available for restarting all VMs.

Thursday, December 1, 2022

PowerCLI script to move/migrate virtual machines to datastore and convert to thin provisioning

 PowerCLI script to move/migrate virtual machines to datastore and convert to thin provisioning


Connect-VIServer vcenter-server

$input = Import-Csv C:\Temp\vmlist.csv

foreach ($row in $input)

{

    $VMName=$row.VMName

    $DSName=$row.DSName

    Move-VM -VM $VMName -Datastore (Get-Datastore $DSName) -DiskStorageFormat Thin -RunAsync

}

Disconnect-VIServer vcenter-server -Confirm:$false


<#

Content of vmlist.csv

VMName,DSName

vm1,DS1

vm2,DS8

vm3,DS6

#>

Tuesday, October 19, 2021

Snapshot report using PowerCLI script

 Snapshot report using PowerCLI script


#### HTML Output Formatting #######

$a = "<style>"

$a = $a + "BODY{font-family:Calibri;font-size:12pt;}"

$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse; padding-right:5px}"

$a = $a + "TH{border-width: 1px;padding: 5px;border-style: solid;border-color: black;color:black;background-color:#FFFFFF }"

$a = $a + "TD{border-width: 1px;padding: 5px;border-style: solid;border-color: black;background-color:Silver}"

$a = $a + "</style>"


Connect-VIServer vcenterserver

Remove-Item D:\temp\SnapshotReport.html

$CurrentDate = Get-Date

$CurrentDate = $CurrentDate.ToString('dd-MMM-yyyy')

$HeadLines = "<BR><i>Snapshot Report - $CurrentDate </i>"


$post = "<BR><i>Snapshots older than 10 Days as of $CurrentDate </i>"

Get-VM | ?{$_.PowerState -eq "PoweredOn"} | Get-Snapshot | Where-Object {$_.Created -lt (Get-Date).AddDays(-10)} | Select-Object VM, Description, Created, @{Label=”Age”;Expression={(New-TimeSpan -Start $_.Created -End (Get-Date)).Days}}, @{Label=”SizeGB”;Expression={“{0:N2} GB” -f ($_.SizeGB)}} | Sort-Object "Age" -Descending | ConvertTo-html -Head $a -PreContent $post -Body "<H2> </H2>" >> D:\temp\SnapshotReport.html


$body = [System.IO.File]::ReadAllText('D:\temp\SnapshotReport.html')

Send-MailMessage -To To@Mailaddress.com -From From@Mailaddress.com -Subject "Snapshot Report - $CurrentDate" -Body $body -SmtpServer smtp.Mailaddress.com -BodyAsHtml

Disconnect-VIServer vcenterserver -Confirm:$False

Monday, September 27, 2021

PowerShell Script to Add new Column to exisiting CSV file

 PowerShell Script to Add new Column to exisiting CSV file


$vmlists = Import-Csv 'D:\temp\file.csv'

$counter =  $vmlists.count

foreach($vm in $vmlists)

{

    $vmName=$vm.Name

    $NewColumnValue = Read-Host "Enter the DatastoreName for $vmName"

    $vm | Add-Member -NotePropertyName Datastore -NotePropertyValue $NewColumnValue

    $counter = $counter -1

    Write-Host $counter

}

$vmlists | Export-Csv 'D:\temp\file.csv' -NoTypeInformation



Exsisting CSV File:

"Name","PowerState","IP Address","NetworkName","Cluster","VMHost"

"vm1","PoweredOn","192.168.1.6","vlan1","cluster1","host01"

"vm2","PoweredOn","192.168.1.7","vlan2","cluster1","host02"


OutPut CSV File

"Name","PowerState","IP Address","NetworkName","Cluster","VMHost","Datastore"

"vm1","PoweredOn","192.168.1.6","vlan1","cluster1","host01","datastore01"

"vm2","PoweredOn","192.168.1.7","vlan2","cluster1","host02","datastore01"





Sunday, August 8, 2021

PowerCLI script to create snapshots for multiple VMs

PowerCLI script to create snapshots for multiple VMs


 #### HTML Output Formatting #######

$a = "<style>"

$a = $a + "BODY{background-color:Lavender ;}"

$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"

$a = $a + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:thistle}"

$a = $a + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:PaleGoldenrod}"

$a = $a + "</style>"

################################################################################################


################################################

# Snapshot Information

#################################################

Connect-VIServer vcenter_server

Remove-Item C:\Temp\Snapshot.html

$Date = Get-date -format F

$Name = Read-Host "Enter Your Name"

$Description = Read-Host "Enter the Requester Name & Reason"

$toAddr = Read-Host "Enter the To Email Address"

$vmname = gc C:\Temp\Servers.txt

get-vm $vmname | new-snapshot -name "$Name - $Date" -Description $Description -Quiesce -Memory | Select VM,Created,Name,Description | ConvertTo-html -Head $a -Body "<H2> </H2>" >> C:\Temp\Snapshot.html

$body = [System.IO.File]::ReadAllText('C:\Temp\Snapshot.html')

Send-MailMessage -To $toAddr -From From@Mailaddress.com -Subject "VMware Snapshots Created for the $Description" -Body $body -SmtpServer smtp.Mailaddress.com -BodyAsHtml

Disconnect-viserver vcenter_server -confirm:$false

#################### END of SCRIPT ####################################

PowerCLI script to schedule snapshots for multiple VMs

PowerCLI script to schedule snapshots


##############START OF FUNCTION###############

Function Get-VIScheduledTasks {

PARAM ( [switch]$Full )

if ($Full) {

  # Note: When returning the full View of each Scheduled Task, all date times are in UTC

  (Get-View ScheduledTaskManager).ScheduledTask | %{ (Get-View $_).Info }

} else {

  # By default, lets only return common headers and convert all date/times to local values

  (Get-View ScheduledTaskManager).ScheduledTask | %{ (Get-View $_ -Property Info).Info } |

  Select-Object Name, Description, Enabled, Notification, LastModifiedUser, State, Entity,

    @{N="EntityName";E={ (Get-View $_.Entity -Property Name).Name }},

    @{N="LastModifiedTime";E={$_.LastModifiedTime.ToLocalTime()}},

    @{N="NextRunTime";E={$_.NextRunTime.ToLocalTime()}},

    @{N="PrevRunTime";E={$_.LastModifiedTime.ToLocalTime()}}, 

    @{N="ActionName";E={$_.Action.Name}}

  }

}


Function Get-VMScheduledSnapshots {

  Get-VIScheduledTasks | ?{$_.ActionName -eq 'CreateSnapshot_Task'} |

    Select-Object @{N="VMName";E={$_.EntityName}}, Name, NextRunTime, Notification

}


Function New-VMScheduledSnapshot {

PARAM (

  [string]$vmName,

  [string]$runTime,

  [string]$notifyEmail=$null,

  [string]$taskName="$vmName Scheduled Snapshot"

)


# Verify we found a single VM

$vm = (get-view -viewtype virtualmachine -property Name -Filter @{"Name"="^$($vmName)$"}).MoRef

if (($vm | Measure-Object).Count -ne 1 ) { "Unable to locate a specific VM $vmName"; break }


# Validate datetime value and convert to UTC

try { $castRunTime = ([datetime]$runTime).ToUniversalTime() } catch { "Unable to convert runtime parameter to date time value"; break }

if ( [datetime]$runTime -lt (Get-Date) ) { "Single run tasks can not be scheduled to run in the past.  Please adjust start time and try again."; break }


# Verify the scheduled task name is not already in use

if ( (Get-VIScheduledTasks | ?{$_.Name -eq $taskName } | Measure-Object).Count -eq 1 ) { "Task Name `"$taskName`" already exists.  Please try again and specify the taskname parameter"; break }


$spec = New-Object VMware.Vim.ScheduledTaskSpec

$spec.name = $taskName

$spec.description = "Snapshot of $vmName scheduled for $runTime"

$spec.enabled = $true

if ( $notifyEmail ) {$spec.notification = $notifyEmail}

($spec.scheduler = New-Object VMware.Vim.OnceTaskScheduler).runAt = $castRunTime

($spec.action = New-Object VMware.Vim.MethodAction).Name = "CreateSnapshot_Task"

$spec.action.argument = New-Object VMware.Vim.MethodActionArgument[] (4)

($spec.action.argument[0] = New-Object VMware.Vim.MethodActionArgument).Value = "$vmName scheduled snapshot"

($spec.action.argument[1] = New-Object VMware.Vim.MethodActionArgument).Value = "Snapshot created using $taskName"

($spec.action.argument[2] = New-Object VMware.Vim.MethodActionArgument).Value = $false # Snapshot memory

($spec.action.argument[3] = New-Object VMware.Vim.MethodActionArgument).Value = $false # quiesce guest file system (requires VMware Tools)


[Void](Get-View -Id 'ScheduledTaskManager-ScheduledTaskManager').CreateScheduledTask($vm, $spec)

Get-VMScheduledSnapshots | ?{$_.Name -eq $taskName }

}


Function Remove-VIScheduledTask {

PARAM ([string]$taskName)

  (Get-View -Id ((Get-VIScheduledTasks -Full | ?{$_.Name -eq $taskName}).ScheduledTask)).RemoveScheduledTask()

}

##############END OF FUNCTION###############

Copy the above Function as a .ps1 file to this location: "C:\Windows\System32\WindowsPowerShell\v1.0"

You can then call these functions in your script.



##############BEGINNING OF SCRIPT###############

#### HTML Output Formatting #######

$a = "<style>"

$a = $a + "BODY{background-color:White ;}"

$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"

$a = $a + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:Green}"

$a = $a + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:PaleGoldenrod}"

$a = $a + "</style>"

################################################################################################


Connect-VIServer vcenter_server

Remove-Item  C:\Temp\ScheduleSnapshotReport.html


""

"Deleting all old scheduled snapshots that are already complete ..."


Get-VMScheduledSnapshots | ?{$_.NextRunTime -eq $null} | %{ Remove-VIScheduledTask $_.Name }


$report = @()

$date = Get-Date

$input = Import-Csv C:\Temp\server.csv


""

"Creating new scheduled snapshots ..."


foreach ($row in $input)

{

    $VMName=$row.VMName

    $Sched=$row.Schedule

    $Mail=$row.Email

    New-VMScheduledSnapshot $VMName $Sched "$Mail"

    $report += $row

}

$report | ConvertTo-html -Head $a -Body "<H2> </H2>" >> C:\Temp\ScheduleSnapshotReport.html

$body = [System.IO.File]::ReadAllText('C:\Temp\ScheduleSnapshotReport.html')

$text = '<font=Arial>Snapshots have been scheduled for the virtual machines listed below as per the specified date and time. A confirmation mail will be sent to the email mentioned upon completion of the snapshot.</font>'


""

"Sending a confirmation e-mail to To@MailAddress.com ..."


Send-MailMessage -To To@MailAddress.com -From From@MailAddress.com -Subject "Scheduled Snapshot Report - $date" -Body "$text $body" -SmtpServer smtp.MailAddress.com -BodyAsHtml


Disconnect-VIServer vcenter_server  -Confirm:$false


##############END OF SCRIPT###############

Content of server.csv





Sunday, July 25, 2021

PowerCLI script to remove the ISO from virtual machine

PowerCLI script to remove the ISO from virtual machine


Connect-VIServer vcenterserver

Get-CDDrive -VM (Get-Content D:\Scripts\CDRom\serverlist.txt) | Set-CDDrive -nomedia -Confirm:$false | Get-VMQuestion | Set-VMQuestion –Option "Yes"

Disconnect-VIServer vcenterserver -Confirm:$false