Foreman ESXi Installation Never Completes

In our environment we want to use Foreman to build our OCP hardware. It was working well except that the installation would repeatedly PXE boot to reinstall because Foreman would not know that the PXE portion was complete.

The standard notification code below was failing for some reason.

%post --interpreter=busybox --ignorefailure=true 
wget -O /dev/null <%= foreman_url %>

After running the unattended install in a Fusion VM so I could have console access I reviewed the install log and a misleading message from wget about the URL being bad. After a little digging I determine that the problem was no DNS in the ESXi installer.

Per the documentation this is expected.
Deploying ESXi 5.x using the Scripted Install feature (2004582)

Note: When ESXi 5.x is being installed using a kickstart file via PXE with DHCP enabled; the DNS settings are not available and are not saved in the configuration file.

Following what I have seen in previous installation scripts I implemented a quick fix to the Foreman OS template to add DNS settings to the installer environment so the call works and the build proceeds as expected.

%post --interpreter=busybox --ignorefailure=true 
# Add temporary DNS resolution so the foreman call works
echo "nameserver <%= @host.subnet.dns_primary %>" >> /etc/resolv.conf
echo "nameserver <%= @host.subnet.dns_secondary %>" >> /etc/resolv.conf
wget -O /dev/null <%= foreman_url %>
echo "Done with Foreman call"

PowerCLI Move-Datastore Function

Moving datastores into folders via drag/drop can be painful. In some cases vCenter does not want to allow a drag from a long list. Here is a quick function to make moving via PowerCLI a little bit easier.

Function Move-Datastore {
    param (
            $datastore = $(throw "Datastore(s) must be provided."),
            $folder = $(throw "A destination folder must be provided.")
    if ($folder.Type -ne "Datastore") {
        throw ("The specified folder is not a datastore folder.")
    $dsList = @()
    foreach ($ds in $datastore) {
        $dsList += $ds.ID

Convenience Functions for Connecting to Multiple vCenters

In a large environment repeatedly connecting and disconnecting from groups of vCenters can be tedious so I created some helper functions and put them in my PowerShell profile.

Connect-VIServerGroup lab
Connect-VIServerGroup desktops
Disconnect-VIServerGroup lab
Function Connect-VIServerGroup {
	param (
		[String]$group = $(throw "A VI server group name must be specified.")
	Connect-VIServer -Server (Get-VIServerList $group)
Function Disconnect-VIServerGroup {
	param (
		[String]$group = $(throw "A VI server group name must be specified.")
	Disconnect-VIServer -Server (Get-VIServerList $group) -Confirm:$false
Function Get-VIServerList {
	param (
		[String]$group = $(throw "A VI server group name must be specified.")
	switch ($group) {
		"lab" {"vclab01.local", "vclab02.local"}
		"servers" {"vc001.local", "vc002.local", "vc003.local", "vc004.local"}
		"desktops" {"vc005.local", "vc006.local", "vc007.local", "vc008.local"}
		default {throw "No VI server group named $group found."}

VMware PowerCLI 5 Cmdlets by Noun

Generated using this post.

Noun Verbs
AdvancedSetting Get,New,Remove,Set
AlarmAction Get,New,Remove
AlarmActionTrigger Get,New,Remove
AlarmDefinition Get,Set
Annotation Get,Set
CDDrive Get,New,Remove,Set
Cluster Get,Move,New,Remove,Set
CustomAttribute Get,New,Remove,Set
CustomField New,Remove,Set
Datacenter Get,Move,New,Remove,Set
Datastore Get,New,Remove,Set
DatastoreCluster Get
DatastoreItem Copy
DrsRecommendation Apply,Get
DrsRule Get,New,Remove,Set
ErrorReport Get
EsxCli Get
EsxTop Get
FloppyDrive Get,New,Remove,Set
Folder Get,Move,New,Remove,Set
HAPrimaryVMHost Get
HardDisk Copy,Get,New,Remove,Set
Inventory Get,Move,Remove
IScsiHbaTarget Get,New,Remove,Set
Log Get
LogType Get
NetworkAdapter Get,New,Remove,Set
NicTeamingPolicy Get,Set
OSCustomizationNicMapping Get,New,Remove,Set
OSCustomizationSpec Get,New,Remove,Set
PassthroughDevice Add,Get,Remove
PowerCLIConfiguration Get,Set
PowerCLIVersion Get
ResourcePool Get,Move,New,Remove,Set
ScsiController Get,New,Set
ScsiLun Get,Set
ScsiLunPath Get,Set
Snapshot Get,New,Remove,Set
Stat Get
StatInterval Get,New,Remove,Set
StatType Get
Task Get,Stop,Wait
Template Get,Move,New,Remove,Set
Tools Dismount,Mount,Update,Wait
UsbDevice Get,Remove
VApp Export,Get,Import,Move,New,Remove,Set,Start,Stop
VIAccount Get
VICredentialStoreItem Get,New,Remove
VIEvent Get
View Get
VIObjectByVIView Get
VIPermission Get,New,Remove,Set
VIPrivilege Get
VIProperty Get,New,Remove
VIRole Get,New,Remove,Set
VirtualPortGroup Get,New,Remove,Set
VirtualSwitch Get,New,Remove,Set
VIServer Connect,Disconnect
VM Get,Move,New,Remove,Restart,Set,Start,Stop,Suspend
VMGuest Get,Restart,Shutdown,Suspend
VMGuestFile Copy
VMGuestNetworkInterface Get,Set
VMGuestRoute Get,New,Remove
VMHost Add,Get,Move,Remove,Restart,Set,Start,Stop,Suspend
VMHostAccount Get,New,Remove,Set
VMHostAdvancedConfiguration Get,Set
VMHostAuthentication Get,Set
VMHostAvailableTimeZone Get
VMHostDiagnosticPartition Get,Set
VMHostDisk Get
VMHostDiskPartition Format,Get
VMHostFirewallDefaultPolicy Get,Set
VMHostFirewallException Get,Set
VMHostFirmware Get,Set
VMHostHba Get,Set
VMHostModule Get,Set
VMHostNetwork Get,Set
VMHostNetworkAdapter Get,New,Remove,Set
VmHostNtpServer Add,Get,Remove
VMHostPatch Get,Install
VMHostProfile Apply,Export,Get,Import,New,Remove,Set
VMHostProfileCompliance Test
VMHostProfileRequiredInput Get
VMHostRoute Get,New,Remove,Set
VMHostService Get,Restart,Set,Start,Stop
VMHostSnmp Get,Set,Test
VMHostStartPolicy Get,Set
VMHostStorage Get,Set
VMHostSysLogServer Get,Set
VMQuestion Get,Set
VMResourceConfiguration Get,Set
VMScript Invoke
VMStartPolicy Get,Set

Quick Memory Allocation for Limit / Reservation Testing in VMware

I am testing the impact and behavior of memory limits and reservations along with balloon drivers and I needed a quick way to allocate memory in a user program.

PowerShell to the rescue. This isn’t a good method for exact memory allocation, but you can consume MBs to GBs of memory pretty quickly.

# Allocate memory by creating a large string.  Divide the length by 4
# (Unicode size) to get an approximation of the MB allocation. Make
# sure to assign the result to a variable otherwise the memory will be
# reclaimed to the .Net garbage collector
$a = "a" * 256MB/4