Automate NFS mount creation on ESX hosts with PowerCLI


It can get tedious to go through and manually add/remove/update NFS Mounts on ESX hosts in a vCenter environment. Fortunately VMWare provides a slick solution which can be easily implemented if you are familiar with Microsoft PowerShell

 

Notes:

 

I like to use PowerGUI when creating/editing powershell scripts as it provides Syntax Highlighting and debugging. My previous tool of choice (notepad) was severely lacking in these areas.

After downloading & installing PowerCLI you will be able to create scripts which can:

  • Grab a list of hosts in a vCenter
  • Iterate over their data stores
  • Find the type of datastore (NFS, Direct attached, etc…)
  • Perform state-altering changes to the ESX hosts
  • Much, much more. Seee the Documentation for details

 

Here are some key snippets from a script I put together which:

  1. Reads in a list of ESX hosts in a vCenter
  2. Iterate over all the data stores
  3. Create new NFS data stores based off of the ESX host location name

 

# -------------- Connect to vCenter, Grab a list of ESX hosts ---------------- #

Write-Host "Connecting to vCenter server"
$DateTimeBegin = Get-Date
Connect-VIServer -Server 10.10.10.220 vDomain\nistadmin
Write-Host "Gathering list of ESX Hosts"
$VMHosts = Get-VMHost

 

# ---------- For each ESX host, start the NFS mount change process ---------- #
$VMHosts | ForEach-Object {
$VMHName = $_.name
DetermineNewIPAddress $VMHName
}

function CheckNFSMounts($VMHostName, $NFSIP, $SubnetStr)
{
Write-Host "Entering CheckNFSMounts with parameters: " $VMHostName " and " $NFSIP
#----- Get a list of datastores from the ESX host -----#
Write-Host "Gathering a list of Datastores on ESX Host: " $VMHostName
$datastores = Get-Datastore -VMHost $VMHostName
#----- Gather a list of all NFS Datastores -----#
Write-Host "Determining NFS Datastores"

 

# ----- Create a new array of Datastores ----- #
$NFSDatastores = @()
$datastores | ForEach-Object {
if($_.type -eq "NFS")
{
$DatastoreView = $_ | Get-View
$NFSDatastores += $DatastoreView.Summary
}
}

#----- If the datastores are of type NFS and the source IP is equal to $OldNFSIP, remove & readd (or just add if remove is commented out) using $NewNFSIP -----#
if($NFSDatastores.count -lt 5)
{
# Checks that $NFSDatastores is not NULL (there are NFS datastores to parse)
# Do a regex to ensure that the NFS mount has the IP Address of the NetApp before continuing
Write-Host "Determining whether or not the NFS mount is to the NetApp"
$NFSDatastores | ForEach-Object{
$datastore = $_
switch -regex ($_.Url)
{
$OldNFSIP { SwapNFSMounts $datastore $VMHostName $NFSIP $SubnetStr; break}
}
}
}
else
{
# If the ESX host has more than 4 data stores, don't add as it will exceed the limit of 8 on a device
# We ended up just "adding" rather than removing to minimize impact to our users 

Write-Host "ESX Host " $VMHostName "has too many Datastores mounted. Unable to create Datastores on new NetApp Interface"
}
Write-Host "---------------------------"
}

# --------- Function which will swap the NFS Mounts based on input criteria --------- #
function SwapNFSMounts($datastore, $VMHostName, $NFSIP, $SubnetStr)
{
Write-Host "Entering SwapNFSMounts with parameters: " $datastore.name " and " $VMHostName " and " $NFSIP

# ----- Remove old NFS Mount ----- #
Write-Host "Removing Datastore: " $datastore.name
|#Remove-Datastore -Datastore $datastore.Name -VMHost $VMHostName -Confirm:$false

# ----- Regex to pull out the NFS URL ----- #
$Regex = "(?<=netfs://"+$OldNFSIP+"/)[a-zA-Z0-9/\.\(\)_\-]+"
$NewNFSURLRaw = $datastore.url
$NewNFSURLRaw -match $Regex | Out-Null
$NewNFSURL = $matches[0]

# ----- Re-create the NFS mount using the correct IP Address & NFS URL ----- #
$DataStoreNameFixed = $datastore.name + "_`(" + $SubnetStr + "`)"
Write-Host "Creating Datastore: " $DataStoreNameFixed " with " $NewNFSURL " and " $NFSIP
New-Datastore -Nfs -VMHost $VMHostName -Name $DataStoreNameFixed -Path $NewNFSURL -NfsHost $NFSIP

Write-Host "---------------------------"
}

# -------------- Disconnect from vCenter -------------- #
Disconnect-VIServer -Server 10.10.10.220
$DateTimeEnd = Get-Date
$DateTimeDelta = $DateTimeEnd - $DateTimeBegin
Write-Host "Calculating Elapsed Time..."
Write-Host "Time elapsed: " $DateTimeDelta.TotalMinutes " Minutes"