Identifying Datastores that aren’t mounted across all hosts in a vSphere cluster

Ensuring that your datastores are mounted across all hosts in a vSphere cluster is an important task that some may take for granted. By not doing so, you may be limiting the very reasons for which you clustered your ESXi hosts in the first place. For example, HA may not be able to start VM’s on another host if that host can’t access the VM’s datastore. This can sometimes be a very easy thing to miss especially if you’re rushing to build out your ESXi hosts. Thankfully PowerCLI can help us take inventory of our environments and show us what hosts can’t see datastores that other hosts in the cluster can see.

Running this script is simple and just requires you to enter your vcenter upon launch.

The script will then churn through your environment and export a CSV file which looks like this.

LAB01-02Cluster 2None
ESXi1 ATAvmspot-labesxi2.vmspot.lan;esxi3.vmspot.lan
LAB01-01Cluster 2None
ESXi1 SSD1vmspot-labesxi2.vmspot.lan;esxi3.vmspot.lan

As you can see, my LAB01-01 datastore is presented to more than one cluster. The script is smart enough to break things out and analyze both clusters individually. The third column shows the ESXi hosts in a given cluster that can’t see the datastore.

#Datastore Host Compliance v1.0
#9/25/2018 Matt Bradford @VMSpot www.VMSpot.com
#This script will look at all datastores and make sure it's presented to all ESXi hosts in a cluster. Data is output to a CSV file which will show what ESXi hosts in the cluster are not able to see the datastore.
#Usage - This script requires the user to enter a vCenter server to connect to. Example .\ClusterDatastores.PS1 -vcenter VC1.VMSPOT.LAN

[cmdletbinding()] Param([Parameter(ValuefromPipeline=$true,Mandatory=$true)][string]$vcenter) #Require a vCenter switch from the console and dump it to the variable $vcenter

Connect-VIServer $vcenter #Connect to the vCenter

function Get-DatastoreCompliance {
    $objReport = @() 

$datastores = Get-Datastore #Gather all Datastores for this vCenter

foreach ($datastore in $datastores){
    $hostclusters = Get-Datastore $datastore | Get-VMHost | Get-Cluster #Get each cluster this datastore is presented to

    foreach ($hostcluster in $hostclusters){

        $obj = @() #Create one time use array
        $obj = "" | Select-Object Datastore,Cluster,Missinghosts #Create the array headers

        $dshosts = Get-Datastore $datastore | Get-VMHost | ?{$_.Parent -eq $hostcluster} #Get each host in the cluster this datastore is presented to
        $clusterhosts = Get-Cluster $hostcluster | Get-VMHost #Get all hosts in the cluster
        $missinghosts = Compare-Object -ReferenceObject $clusterhosts -DifferenceObject $dshosts -PassThru #Compare all hosts in the cluster to the hosts the datastore is presented to
        $missinghosts = $missinghosts -join ';' #If there are several missing hosts, the output of Compare-Object will be an array which isn't CSV friendly. This just breaks the array apart and delimits with a semicolon
            $missinghosts = "None"
        } #If no hosts are missing, enter "None" instead of a blank value

        $obj.Datastore = $datastore #Add the datastore name to the array
        $obj.Cluster = $hostcluster #Add the ESXi Cluster name to the array
        $obj.Missinghosts = $missinghosts #Add the missing hosts to the array

        $objReport += $obj #Add values from one time use array to the function's output array
$objReport #Output the final array

Get-DatastoreCompliance | Export-CSV -notype datastorecompliance_$vcenter.csv #Output the function to a CSV

Matt Bradford

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.