Enable and Disable ESXi Host SSH with PowerCLI | VMHostService Cmdlet

Maybe you’re upgrading your hosts, maybe you’re trying to run a command on multiple ESXi Hosts, any which way one thing which you will have to do is enable SSH from the vCenter, and disable when you’re done – because annoying as it is, security is important! 😉 It would be especially annoying if you have to do that for dozens of ESXi hosts at a time.

So here I’ll show you guys a simple script you can run to enable and then disable SSH on multiple ESXi hosts so that you can go ahead and do your main task instead of being distracted by side quests!

Enable SSH on ESX host

$host_list = Get-Content "host_list.txt"


Connect-VIServer $vcenter 


foreach($hosts in $host_list){
	Get-VMHostService -VMHost $hosts | Where-Object {$_.Key -eq "TSM-SSH" } | Start-VMHostService -confirm:$false 
}


Disconnect-VIServer * -confirm:$false 

If you’ve followed the blog you will know I like to follow the Get-Content method to get a list of things (in this case list of ESXi Hosts) from a simple text file (separated by new lines). You can follow how to use Get-Content here

The real star of the show is this guy right here:

Get-VMHostService -VMHost $hosts | Where-Object {$_.Key -eq "TSM-SSH" } | Start-VMHostService -confirm:$false 

We use the Get-VMHostService cmdlet to output the list of services that is available on the ESX host. From there we pipe that list and search for “TSM-SSH” service. Once that is filtered we pipe that service over to the Start-VMHostService cmdlet which will enable SSH on the host. This usually triggers a “Are you sure?” on the shell but since we need things as automated as possible we disable that with -confirm:$false

That’s it! Simples!

Disable SSH on ESX host

$host_list = Get-Content "host_list.txt"

Connect-VIServer $vcenter 


foreach($hosts in $host_list){
	Get-VMHostService -VMHost $hosts | Where-Object {$_.Key -eq "TSM-SSH" } | Stop-VMHostService -confirm:$false 
}


Disconnect-VIServer * -confirm:$false 

This is exactly the same as above except that instead of piping the filtered SSH service to “Start-VMHostService” cmdlet, we pipe it to “Stop-VMHostService” cmdlet. Self explanatory really (works out because I’m lazy to type at this point xD)

And that is it! It makes me feel validated if you like, share, comment if you found this useful (no pressure 😉 )! Social Media Links are below

Happy Scripting!

Getting Snapshot details of Virtual Machines | Get-Snapshot Cmdlet | PowerCLI

Are you a vSphere Admin facing complaints of Virtual Machine slowness? Are rogue, stale and abandoned Snapshots infesting your infrastructure? Boy have I got the script for you!

Sorry about the “as seen on TV” intro, but as a vSphere admin sometimes snapshots do get out of hand. Below is a simple little one-liner using Get-Snapshot Cmdlet to get a list of all snapshots in your environment.

The One-Liner

Get-VM | Get-Snapshot | Select @{Label = "VM"; Expression = {$_.VM}}, @{Label = "Snapshot Name";Expression = {$_.Name}}, @{Label = "Created Date"; Expression = {$_.Created}} , @{Label = "Snapshot Size"; Expression = {$_.SizeGB}} | Export-Csv "snapshot_details.csv"

Script breakdown:

The one-liner will output:

  • The virtual machine which has the snapshot
  • The name of the snapshot
  • The date the snapshot was created
  • The size of the snapshot

This one is fairly simple.

Get-VM when executed alone gets the list of all VMs of the vCenter, which is then piped to (executes like a foreach loop on the next command) the Get-Snapshot Cmdlet which gets all the information of a snapshot of that particular VM (like you specified it like this – Get-Snapshot -VM vm_name)

Then we simply select what we want to output. The Get-Snapshot Cmdlet fetches the following data:

To select, simply add a @{Label = “basically the column name”; Expression = {$_.theParameterThatYouWant}} block to the SELECT statement of the one-liner. You can add as many columns like this as you want separated by commas.

And that is it. In a future post maybe I will pursue how to select snapshots that are older than x number of days and things like that. But until that day comes, hope you enjoyed this one and found it to be useful!

Leave a comment, share and follow me on Social Media! Happy Scripting!

Get the ISO Path of mounted CDs on VMs | Get-CDDrive Cmdlet

Has it happened to you that you see VMs that do not have any associated disks in certain datastores show up in those datastores, also not allowing vMotions as well leaving you confused? Well it could be that there are ISOs in that datastore mounted to those VMs! This is tedious when you are doing datastore cleanups and what not. In this post we’ll get to the bottom of creating a script that will generate a list of VMs with ISOs mounted and their paths so that you can deal with them as you wish.

There are two ways to get this, the lazy one-liner way and the a more comprehensive script. Both versions use the Get-CDDrive Cmdlet to pull the CD drive information of a VM. Lets discuss both shall we :

The lazy One-Liner

This one liner will output a csv containing ISO paths of all the VMs in the vCenter (even on the VMs without an ISO mounted to them). If you don’t mind that – this is the easiest way to get this done.

Get-VM | Select Name, @{Label="ISO file"; Expression = { ($_ | Get-CDDrive).ISOPath }} | Export-Csv "vms_with_isos.csv"

This is fine for a small vCenter with a few VMs, but is very inconvenient for a large vCenter when the output file is a few thousand lines long. So lets look at a script that will only get the VMs with ISOs mounted to them.

The Comprehensive script

$vcenter = "vcenter_name"

$vm_list_with_iso = @()

Connect-VIServer $vcenter 

$vmlist = Get-VM 

foreach($vm in $vmlist){
	$cdinfo = Get-CDDrive $vm
	
	if($cdinfo.IsoPath -ne $null){
		
		$details = @{
			VM_name = $vm.name
			ISOPath = $cdinfo.IsoPath

		} 

		$vm_list_with_iso += New-Object PSObject -Property $details | Select VM_name,ISOPath

	}

}

$vm_list_with_iso | Export-Csv "vms_with_isos.csv"

Even though the script seems bigger, whats different is the “if” statement where it checks whether the ISOPath output by the Get-CDDrive Cmdlet is equal to $null (null variable used by powershell) or not. If its not null then that means an ISO is mounted.

And that is it!

If you liked it, please share the news! Happy Scripting!

get-list-of-vms-in-esx-host

Get the list of Virtual Machines on a ESXi Host with Get-VMHost | PowerCLI

Recently I needed to create a script to get a list of all virtual machines in a specific ESXi host. Surprisingly I had to search high and low on the internet to figure this out.

This is perplexing I mean its very straightforward to get the VMs in a datastore with

Get-VM -Datastore <datastore_name>

you would think getting all the virtual machines on a ESXi host would be more important than that! Work on this VMware – give us a Get-VM -VMHost!

But I digress – this is how you get the list of virtual machines on a ESXi host… I mean I was ranting up there but it’s really not that difficult, just that there’s no proper documentation on it

Get-VMHost -Name <Host_name> | Get-VM

And that’s all there is to it. But it’s not that intuitive, you wouldn’t think piping through the host name to Get-VM would do anything right? Anyways this one-liner saved my bacon, and I hope it would be useful to you as well!

Till the next time – happy scripting!

Expanding an existing disk on a Virtual Machine with PowerCLI | Get-HardDisk & Set-HardDisk cmdlets

We recently had a sudden requirement to increase the C: drives of a set of VMs to assist with an Operating system patching process – its not practical to to manually do that one by one – so PowerCLI to the rescue. So if you get a scenario where you need to expand an existing disk of a virtual machine by a specified amount of GB (especially a bulk of VMs), the following script will make life much easier.

Get the current size of the required disk

Use the code below to get the size (in GB) of the harddisk in question (here I’m getting the size of “hard disk 1”)

$vm_info_dsk = (Get-HardDisk -VM $vm_name | Where-Object {$_.Name -eq "Hard Disk 1"}).CapacityGB

You can make this a more expandable/usable code by making the Hard disk number a variable as well. With this you can change the name of the Hard disk easily without having to replace all the instances where the name was used.

$hard_disk_number = "Hard Disk 1"

$vm_info_dsk = (Get-HardDisk -VM $vm_name | Where-Object {$_.Name -eq $hard_disk_number}).CapacityGB

Setting the hard disk to the new size

You can change the size of the disk using the Set-HardDisk command. Here I’m going to assume the size of the disk needs to be increased by 10GB

$space_to_increase = 10
$new_capacity = $vm_info_dsk + $space_to_increase

Get-HardDisk -VM $vm_name | Where-Object {$_.Name -eq "Hard Disk 1"} | Set-HardDisk -capacityGB $new_capacity -confirm:$false

How it all comes together (the complete script)

Lets see how to put this all in to a robust expandable script.

The script will read a list of vms from the vm_list.txt text file (vms should be separated by a new line) which would be useful for bulk list of VMs – for more clarity on Get-Content read that post here. To change any parameter (different disk size, different harddisk) simply change the relevant variable.

#Read list from a text file vm_list.txt - separated by a new line
$vm_list = Get-Content "vm_list.txt"

$vcenter = "vCenter1"
$space_to_increase = 20
$hard_disk_number = "Hard Disk 1"

Connect-VIServer $vcenter 


foreach($vm_name in $vm_list){
	write-host "Fetching information of $vm_name"
	$vm = Get-VM $vm_name

	$vm_info_dsk = (Get-HardDisk -VM $vm_name | Where-Object {$_.Name -eq $hard_disk_number}).CapacityGB

	Write-Host "$vm $hard_disk_number is $vm_info_dsk"

	$new_capacity = $vm_info_dsk + $space_to_increase

	Write-Host "new hard disk capacity $new_capacity"

	Get-HardDisk -VM $vm_name | Where-Object {$_.Name -eq $hard_disk_number} | Set-HardDisk -capacityGB $new_capacity -confirm:$false

#Check if it is successfully set and display the new size
	$vm_info_dsk = (Get-HardDisk -VM $vm_name | Where-Object {$_.Name -eq $hard_disk_number}).CapacityGB

	Write-Host "$vm new hard disk 1 is $vm_info_dsk"
}
	
Disconnect-VIServer -Confirm:$false