{"id":577,"date":"2011-05-16T22:11:04","date_gmt":"2011-05-16T21:11:04","guid":{"rendered":"http:\/\/www.amikkelsen.com\/?p=577"},"modified":"2011-05-16T22:20:33","modified_gmt":"2011-05-16T21:20:33","slug":"poor-man%e2%80%99s-hostprofiles-including-esx-deployment","status":"publish","type":"post","link":"https:\/\/www.amikkelsen.com\/?p=577","title":{"rendered":"Poor man\u00e2\u20ac\u2122s hostprofiles including ESX deployment"},"content":{"rendered":"<p>Last year I was asked to reduce the time spend on installing and configuring our ESX hosts. \u00c2\u00a0Because we weren\u00e2\u20ac\u2122t using Enterprise Plus licenses, we didn\u00e2\u20ac\u2122t have Host Profiles.<br \/>\nI came up with a simple two-step process based on the EDA appliance and a custom PowerShell script.<\/p>\n<ul>\n<li>Install the host from PXE.<br \/>\nOnly setting the minimum configuration, so it\u00e2\u20ac\u2122s as versatile as possible.<\/p>\n<ul>\n<li>Disk layout<\/li>\n<li>Network teaming<\/li>\n<li>FQDN and IP<\/li>\n<\/ul>\n<\/li>\n<li>Configure the host using a      custom PowerShell script.<br \/>\nBased on the Datacenter and Cluster the host is to be added to.<\/p>\n<ul>\n<li>Add to vCenter<\/li>\n<li>Set COS memory<\/li>\n<li>Enable VMotion<\/li>\n<li>License host<\/li>\n<li>And much more\u00e2\u20ac\u00a6<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>A lot of blog posts are available on the net, on how to setup and install an ESX host using the EDA appliance so I won\u00e2\u20ac\u2122t trouble you with this.<\/p>\n<p>The PowerShell script is divided into several sections, I won\u00e2\u20ac\u2122t explain everyone, only the most relevant, the rest is documented in the full script.<br \/>\nAll steps in the script are logged to a host specific log file.<\/p>\n<ul>\n<li>User input \u00e2\u20ac\u201c Only 3 things      are asked for when running the script, the rest is stored in the scripts      Static section.\n<ul>\n<li>FQDN of the host (must be       configured in DNS to work)<\/li>\n<li>The environment \u00e2\u20ac\u201c what       environment is the host to be placed in, like PROD, DMZ, etc.<\/li>\n<li>The hosts VMotion IP.<\/li>\n<\/ul>\n<\/li>\n<li>Add the host to the right      cluster.<br \/>\nYou must have get the Datacenter\/Cluster variable prior to adding the      host, else it will just be placed in the first datacenter (See script for      more info).<\/p>\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n add-vmhost $strHost -location $strvCenterDatacenter -user $strHostUser -password $strHostUserPWD -force: $true\r\n <\/pre>\n<\/li>\n<li>Set the host in      maintenance mode\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n Get-VMHost -Name $strHost | Set-VMHost -State maintenance\r\n <\/pre>\n<\/li>\n<li>License host.<br \/>\nAs you can see below, you have to supply the full name of the license you      are adding, not just the license key.<\/p>\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n $targethostMoRef = (get-VMHost $strHost | get-view).MoRef\r\n $si = Get-View ServiceInstance\r\n $LicManRef=$si.Content.LicenseManager\r\n $LicManView=Get-View $LicManRef\r\n $licassman = (Get-View $LicManView.LicenseAssignmentManager)\r\n\r\n #$licassman.UpdateAssignedLicense($targethostMoRef.value,\u00e2\u20ac\u009dYOUR LIC KEY\u00e2\u20ac\u009d,\u00e2\u20ac\u009dvSphere4 Enterprise Plus (1-12 cores per CPU\u00e2\u20ac\u009d)\r\n $licassman.UpdateAssignedLicense($targethostMoRef.value,\u00e2\u20ac\u009dYOUR LIC KEY\u00e2\u20ac\u009d,\u00e2\u20ac\u009dvSphere4 Enterprise (1-6 cores per CPU\u00e2\u20ac\u009d)\r\n <\/pre>\n<\/li>\n<li>Set the correct time zone.\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n $strTimeZone = &quot;Europe\/Copenhagen&quot;\r\n $tmpHost = Get-VMHost $strHost | get-view\r\n $tmpDTSystem =\u00c2\u00a0 $tmpHost.ConfigManager.DateTimeSystem\r\n $tmpMoRef = Get-View\u00c2\u00a0 $tmpDTSystem\r\n $tmpDateConfig = New-Object      Vmware.Vim.HostDateTimeConfig\r\n $tmpDateConfig.timeZone = $strTimeZone\r\n $tmpMoRef.updateDateTimeConfig($tmpDateConfig)\r\n <\/pre>\n<\/li>\n<li>Add NTP servers.<br \/>\nUse an array of NTP servers like<br \/>\n$arrNTPServer = @(&#8220;dk.pool.ntp.org&#8221;,&#8221;de.pool.ntp.org&#8221;,&#8221;us.pool.ntp.org&#8221;,&#8221;clock.cimat.ues.edu.sv&#8221;,&#8221;ntp1.gbg.netnod.se&#8221;,&#8221;ntp1.theremailer.net&#8221;)<\/p>\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n Add-VMHostNtpServer -VMHost $strHost -NtpServer $arrNTPServer -Confirm:$false\r\n <\/pre>\n<p>If you want you can restart the NTP service \u00e2\u20ac\u201c only do it if you don\u00e2\u20ac\u2122t plan      on restarting the host after configuring.<\/p>\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n Restart-VMHostService $ntpd -Confirm:$false\r\n <\/pre>\n<\/li>\n<li>Open firewall rules<br \/>\nI always open the following firewall rules so that NTP and the SSH is      working<\/p>\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n Get-VmhostFirewallException -VMHost $strHost -Name &quot;NTP Client&quot; | Set-VMHostFirewallException -enabled:$true\r\n Get-VmhostFirewallException -VMHost $strHost -Name &quot;SSH Client&quot; | Set-VMHostFirewallException -enabled:$true\r\n &#x5B;\/powershel]&lt;\/li&gt;\r\n\t&lt;li&gt;Set the correct DNS servers\r\n Use an array of DNS servers, this way you can add multiple DNS servers at      once.\r\n @(&quot;10.10.10.40&quot;,&quot;10.10.10.30&quot;) or @(&quot;10.10.10.40&quot;)\r\n &#x5B;powershell]\r\n $strHost = @(&quot;10.10.10.40&quot;,&quot;10.10.10.30&quot;)\r\n Get-VMHost -Name $strHost | Get-View | %{$tmpNS = Get-View -Id $_.configManager.networkSystem\r\n $tmpDNS = $tmpNS.NetworkConfig.DnsConfig\r\n $tmpDNS.domainName = $strHostDomain\r\n $tmpDNS.address = $arrDNSsrv\r\n $tmpDNS.searchDomain = $strSearchDomain\r\n $tmpNS.updateDnsConfig($tmpDNS)}\r\n <\/pre>\n<\/li>\n<li>Configuring network,      adding network including VMotion.<br \/>\nSee the script for the full script.<\/p>\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n $vSwitch = Get-VirtualSwitch $strHost -Name vSwitch0\r\n #Set-VirtualSwitch -VirtualSwitch $vSwitch -Nic vmnic1\r\n New-VirtualPortGroup -VirtualSwitch $vSwitch -Name &quot;VMOTION&quot; -VLanId 0\r\n New-VMHostNetworkAdapter -VMHost $strHost -PortGroup &quot;VMOTION&quot; -VirtualSwitch $vSwitch -IP $strVMotion -SubnetMask $strSubnetMask -VMotionEnabled $true\r\n $strNetConfig = Get-View (Get-VMHost $strHost | Get-View).ConfigManager.NetworkSystem\r\n $strIPRoute = New-Object VMware.Vim.HostIpRouteConfig\r\n $strIPRoute.defaultGateway = $strGateway\r\n $strNetConfig.UpdateIpRouteConfig($strIPRoute)\r\n New-VirtualPortGroup -VirtualSwitch $vSwitch -Name &quot;PROD&quot; -VLanId 200\r\n New-VirtualPortGroup -VirtualSwitch $vSwitch -Name &quot;PXE&quot; -VLanId 0\r\n <\/pre>\n<p>If needed you can remove the default VM network<\/p>\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n $vSwitch = Get-VirtualSwitch $strHost -Name vSwitch0\r\n $vmnetwork = Get-VirtualPortGroup -VirtualSwitch $vSwitch -Name &quot;VM Network&quot;\r\n Remove-VirtualPortGroup -VirtualPortGroup $vmnetwork -Confirm:$false}\r\n <\/pre>\n<\/li>\n<li>Reboot the host J\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n Get-VMHost -Name $strHost | %{Get-View $_.ID} | %{$_.RebootHost_Task($TRUE)}\r\n <\/pre>\n<\/li>\n<li>If you want your script to wait for the host to      be rebooted before continuing, you can do it with these two loops.\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n do{\r\n $result = Get-VMHost $strHost\r\n Start-Sleep 10 # Wait 10 sec\r\n }\r\n Until($result.State -ne &quot;Maintenance&quot;)\r\n # Maintenance - because host entered Maintenence mode earlier\r\n\r\n do{\r\n $result =  Get-VMHost $strHost\r\n Start-Sleep 10 # Wait 10 sec\r\n }\r\n Until($result.State -eq &quot;Maintenance&quot;)\r\n <\/pre>\n<\/li>\n<li>Finally exit the host from      maintenance mode.\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n Get-VMHost -Name $strHost | Set-VMHost -State connected\r\n <\/pre>\n<\/li>\n<\/ul>\n<p>If everything is configured correctly, DRS should start migrating VM\u00e2\u20ac\u2122s to the newly added host.<\/p>\n<p>This script helped reducing the time spend on installing and configuring a host from 90 minutes to about 18 minutes. That\u00e2\u20ac\u2122s a reduction of more than 500%, time you can use on other cool PowerShell tasks. J<\/p>\n<p>By using a script to customize our hosts, we also gained two other benefits.<\/p>\n<ol>\n<li>Compliance \u00e2\u20ac\u201c a host is      always installed and configured the exact same way each time.<\/li>\n<li>Each step is documented in      a host specific log file.<\/li>\n<\/ol>\n<p>The full script can be downloaded <a title=\"ESX Deployment\" href=\"http:\/\/www.amikkelsen.com\/?dl_id=28\" target=\"_self\">here<\/a>.<\/p>\n<p>\u00ef\u00bb\u00bf<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last year I was asked to reduce the time spend on installing and configuring our ESX hosts. \u00c2\u00a0Because we weren\u00e2\u20ac\u2122t using Enterprise Plus licenses, we didn\u00e2\u20ac\u2122t have Host Profiles. I came up with a simple two-step process based on the EDA appliance and a custom PowerShell script. Install the host from PXE. Only setting the\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.amikkelsen.com\/?p=577\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[282,285,284,26,283,286,232,330,48],"class_list":["post-577","post","type-post","status-publish","format-standard","hentry","category-powershell","tag-deployment","tag-dns","tag-drs","tag-esx","tag-get-vmhost","tag-hostprofiles","tag-ntp","tag-powershell","tag-script"],"_links":{"self":[{"href":"https:\/\/www.amikkelsen.com\/index.php?rest_route=\/wp\/v2\/posts\/577","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.amikkelsen.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.amikkelsen.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.amikkelsen.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.amikkelsen.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=577"}],"version-history":[{"count":4,"href":"https:\/\/www.amikkelsen.com\/index.php?rest_route=\/wp\/v2\/posts\/577\/revisions"}],"predecessor-version":[{"id":579,"href":"https:\/\/www.amikkelsen.com\/index.php?rest_route=\/wp\/v2\/posts\/577\/revisions\/579"}],"wp:attachment":[{"href":"https:\/\/www.amikkelsen.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=577"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.amikkelsen.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=577"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.amikkelsen.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=577"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}