Hi Guys,
I need to change the scratch file location on a bunch of ESXi Hosts. A lot of Servers lately are coming with dedicated (small) hard disks for the O/S plus, disks for vSAN.
The Default location of the scratch files is, where the O/S is installed. this is causing problems so, i want to move the Scratch files to a vSAN datastore (there may not be a VMFS datastore)
I've pieced the following together but would like any input on it before running it on a Production Environment
# login to vCenter
$table = @()
$prefix = ".scratch_"
$datastore = Get-Datastore | where {$_.Type -eq "VSAN"}
foreach ($ds in $datastore) {
New-PSDrive -Location $ds -Name PSD -PSProvider VimDatastore -Root '' | Out-Null
foreach ($h in ($ds | Get-VMHost)){
$fqdn = $h.Name
$hostName = $fqdn.Split(".")[0].TrimStart("{")
$hostDS = $h | Get-Datastore | where {$_.Type -eq "VSAN"}
$scratchFolder = "$($prefix)$($hostName)"
$tableProp=[ordered]@{
'Host FQDN'=$fqdn
'Host Name'=$hostName
'VSAN DS'= $hostDS
}
# Check to see if a scratch folder for the Host exists on the vSAN DS and create it if needed
$scratchFolderPath = "/vmfs/volumes/$($hostDS.Name)/$scratchFolder"
$scratchFolderPathExists = Test-Path -Path $scratchFolderPath | Out-Null
if (-not ($scratchFolderPathExists)){
New-Item -Path "PSD:\$scratchFolder" -ItemType Directory | Out-Null
}
# identify current Scratch Folder Settings
$configuredScratch = $h | Get-AdvancedSetting -Name "ScratchConfig.ConfiguredScratchLocation"
$configuredScratchValue = $configuredScratch.Value
$currentScratch = $h | Get-AdvancedSetting -Name "ScratchConfig.CurrentScratchLocation"
$currentScratchValue = $currentScratch.Value
$tableProp.Add('Current Scratch Value', $currentScratchValue)
# set new Scratch location
$configuredScratch | Set-AdvancedSetting -Value $scratchFolderPath -Confirm:$false | Out-Null
$tableProp.Add('New Scratch Location',$scratchFolderPath)
# Place Host in Maintenance mode, reboot, exit Maintenance Mode, move to next Host
Set-VMHost $h -State Maintenance -Evacuate
Restart-VMHost $h
Start-Sleep -Seconds 900
$connectionState = Get-VMHost $h.ConnectionState
while ($connectionState -eq "Maintenance") {
Set-VMHost $h -state Connected
}
$table += New-Object -TypeName psobject -Property $tableProp
}
Remove-PSDrive -Name PSD -Confirm:$false
}
$table | Sort-Object -Property "Host FQDN" | ft -AutoSize
Well, not really.
In the following code extract, we restart the ESXi node.
But if we immediately test if the ESXi node is connected, we might be too soon (before the restart actually changes the state to Disconnected).
Restart-VMHost $h
Start-Sleep -Seconds 900
$esx = Get-VMHost -Name $h.Name
while ($esx.connectionState -ne "Connected")
{
$esx = Get-VMHost -Name $esx.Name
}
The ideal way to leave out the sleep would be to first wait till the host is disconnected, followed by a wait till the host is connected again.
Something like this for example.
Restart-VMHost $h
$esx = Get-VMHost -Name $h.Name
while ($esx.connectionState -ne "Disconnected")
{
$esx = Get-VMHost -Name $esx.Name
}
while ($esx.connectionState -ne "Connected")
{
$esx = Get-VMHost -Name $esx.Name
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I made a couple of small changes.
$table = @()
$prefix = ".scratch_"
$datastore = Get-Datastore | where { $_.Type -eq "VSAN" }
foreach ($ds in $datastore)
{
foreach ($h in ($ds | Get-VMHost))
{
$fqdn = $h.Name
$hostName = $fqdn.Split(".")[0]
$hostDS = $h | Get-Datastore | where { $_.Type -eq "VSAN" }
$scratchFolder = "$($prefix)$($hostName)"
$tableProp = [ordered]@{
'Host FQDN' = $fqdn
'Host Name' = $hostName
'VSAN DS' = $hostDS
}
# Check to see if a scratch folder for the Host exists on the vSAN DS and create it if needed
New-PSDrive -Location $hostDS -Name PSD -PSProvider VimDatastore -Root '' | Out-Null
$scratchFolderPath = "PSD:/$($hostDS.Name)/$scratchFolder"
if (-not (Test-Path -Path $scratchFolderPath))
{
New-Item -Path $scratchFolderPath -ItemType Directory | Out-Null
}
Remove-PSDrive -Name PSD -Confirm:$false
# identify current Scratch Folder Settings
$configuredScratch = $h | Get-AdvancedSetting -Name "ScratchConfig.ConfiguredScratchLocation"
$configuredScratchValue = $configuredScratch.Value
$currentScratch = $h | Get-AdvancedSetting -Name "ScratchConfig.CurrentScratchLocation"
$currentScratchValue = $currentScratch.Value
$tableProp.Add('Current Scratch Value', $currentScratchValue)
# set new Scratch location
$configuredScratch | Set-AdvancedSetting -Value $scratchFolderPath -Confirm:$false | Out-Null
$tableProp.Add('New Scratch Location', $scratchFolderPath)
# Place Host in Maintenance mode, reboot, exit Maintenance Mode, move to next Host
Set-VMHost $h -State Maintenance -Evacuate
Restart-VMHost $h
Start-Sleep -Seconds 900
$esx = Get-VMHost -Name $h.Name
while ($esx.connectionState -ne "Connected")
{
$esx = Get-VMHost -Name $esx.Name
}
$table += New-Object -TypeName psobject -Property $tableProp
}
}
$table | Sort-Object -Property "Host FQDN" | ft -AutoSize
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks Luc,
i'm not sure i understand your 4th point "your waiting for the ESXi Node to come back will not work".
Is there a way of placing a host into MM, rebooting and once it's connected to the vCenter again, exiting MM before moving on to the next host in the Cluster ?
i'd prefer to limit the number of Hosts in MM or, rebooting in a Cluster at any one time
Regards,
Jason
Because you don't refresh the state in the While-block.
When you go while the ESXi node is in maintenance mode, you will get stuck in that loop.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks Luc,
with your
while ($esx.connectionState -ne "Connected")
{
$esx = Get-VMHost -Name $esx.Name
}
would i be ok to remove the
Start-Sleep -Seconds 900
Am i correct in assuming that the script won't move on to the next host in the for Loop until i manually take the current Host out of Maintenance Mode ?
Well, not really.
In the following code extract, we restart the ESXi node.
But if we immediately test if the ESXi node is connected, we might be too soon (before the restart actually changes the state to Disconnected).
Restart-VMHost $h
Start-Sleep -Seconds 900
$esx = Get-VMHost -Name $h.Name
while ($esx.connectionState -ne "Connected")
{
$esx = Get-VMHost -Name $esx.Name
}
The ideal way to leave out the sleep would be to first wait till the host is disconnected, followed by a wait till the host is connected again.
Something like this for example.
Restart-VMHost $h
$esx = Get-VMHost -Name $h.Name
while ($esx.connectionState -ne "Disconnected")
{
$esx = Get-VMHost -Name $esx.Name
}
while ($esx.connectionState -ne "Connected")
{
$esx = Get-VMHost -Name $esx.Name
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
thanks, that worked perfectly