Automation

 View Only
  • 1.  Set Scratch Location

    Posted May 07, 2019 04:23 PM

    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



  • 2.  RE: Set Scratch Location

    Posted May 07, 2019 05:25 PM

    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



  • 3.  RE: Set Scratch Location

    Posted May 07, 2019 08:15 PM

    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



  • 4.  RE: Set Scratch Location

    Posted May 07, 2019 08:25 PM

    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.



  • 5.  RE: Set Scratch Location

    Posted May 10, 2019 12:16 PM

    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 ?



  • 6.  RE: Set Scratch Location
    Best Answer

    Posted May 10, 2019 12:30 PM

    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

    }



  • 7.  RE: Set Scratch Location

    Posted May 10, 2019 01:31 PM

    thanks, that worked perfectly :smileyhappy: