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:
- PowerGUI
- PowerCLI 4.1 Update 1
- VMWare vCenter 4.1
- ESX hosts ranging from 4.0 -> 4.1
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:
- Reads in a list of ESX hosts in a vCenter
- Iterate over all the data stores
- 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"