VMware Cloud Community
the3rdd
Contributor
Contributor
Jump to solution

Mount NFS to host

Alright I can mount an NFS Data Store using something like the following with the rest of the script populating the variables

New-Datastore -Nfs -VMHost $NEWHost -Name $Sharename -Path $remotePath -NfsHost $remoteHost | Out-Null

In a script and it works no problem. However this will only work for a single NFS share to all servers.

My issue is this, and I was hoping to be pointed in the right direction if possible.

I have multiple Datacenters, lets say Test01, Test02, and Test03. Within these centers I have physical Hosts as follows, Test01esx01, Test01esx02, Test02esx01, Test02esx02, and so forth.

Within each of these Datacenters I have a virtual machine that has an NFS share and named as follows, Test01NFS, Test02NFS, and so forth.

For each of these Datacenters I wish to mount the corresponding NFS share to the correct datacenter. So Test01NFS will mount to all Test01esx servers and then Test02NFS will mount to all Test02esx servers, and so forth. Any direction would be greatly appreciated.

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

To avoid possible problems with the quotes and substitution, I slightly changed the script.

Does this version produce the same errors ?

Get-Datacenter | where {$_.Name -notmatch 'nottest*'} | foreach {
    $DC = $_
   
$DC | Get-VMHost | %{         foreach ($DC.Name in $DC)         {             $NewName = $DC.Name             $Site = $NewName.substring(0,6)             $SiteNFS = $Site + "NFS"

            Write "DataCenter: $Site"
            Write "Mounting NFS $SiteNFS"
            if (!(Get-DataStore $SiteNFS -ErrorAction SilentlyContinue)) {                 if((Get-WmiObject -Class Win32_PingStatus -Filter "Address='$SiteNFS'").StatusCode -eq 0){                     New-Datastore -Nfs -VMHost $_ -Name $SiteNFS -Path /nfs -NfsHost $SiteNFS -ErrorAction SilentlyContinue | Out-Null
                }             }         }     } }


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
27 Replies
alanrenouf
VMware Employee
VMware Employee
Jump to solution

So your Setup looks like this ?

DC: Test01

Host: Test01esx01

Host: Test01esx02

Host: Test01esx03

DC: Test02

Host: Test02esx01

Host: Test02esx02

Host: Test02esx03

DC: Test03

Host: Test03esx01

Host: Test03esx02

Host: Test03esx03

All Hosts in Test01 need Test01NFS

All Hosts in Test02 need Test02NFS

All Hosts in Test03 need Test03NFS

Is this correct ?

Blog: http://virtu-al.net Twitter: http://twitter.com/alanrenouf Co-author of the PowerCLI Book: http://powerclibook.com
0 Kudos
the3rdd
Contributor
Contributor
Jump to solution

Correct. 

0 Kudos
alanrenouf
VMware Employee
VMware Employee
Jump to solution

Ok, Standby...

Blog: http://virtu-al.net Twitter: http://twitter.com/alanrenouf Co-author of the PowerCLI Book: http://powerclibook.com
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Would something like this work ?

foreach($i in 1..3){

  Get-Datacenter -Name ("Test0" + $i) | Get-VMHost | %{

    New-Datastore -Nfs -VMHost $_ -Name $sharename -Path $remotePath -NfsHost ("Test0" + $i + "NFS") | Out-Null

  }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

alanrenouf
VMware Employee
VMware Employee
Jump to solution

Holy crap your fast, I was working on a similar solution but grabbing the last two digits each time from the DC so we know which one we are in, that way it is more dynamic... ahh well,  Lucs is a nice fast solution Smiley Happy

Blog: http://virtu-al.net Twitter: http://twitter.com/alanrenouf Co-author of the PowerCLI Book: http://powerclibook.com
0 Kudos
the3rdd
Contributor
Contributor
Jump to solution

It looks like it would but the real world part of it would be equivelant to

EastDataCenter 

EastDataCenterHost01

EastDataCenterHost02

     EastDataCenterNFS

WestDataCenter

   WestDataCenterHost01

   WestDataCenterHost02

     WestDataCenterNFS

It would have to be name aware of sorts so that the East NFS was mounted to the East center and West NFS was mounted to the West Center.

0 Kudos
alanrenouf
VMware Employee
VMware Employee
Jump to solution

Like this:

Get-Datacenter | Foreach {
   $DC = $_
$DC | Get-VMHost | %{
    Write "DataCenter: $DC"
Write "Mounting NFS $($DC.Name)NFS"
New-Datastore -Nfs -VMHost $_ -Name $sharename -Path $remotePath -NfsHost ($DC + "NFS") | Out-Null
  }
}

Blog: http://virtu-al.net Twitter: http://twitter.com/alanrenouf Co-author of the PowerCLI Book: http://powerclibook.com
0 Kudos
LucD
Leadership
Leadership
Jump to solution

No problem, we can use another loop

Something like this perhaps ?

foreach($region "East","West"){

    Get-Datacenter -Name ($region + "Datacenter") | Get-VMHost | %{

      New-Datastore -Nfs -VMHost $_ -Name $sharename -Path $remotePath -NfsHost ($region + "DatacenterNFS") | Out-Null

    }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
the3rdd
Contributor
Contributor
Jump to solution

This works for me. Only issue is now trying to get it to error silently when the datastore already exists, o skip it if it exists. I do appreciate your help guys.

Get-Datacenter | Foreach {
$DC = $_
$DC | Get-VMHost | %{

foreach ($DC.Name in $DC)
{
            $NewName = $DC.Name
            $Site = $NewName.substring(0,6)

Write "DataCenter: $Site"
Write "Mounting NFS $($Site)NFS"
New-Datastore -Nfs -VMHost $_ -Name ($Site + "NFS") -Path $path -NfsHost ($Site + "NFS") | Out-Null

}
}

}

0 Kudos
alanrenouf
VMware Employee
VMware Employee
Jump to solution

How about...

Get-Datacenter | Foreach {
$DC = $_
$DC | Get-VMHost | %{
  foreach ($DC.Name in $DC)
  {
      $NewName = $DC.Name
      $Site = $NewName.substring(0,6)
  
   Write "DataCenter: $Site"
   Write "Mounting NFS $($Site)NFS"
   If (! (Get-Datastore ($Site + "NFS"))) {
    New-Datastore -Nfs -VMHost $_ -Name ($Site + "NFS") -Path $path -NfsHost ($Site + "NFS") | Out-Null
   }

  }
}
}

Blog: http://virtu-al.net Twitter: http://twitter.com/alanrenouf Co-author of the PowerCLI Book: http://powerclibook.com
0 Kudos
the3rdd
Contributor
Contributor
Jump to solution

Dang it, I should have remembered that from a previous Luc'd answer on another matter. It helps but it still doesn't stop the errors on the parts that may not have NFS yet and they won't suppress with -erroraction silentlycontinue. 

0 Kudos
alanrenouf
VMware Employee
VMware Employee
Jump to solution

Sorry, not sure I understand what isnt working?

Blog: http://virtu-al.net Twitter: http://twitter.com/alanrenouf Co-author of the PowerCLI Book: http://powerclibook.com
0 Kudos
the3rdd
Contributor
Contributor
Jump to solution

Basically if it has any errors, which don't matter because it works, it displays them, I am trying to suppress them, if possible. 

0 Kudos
alanrenouf
VMware Employee
VMware Employee
Jump to solution

Oh wow, and the -ea SilentlyContinue on the New-Datastore doesnt work ?

What are the errors ?

Blog: http://virtu-al.net Twitter: http://twitter.com/alanrenouf Co-author of the PowerCLI Book: http://powerclibook.com
0 Kudos
Vishy1
Enthusiast
Enthusiast
Jump to solution

Take a look into this scrpt found here

http://www.eprich.com/vmware/fastnfs-mounting-a-nfs-datastore-to-several-vsphere-hosts-with-powercli

If you found this information useful, please consider awarding points for Correct or Helpful.
0 Kudos
the3rdd
Contributor
Contributor
Jump to solution

Well the error is on the Get-Datastore part of the code, it errors that the datastore is not found, as some will not have it available yet.

It also seems I will need to try and find a way to verify the NFS share exists in the first place before trying to mount it, I have researched a bit and found ways to use get-wmi to find shares but I haven't found a real easy way to query if the NFS share, and the machine, exist before attempting to mount them to the host.

0 Kudos
the3rdd
Contributor
Contributor
Jump to solution

Thought about it and came up with a better way for validation. If the NFS server exists then that means there will be an NFS share. So that means pinging a host should validate as to whether the drive should be mapped, if it isn't already. The following is the code that works for me for simply mapping

Get-Datacenter | where {$_.Name -notmatch 'nottest*'} | Foreach {
$DC = $_
$DC | Get-VMHost | %{

foreach ($DC.Name in $DC)
{
            $NewName = $DC.Name
            $Site = $NewName.substring(0,6)

    Write "DataCenter: $Site"
    Write "Mounting NFS $($Site)NFS"
    If (!(Get-DataStore ($Site + " NFS") -ErrorAction SilentlyContinue))  {
    New-Datastore -Nfs -VMHost $_ -Name ($Site + "NFS") -Path /nfs -NfsHost ($Site + "NFS") -ErrorAction SilentlyContinue | Out-Null
}
    }
    }

}

Then this is the code that I was able to get for pinging a host

foreach ($vm in $vms) {
    $ping = New-Object System.Net.NetworkInformation.Ping
    try
    {
        $status = [string]($ping.Send($vm)).Status
    }
    catch [System.Net.NetworkInformation.PingException]{$status = $null}
    switch($status){
        Success {}
        Default {
            Write-Host "$vm not responding."
        }
    }
}
So now I am looking at combining so that the script will check if the datastore is already mapped, if yes skip, if no then ping the ($site+"NFS"), if response is received then map the share, if no response is received then skip and move to the next. Any help would be appreciated.
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try it like this

Get-Datacenter | where {$_.Name -notmatch 'nottest*'} | foreach {
    $DC = $_
   
$DC | Get-VMHost | %{         foreach ($DC.Name in $DC)         {             $NewName = $DC.Name             $Site = $NewName.substring(0,6)             Write "DataCenter: $Site"
           
Write "Mounting NFS $($Site)NFS"
           
if (!(Get-DataStore ($Site + " NFS") -ErrorAction SilentlyContinue)) {                 if((Get-WmiObject -Class Win32_PingStatus -Filter "Address='$Site +"NFS"'").StatusCode -eq 0){                     New-Datastore -Nfs -VMHost $_ -Name ($Site + "NFS") -Path /nfs -NfsHost ($Site + "NFS") -ErrorAction SilentlyContinue | Out-Null                }             }         }     } }

I prefer the WMI ping. It's more compact.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
the3rdd
Contributor
Contributor
Jump to solution

Just giving an update, I am trying to play a bit with the script as it doesn't like the Ping command for some reason. It keeps giving me the error

Get-WMIObject : Invalid Query

If I put in a declared value, instead of having ti try to pull the site through the variable it gives me

Get-WMIObject : A positional Parameter cannot be found that accepts argument "nfs01"

Which is the machine name the variable is housing.

0 Kudos