Configure ESXi Scratch Config w/ Powershell/PowerCLI and other advanced settings...
Summary:
# Initial Option will always have $num, every subsequent defined option should be ($Num +1)
# $NumberofOptions should match the amount of options you plan to update.
# I made this number 20, even though I only have 4
# It just makes it easier to add more later w/o remember to change
# this number each time I add an option.
$Num = 0
$NumberofOptions = 20
# Any static options that don't have reliance upon data should be defined here.
# These first two options simply define my remote syslog info.
# Key is the important value.
# To find out what values are available you can use the Get-AdvancedSetting cmdlet
$Options = New-Object VMware.Vim.OptionValue[] ($NumberofOptions)
$Options[$Num] = New-Object VMWare.Vim.OptionValue
$Options[$Num].Key = "Syslog.Remote.Hostname"
$Options[$Num].Value = "192.168.1.5"
$Options[($Num + 1)] = New-Object VMWare.Vim.OptionValue
$Options[($Num + 1)].Key = "Syslog.Remote.Port"
$Options[($Num + 1)].Value = "514"
# Additional Options can be found by search for # Additional Options #
# Starting a Loop statement to run commands against each individual
# ESXi host aka VMHost in API terms
Foreach ($VMHost in $VMHosts)
{
# I need the datacenter node name here so I can create the directory/directories needed for
# the scratch and local syslog directories.
$DataCenter = Get-Datacenter -VMHost $vmhost -ErrorVariable +ErrorLog
# In my case, my standard local datastore name is formatted as myESXHostName_local
# This is needed so I can get the uuid of the store the scratch directory.
$DS = Get-Datastore "$($VMHost.NetworkInfo.Hostname)_local" -ErrorVariable +ErrorLog
$PathCheck = Test-Path vmstore:\$DataCenter\"$($VMHost.NetworkInfo.Hostname)_local"\"logfiles\" -ErrorVariable +ErrorLog
If ($Pathcheck -ne $true)
{mkdir vmstore:\$DataCenter\"$($VMHost.NetworkInfo.Hostname)_local"\logfiles -ErrorVariable +ErrorLog}
$Options[($Num + 1)] = New-Object VMWare.Vim.OptionValue
$Options[($Num + 1)].Key = "Syslog.local.datastorepath"
$Options[($Num + 1)].Value = ("[" + $VMHost.NetworkInfo.Hostname + "_local] /logfiles/" + $VMHost.NetworkInfo.Hostname + ".log")
$PathCheck = Test-Path vmstore:\$DataCenter\"$($VMHost.NetworkInfo.Hostname)_local"\".locker-$($VMHost.NetworkInfo.Hostname)" -ErrorVariable +ErrorLog
If ($Pathcheck -ne $true)
{mkdir vmstore:\$DataCenter\"$($VMHost.NetworkInfo.Hostname)_local"\".locker-$($VMHost.NetworkInfo.Hostname)" -ErrorVariable +ErrorLog}
# Here I define the scratch directory location using the datastore information
$Options[($Num + 1)] = New-Object VMWare.Vim.OptionValue
$Options[($Num + 1)].Key = "ScratchConfig.ConfiguredScratchLocation"
$Options[($Num + 1)].Value = ("/vmfs/volumes/$($DS.ExtensionData.info.vmfs.uuid)/.locker-$($VMHost.NetworkInfo.Hostname)")
# End Additional Options #
## Here is where we now apply all those defined advanced settings ##
# Begin loop statement to apply each $Option / Advanced Setting, skipping $null entries
Foreach ($Option in ($Options | where {$_ -ne $null}))
{
Write-Host "Checking if $($Option.Key) equals $($Option.Value)"
# Here I'm simply checking to see if the advanced setting is already is configured.
IF ((Get-AdvancedSetting -Name $Option.Key -ErrorAction:SilentlyContinue -ErrorVariable +ErrorLog).Value -ne $Option.Value )
{Write-Host "It doesn't so I'm changing it."
# If it's not configured, then I'm changing it.
Get-AdvancedSetting -Name $Option.Key | Set-AdvancedSetting -Value $Option.Value -ErrorAction:SilentlyContinue -ErrorVariable +ErrorLog
}
# If it is configured, then this simply lets you know that it is.
Else {Write-Host "It does!? That's weird, moving on."}
}
}
# Outputs an error txt file if any were recorded.
If ($errorLog.Count -gt 0)
{
$ErrorLog | Out-File $LogPath
}
Managing Vmware Infrastructure with Windows Powershell Tfm (Google Affiliate Ad)
Needed to script configure all my 100+ ESXi hosts w/ a scratch location. Having a permanent scratch location configured is helpful when an error such as a purple screen of death (PSOD) occurs on ESXi. It is not a requirement, but definitely a best practice.
PreRequisites:
- Powershell 2.0 +
- PowerCLI 5.1 +
- vCenter 4.1 +
- Local or Shared Datastore
- Local is easy if you standardize on naming of a local datastore.
- I'll focus on this in my script example.
- Shared Datastore essentially accomplishes a similar goal of a remote syslog server, you'll want to be sure to separate logs to their own individual directory.
- Scaling may become an issue unless you focus these shared datastores among clusters rather than all hosts.
Rather than write a single line to just configure the scratch location, I decided to write something that could host my standard build config info for all advanced settings. This way I could simply add additional advanced settings to this same script. This is made simply to also cover anything that a scripted pxe build process may fail to apply. It's not the most elegant solution, so I more than welcome feedback and tips.
So here it is:
So here it is:
# Stuff to capture errors, yes, it is quite useful.
$Date = Get-Date -Format yyyy.MM.dd-hh.mm.ss
$UserName = (Get-ChildItem env:\username).value
$ErrorLog = @()
# This can also be a network share like \\servername\hiddensharename$
$ErrorLogOutPutPath = "C:\somepath\errors\WhateverNameYouWantHere$($Date)-$($Username).txt"
# Connecting to my vCenter
Connect-viserver myvCenterServerName -ErrorVariable +ErrorLog
# Here I am gather all the hosts connected to my connected vCenter instance.
$Date = Get-Date -Format yyyy.MM.dd-hh.mm.ss
$UserName = (Get-ChildItem env:\username).value
$ErrorLog = @()
# This can also be a network share like \\servername\hiddensharename$
$ErrorLogOutPutPath = "C:\somepath\errors\WhateverNameYouWantHere$($Date)-$($Username).txt"
# Connecting to my vCenter
Connect-viserver myvCenterServerName -ErrorVariable +ErrorLog
# Here I am gather all the hosts connected to my connected vCenter instance.
$VMHosts = Get-VMHost -ErrorVariable +ErrorLog
# Initial Option will always have $num, every subsequent defined option should be ($Num +1)
# $NumberofOptions should match the amount of options you plan to update.
# I made this number 20, even though I only have 4
# It just makes it easier to add more later w/o remember to change
# this number each time I add an option.
$Num = 0
$NumberofOptions = 20
# Any static options that don't have reliance upon data should be defined here.
# These first two options simply define my remote syslog info.
# Key is the important value.
# To find out what values are available you can use the Get-AdvancedSetting cmdlet
$Options = New-Object VMware.Vim.OptionValue[] ($NumberofOptions)
$Options[$Num] = New-Object VMWare.Vim.OptionValue
$Options[$Num].Key = "Syslog.Remote.Hostname"
$Options[$Num].Value = "192.168.1.5"
$Options[($Num + 1)] = New-Object VMWare.Vim.OptionValue
$Options[($Num + 1)].Key = "Syslog.Remote.Port"
$Options[($Num + 1)].Value = "514"
# Additional Options can be found by search for # Additional Options #
# Starting a Loop statement to run commands against each individual
# ESXi host aka VMHost in API terms
Foreach ($VMHost in $VMHosts)
{
# I need the datacenter node name here so I can create the directory/directories needed for
# the scratch and local syslog directories.
$DataCenter = Get-Datacenter -VMHost $vmhost -ErrorVariable +ErrorLog
# In my case, my standard local datastore name is formatted as myESXHostName_local
# This is needed so I can get the uuid of the store the scratch directory.
$DS = Get-Datastore "$($VMHost.NetworkInfo.Hostname)_local" -ErrorVariable +ErrorLog
# Additional Options #
# Here is where I am testing whether the local syslog path exists
# If not, the script will create it. The path is required for the logging to work.
$PathCheck = Test-Path vmstore:\$DataCenter\"$($VMHost.NetworkInfo.Hostname)_local"\"logfiles\" -ErrorVariable +ErrorLog
If ($Pathcheck -ne $true)
{mkdir vmstore:\$DataCenter\"$($VMHost.NetworkInfo.Hostname)_local"\logfiles -ErrorVariable +ErrorLog}
# Here I define the local syslog datastore path
$Options[($Num + 1)] = New-Object VMWare.Vim.OptionValue
$Options[($Num + 1)].Key = "Syslog.local.datastorepath"
$Options[($Num + 1)].Value = ("[" + $VMHost.NetworkInfo.Hostname + "_local] /logfiles/" + $VMHost.NetworkInfo.Hostname + ".log")
# Here is where I am testing whether the local scratch path exists
# If not, the script will create it. The path needs to exist prior to configuration.
$PathCheck = Test-Path vmstore:\$DataCenter\"$($VMHost.NetworkInfo.Hostname)_local"\".locker-$($VMHost.NetworkInfo.Hostname)" -ErrorVariable +ErrorLog
If ($Pathcheck -ne $true)
{mkdir vmstore:\$DataCenter\"$($VMHost.NetworkInfo.Hostname)_local"\".locker-$($VMHost.NetworkInfo.Hostname)" -ErrorVariable +ErrorLog}
# Here I define the scratch directory location using the datastore information
$Options[($Num + 1)] = New-Object VMWare.Vim.OptionValue
$Options[($Num + 1)].Key = "ScratchConfig.ConfiguredScratchLocation"
$Options[($Num + 1)].Value = ("/vmfs/volumes/$($DS.ExtensionData.info.vmfs.uuid)/.locker-$($VMHost.NetworkInfo.Hostname)")
# End Additional Options #
## Here is where we now apply all those defined advanced settings ##
# Begin loop statement to apply each $Option / Advanced Setting, skipping $null entries
Foreach ($Option in ($Options | where {$_ -ne $null}))
{
Write-Host "Checking if $($Option.Key) equals $($Option.Value)"
# Here I'm simply checking to see if the advanced setting is already is configured.
IF ((Get-AdvancedSetting -Name $Option.Key -ErrorAction:SilentlyContinue -ErrorVariable +ErrorLog).Value -ne $Option.Value )
{Write-Host "It doesn't so I'm changing it."
# If it's not configured, then I'm changing it.
Get-AdvancedSetting -Name $Option.Key | Set-AdvancedSetting -Value $Option.Value -ErrorAction:SilentlyContinue -ErrorVariable +ErrorLog
}
# If it is configured, then this simply lets you know that it is.
Else {Write-Host "It does!? That's weird, moving on."}
}
}
# Outputs an error txt file if any were recorded.
If ($errorLog.Count -gt 0)
{
$ErrorLog | Out-File $LogPath
}
Managing Vmware Infrastructure with Windows Powershell Tfm (Google Affiliate Ad)
Comments