Lab template: Ubuntu 16.04

Recently I’ve been working in a couple of different / disconnected labs. This means I’m managing a couple copies of all my templates manually. Sometimes its hard to find the right section of my notes depending on when/where I’m working on the lab, so I decided to post a couple quick blog posts so I can always find them. The following notes are for creating a template based on Ubuntu 16.04.1, and include notes on setting a static IP and joining to the domain with pbis-open (formerly likewise-open).

Install Ubuntu 16.04.1 Server from ISO image (http://www.ubuntu.com/download/server/thank-you?version=16.04.1&architecture=amd64), accepting all defaults. When prompted for an admin user, use the name hostadmin.

Once the install is complete, login as hostadmin. Switch to root and set a password for the root user.

sudo su -
passwd

Apply updates and install the packages openssh-server and ntp:

apt-get update && apt-get upgrade
apt-get install openssh-server ntp -y

Get the template ready for PowerBroker Identity Services (formerly likewise-open) domain joins:

wget http://download1.beyondtrust.com/Technical-Support/Downloads/PowerBroker-Identity-Services-Open-Edition/pbiso/850/pbis-open-8.5.0.153.linux.x86_64.deb.sh
chmod +x pbis-open-8.5.0.153.linux.x86_64.deb.sh
./pbis-open-8.5.0.153.linux.x86_64.deb.sh
cd /opt/pbis/bin/ 

At this point, I shutdown the VM and convert it to a template. When I’m ready to use the VM, I deploy a copy from template and follow the remaining steps.

If needed, set a static IP by updating the following file:

nano /etc/network/interfaces

The important sections to include in the iface settings are address, netmask, gateway, dns-search, and dns-nameservers. An example has been included below:

iface eth0 inet static
address 192.168.0.100
netmask 255.255.255.0
gateway 192.168.0.1
dns-search lab.enterpriseadmins.org
dns-nameservers 192.168.0.20

Verify that the hostname is properly set:

nano /etc/hostname

Join the Linux VM to the domain and create a DNS record:

domainjoin-cli join lab.enterpriseadmins.org adminbw
/opt/pbis/bin/config AssumeDefaultDomain true
/opt/pbis/bin/config LoginShellTemplate /bin/bash
/opt/pbis/bin/config HomeDirTemplate %H/%U
/opt/pbis/bin/config RequireMembershipOf "lab\\domain^users"
/opt/pbis/bin/update-dns

Once I reach this point, I kick off a quick reboot (just to make sure the domain join took) and am now free to use the VM.

Posted in Virtualization | 1 Comment

Reload syslog configuration on ESXi

I recently updated Log Insight to version 3.3.2 in my lab. After selecting the appropriate PAK file, the UI displayed a warning containing the following text:

Note that certain builds of ESXi need to have 
their syslog configuration reloaded after restart, 
otherwise log data will stop forwarding. 
Configuration can be reloaded from the vSphere 
Integration page. See the Online Help for 
more information.

I waited a couple hours after the upgrade to check back on the system and noticed that I was no longer collecting syslog data. I visited the vSphere Integration page and reviewed my hosts, but they were already configured as expected. I picked just one host and updated the configuration anyway, and that host started logging data again. For another host, I manually cleared the syslog.global.logHost value from the web client and then re-entered the logHost text. This also caused the host to start sending syslog data again. Interested in the minimum effort to ‘reload’ syslog configuration (without needing to update/reset logHost values) I found the following KB article: https://kb.vmware.com/kb/2003322. It appears that esxcli has an option to simply reload the configuration (using esxcli system syslog reload). To run this on all hosts remaining in my inventory, I executed the following code:

Get-VMHost | Sort-Object Name | %{
  write-host -nonewline "$($_.Name) reloading syslog:"
  (Get-EsxCli -VMHost $($_.Name) -v2).system.syslog.reload.invoke()
}

Note: this requires the latest version (6.3 release 1) of PowerCLI. I hope someone finds this information helpful.

Posted in Scripting, Virtualization | Leave a comment

Find ESXi Installation Date with PowerCLI

I recently noticed a link to a very interesting article on Twitter: Find ESXi Installation Date — http://vcdx56.com/2016/01/05/find-esxi-installation-date/. These steps are straight forward and show how to calculate the original ESXi install date, looking at the first section of the UUID. I didn’t realize so much useful information was coded into the UUID, but this could be useful information for certain reports. To understand the process, please check out the original article on vcdx56.com.

The following few lines of code will return this information for all hosts in a vCenter using PowerCLI.

# Find ESXi install date: http://vcdx56.com/2016/01/05/find-esxi-installation-date/
# Convert HEX to DEC: http://michaelflanakin.com/Weblog/tabid/142/articleType/ArticleView/articleId/1073/Converting-ToFrom-Hex-with-PowerShell.aspx
# Convert epoch to date: http://stackoverflow.com/questions/10781697/convert-unix-time-with-powershell

Get-VMHost | Sort Name | %{
  $thisUUID = (Get-EsxCli -VMHost $_.name).system.uuid.get()
  $decDate = [Convert]::ToInt32($thisUUID.Split("-")[0], 16)
  $installDate = [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($decDate))
  [pscustomobject][ordered]@{
    Name="$($_.name)"
    InstallDate=$installDate
  } # end custom object
} # end host loop
Posted in Scripting, Virtualization | 1 Comment

Do you have any way of getting IPs from a list of server names?

A few days ago, someone asked a very basic question. Where is the opposite version of this script:
http://enterpriseadmins.org/blog/scripting/do-you-have-any-way-of-getting-server-name-from-the-attached-list-of-ips/? They had a list of host names and wanted the associated IP addresses. Since it is somewhat common for a name to resolve to multiple IP addresses, this function has a few more lines as it will loop through each result.

Function Get-HostIP ([string]$hostName) {
  try {
    [system.net.dns]::GetHostByName($hostName).AddressList | %{
      New-Object psobject -Property @{
        HostName = $hostName
        IPAddress = $_.IPAddressToString
      } # End result object
    } # end foreach loop
  } catch {
    New-Object psobject -Property @{
      HostName = $hostName
      IPAddress = "Unknown/Error"
    } # end result object
  } # end try/catch
} # end function

Here is a sample result running this function against google.com:

Get-HostIP 'google.com'

IPAddress     HostName
---------     --------
173.194.46.67 google.com
173.194.46.71 google.com
173.194.46.65 google.com
173.194.46.66 google.com
173.194.46.69 google.com
173.194.46.72 google.com
173.194.46.70 google.com
173.194.46.78 google.com
173.194.46.68 google.com
173.194.46.73 google.com
173.194.46.64 google.com
Posted in Scripting | Leave a comment

Setup VSAN without vCenter using PowerCLI

Recently @RuddyVCP (Blog | Twitter) and I worked on building a home lab to give away at the 2015 Indianapolis VMUG UserCon. The idea was we’d build a three node VSAN cluster using Intel NUC miniature PCs each with a 1TB 7200 RPM SATA disk and a 256GB M.2 SSD. Between Kyle and I we have plenty of content for a series of blog posts, as this was a much more challenging project than either of us initially assumed.

Today I want to write about the VSAN install, as it was part of a chicken vs. egg type discussion. Normally one would setup VSAN on a cluster from within vCenter. However, in our day-zero deployment we did not have a working vCenter yet, or a place to deploy the vCenter server. All of the local disks inside the NUCs needed to be claimed by the VSAN (three nodes with one SSD and one spinning disk are the bare minimum for VSAN), so we couldn’t use one of those disks as a temporary home for vCenter either. The catch was without vCenter we also couldn’t deploy VSAN… or could we? How can you setup VSAN without vCenter?

Our Technical Account Manager @eck79 (Blog | Twitter) pointed us at this gem of a document for just such an occasion. It covers using the shell to do just that — setup VSAN without vCenter for day-zero deployments: https://www.vmware.com/files/pdf/products/vsan/VMware-TechNote-Bootstrapping-VSAN-without-vCenter.pdf

This document is great… it covers the basics of VSAN and includes bootstrapping instructions using esxcli over SSH. I wanted to do a bit of testing to see if I could make this work from within PowerCLI. Here is some sample code that I tested on a handful of NUCs to do just that — enable VSAN without vCenter using PowerCLI.

Set-PowerCLIConfiguration -DefaultVIServerMode:Multiple -InvalidCertificateAction:Ignore -Confirm:$false

Connect-VIServer 192.168.1.31,192.168.1.32,192.168.1.33 -User root -Password My#1Passwo
Get-VMHostNetworkAdapter -Name vmk0 | Set-VMHostNetworkAdapter -VsanTrafficEnabled:$true -Confirm:$false

Get-VMHost | Sort Name | %{
$vmh = $_
$luns = Get-ScsiLun -VMHost $vmh -LunType disk | ?{$_.IsLocal -eq $true -AND $_.CapacityGB -gt 32} | select CanonicalName, @{N="SSD";E={$_.ExtensionData.Ssd}}, CapacityGB
$dataLun = ($luns | ?{$_.ssd -eq $false} ).CanonicalName
$ssdLun = ($luns | ?{$_.ssd -eq $true} ).CanonicalName

$thisEsxCli = $vmh | Get-EsxCli
$thisEsxCli.vsan.storage.add($dataLun,$ssdLun)

# On the first pass we need to get a new UUID, future passes will reuse the existing value
if (!$newVsanUUID) {$newVsanUUID = $thisEsxCli.system.uuid.get()}
$thisEsxCli.vsan.cluster.join($newVsanUUID)
}

$thisEsxCli.vsan.cluster.get()

Lets break this code down a bit. In the first couple of lines we are connecting to all three of the NUCs (which are already running ESXi 6.0). We then enable VSAN traffic on the existing management network/vmk0 interface. We could easily have created a new portgroup/vmkernel interface, perhaps on its own VLAN, but to keep this simple I used the existing interface. When using unsupported hardware, best practices take the backseat.
We then loop through all the hosts (the three we have connected to earlier) and for each host we select the pair of local disks. The where-object statement that picks out devices larger than 32GB is just excluding the USB drive that contains the boot image. Once we have the disks, we use Get-EsxCli to claim them for VSAN. Finally we use the first host in the loop to generate a new UUID for the VSAN cluster (subsequent hosts will reuse this value) and we add the hosts to the VSAN cluster. Pretty snazzy. Here are some screenshots showing some of the various output.

Here is where we enabled the VSAN traffic on each host:
Enable VSAN traffic

Here you’ll see the code block that is selecting the disks, claiming them for VSAN (one true return per host) and then adding the host to the VSAN cluster (another true return for each host).
Host EsxCli loop code block with 6 true returns

Here you can see the status of the cluster is healthy.
esxi vsan cluster get at the very end

And finally, a screenshot showing the datastore is present — it appears three times, once per host.
Get-Datastore

Posted in Scripting, Virtualization | Leave a comment