Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Microsoft.AVS.NFS/Microsoft.AVS.NFS.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = @(
"New-NFSDatastore",
"Remove-NFSDatastore"
"Remove-NFSDatastore",
"Get-NFSDatastoreNConnectValue"
)

# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
Expand Down
138 changes: 138 additions & 0 deletions Microsoft.AVS.NFS/Microsoft.AVS.NFS.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,141 @@ function Remove-NFSDatastore {
Write-Host "Datastore $($DatastoreName) unmounted successfully on $HostUnmountedCount/$HostCount hosts in cluster $($ClusterName)."
}

<#
.SYNOPSIS
Gets NFS NConnect value for a specific datastore across all hosts in a cluster.

.DESCRIPTION
Retrieves the NConnect (number of TCP connections) configuration for the specified NFS datastore
mounted on each host in the cluster.

.PARAMETER ClusterName
Name of the vSphere cluster to query for NFS NConnect information.

.PARAMETER DatastoreName
Name of the NFS datastore to retrieve NConnect value for.

.EXAMPLE
Get-NFSDatastoreNConnectValue -ClusterName "Cluster1" -DatastoreName "nfs-datastore-01"

.INPUTS
vCenter cluster name, NFS datastore name.

.OUTPUTS
NamedOutputs hashtable containing NConnect details per host.
#>
function Get-NFSDatastoreNConnectValue {
[CmdletBinding()]
[AVSAttribute(10, UpdatesSDDC = $false)]
Param (
[Parameter(
Mandatory = $true,
HelpMessage = 'vSphere Cluster name in vCenter')]
[ValidateNotNullOrEmpty()]
[String]
$ClusterName,

[Parameter(
Mandatory = $true,
HelpMessage = 'Name of NFS datastore to get NConnect value for')]
[ValidateNotNullOrEmpty()]
[String]
$DatastoreName
)

$ClusterName = Limit-WildcardsandCodeInjectionCharacters -String $ClusterName
$DatastoreName = Limit-WildcardsandCodeInjectionCharacters -String $DatastoreName

Write-Host "Collecting NConnect value for NFS datastore '$DatastoreName' across hosts in cluster '$ClusterName'"
Write-Host ""

$Cluster = Get-Cluster -Name $ClusterName -ErrorAction Ignore
if (-not $Cluster) {
throw "Cluster '$ClusterName' does not exist."
}

$Datastore = $Cluster | Get-Datastore -Name $DatastoreName -ErrorAction Ignore
if (-not $Datastore) {
throw "Datastore '$DatastoreName' not found on cluster '$ClusterName'."
}

# NFS datastores have Type 'NFS' (v3) or 'NFS41' (v4.1)
if ($Datastore.Type -notin @('NFS', 'NFS41')) {
throw "Datastore '$DatastoreName' is of type '$($Datastore.Type)'. This cmdlet only supports NFS datastores (NFS or NFS41)."
}

# Get only connected hosts (filter out disconnected/maintenance mode hosts)
$AllVMHosts = $Cluster | Get-VMHost -ErrorAction Ignore
if (-not $AllVMHosts) {
throw "No hosts found in cluster '$ClusterName'."
}

$VMHosts = $AllVMHosts | Where-Object { $_.ConnectionState -eq 'Connected' }
if (-not $VMHosts) {
throw "No connected hosts found in cluster '$ClusterName'. All hosts are disconnected or in maintenance mode."
}

$DisconnectedHosts = $AllVMHosts | Where-Object { $_.ConnectionState -ne 'Connected' }
if ($DisconnectedHosts) {
Write-Warning "Skipped $($DisconnectedHosts.Count) host(s) due to disconnected or maintenance state: $($DisconnectedHosts.Name -join ', ')"
}

$NamedOutputs = @{}
$HostsNotMounted = @()
$HostsFailed = @()

foreach ($VMHost in $VMHosts) {
try {
$EsxCli = Get-EsxCli -VMHost $VMHost -V2 -ErrorAction Stop
$NfsDatastores = $EsxCli.storage.nfs.list.invoke()

if (-not $NfsDatastores) {
$HostsNotMounted += $VMHost.Name
continue
}

$NfsDs = $NfsDatastores | Where-Object { $_.VolumeName -eq $DatastoreName }
if (-not $NfsDs) {
$HostsNotMounted += $VMHost.Name
continue
}

$IsNfsV41 = $NfsDs.NFSv41 -eq $true
$NConnectValue = if ($null -ne $NfsDs.Connections) { $NfsDs.Connections } else { "N/A" }

$NamedOutputs[$VMHost.Name] = "
{
DatastoreName : $($NfsDs.VolumeName),
NfsServerHost : $($NfsDs.Host),
SharePath : $($NfsDs.Share),
NfsVersion : $(if ($IsNfsV41) { '4.1' } else { '3' }),
NConnectValue : $NConnectValue,
Accessible : $($NfsDs.Accessible),
Mounted : $($NfsDs.Mounted)
}"
}
catch {
$HostsFailed += $VMHost.Name
Write-Error "Failed to query host '$($VMHost.Name)': $($_.Exception.Message)"
continue
}
}

if ($HostsNotMounted.Count -gt 0) {
Write-Warning "Datastore '$DatastoreName' not mounted on $($HostsNotMounted.Count) host(s): $($HostsNotMounted -join ', ')"
}

if ($HostsFailed.Count -gt 0) {
Write-Warning "Failed to query $($HostsFailed.Count) host(s): $($HostsFailed -join ', ')"
}

if ($NamedOutputs.Count -eq 0) {
throw "Failed to query all hosts in cluster '$ClusterName'. Check hosts connectivity."
}

Write-Host ($NamedOutputs | ConvertTo-Json -Depth 10)

Set-Variable -Name NamedOutputs -Value $NamedOutputs -Scope Global
Write-Host " "
}

Loading