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.
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
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 ?
Correct.
Ok, Standby...
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
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
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.
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
}
}
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
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
}
}
}
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
}}
}
}
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.
Sorry, not sure I understand what isnt working?
Basically if it has any errors, which don't matter because it works, it displays them, I am trying to suppress them, if possible.
Oh wow, and the -ea SilentlyContinue on the New-Datastore doesnt work ?
What are the errors ?
Take a look into this scrpt found here
http://www.eprich.com/vmware/fastnfs-mounting-a-nfs-datastore-to-several-vsphere-hosts-with-powercli
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.
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."
}
}
}
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
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.