VMware Cloud Community
piercj2
Enthusiast
Enthusiast
Jump to solution

Set Scratch Location

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

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

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

View solution in original post

0 Kudos
6 Replies
LucD
Leadership
Leadership
Jump to solution

I made a couple of small changes.

  1. Not sure why you do the TrimStart('{')
  2. The path you use needs to be based on the new PSProvides name, PDS. Consider it a drive
  3. I moved the creation and removal of the PSProvider closer together. In fact it will only exist where the script actually needs it
  4. Your waiting for the ESXi node to come back will  not work. Not that it is not advisable to overwrite the ForEach variable inside the loop, hence the use of $esx instead $h

# login to vCenter

$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

0 Kudos
piercj2
Enthusiast
Enthusiast
Jump to solution

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

0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

0 Kudos
piercj2
Enthusiast
Enthusiast
Jump to solution

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 ?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

0 Kudos
piercj2
Enthusiast
Enthusiast
Jump to solution

thanks, that worked perfectly Smiley Happy

0 Kudos