I’m currently winding down on a datacenter build that has consumed me for the better part of six months. Last night our team went through and stood up vSphere on 200+ hosts. I know that’s nothing for you cloud providers, but that’s a lot of servers for the average IT shop. Being a lights out datacenter we have 3 management paths to every server IP-KVM, ILOM, and serial ports. Going through and setting all that up would have been a pain in the but, so I did a little searching and found how to configure the SUN ILOM via the serial port. With that document and little experimentation I quickly had my script, now all that was left was to learn how to script via a COM port. I turned to BING and found this article which pointed me to a new-to-me .Net Class… about 4hrs later I had a complete solution, and yet another example of the Admin Development Model.
First I created a CSV that contained all the hosts to be loaded thereby making it easy for anyone to modify the parameters.
1 |
<a href="http://get-admin.com/blog/wp-content/uploads/2011/02/ILOM.png"><img class="alignnone size-medium wp-image-1228" title="ILOM" src="http://get-admin.com/blog/wp-content/uploads/2011/02/ILOM-300x172.png" alt="" width="300" height="172" /></a> |
Once I had my input I wrote a simple PowerShell one liner to ingest the data, and extract the location of the server. I could have done this in the csv, but that was being generated by our CMDB, so I chose to do this in script instead.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<span style="color: #ff4500;">$master</span> <span style="color: #a9a9a9;">=</span> <span style="color: #0000ff;">Import-Csv</span> <span style="color: #8b0000;">".ILOM.csv"</span> <span style="color: #a9a9a9;">|</span> <span style="color: #0000ff;">Where-Object</span> <span style="color: #000000;">{</span><span style="color: #ff4500;">$_</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">id</span> <span style="color: #a9a9a9;">-match</span> <span style="color: #8b0000;">'(?w{2})(?d+)RU(?d+)-(?S+)'</span><span style="color: #000000;">}</span> <span style="color: #a9a9a9;">|</span> <span style="color: #0000ff;">ForEach-Object</span> <span style="color: #000000;">{</span> <span style="color: #0000ff;">New-Object</span> <span style="color: #8a2be2;">PSObject</span> <span style="color: #000080;">-Property</span> <span style="color: #000000;">@{</span> <span style="color: #8b0000;">'id'</span><span style="color: #a9a9a9;">=</span><span style="color: #ff4500;">$_</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">id</span> <span style="color: #8b0000;">'hostname'</span><span style="color: #a9a9a9;">=</span><span style="color: #ff4500;">$_</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">hostname</span> <span style="color: #8b0000;">'ip'</span><span style="color: #a9a9a9;">=</span><span style="color: #ff4500;">$_</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">ip</span> <span style="color: #8b0000;">'gateway'</span><span style="color: #a9a9a9;">=</span><span style="color: #ff4500;">$_</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">gateway</span> <span style="color: #8b0000;">'netmask'</span><span style="color: #a9a9a9;">=</span><span style="color: #ff4500;">$_</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">netmask</span> <span style="color: #8b0000;">'row'</span><span style="color: #a9a9a9;">=</span><span style="color: #ff4500;">$Matches</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">row</span> <span style="color: #8b0000;">'rack'</span><span style="color: #a9a9a9;">=</span><span style="color: #ff4500;">$Matches</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">rack</span> <span style="color: #8b0000;">'ru'</span><span style="color: #a9a9a9;">=</span><span style="color: #ff4500;">$Matches</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">ru</span> <span style="color: #8b0000;">'model'</span><span style="color: #a9a9a9;">=</span><span style="color: #ff4500;">$Matches</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">model</span> <span style="color: #000000;">}</span> <span style="color: #000000;">}</span> |
Then I turned my attention to the actual configuration itself. I found that I could just push the commands through via brute force, but didn’t like this solution because it lacked any feedback. It turned out that It was actually harder to get the output then it was to push the commands. Mainly because the Service Processor on a SUN is ridiculously slow I had to insert insane sleeps into my script to actually capture the output.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<span style="color: #ff4500;">$Script:Server</span> <span style="color: #a9a9a9;">=</span> <span style="color: #ff4500;">$master</span><span style="color: #a9a9a9;">[</span><span style="color: #800080;">0</span><span style="color: #a9a9a9;">]</span> <span style="color: #006400;">#open serial connection</span> <span style="color: #ff4500;">$port</span> <span style="color: #a9a9a9;">=</span> <span style="color: #0000ff;">New-Object</span> <span style="color: #8a2be2;">System.IO.Ports.SerialPort</span> <span style="color: #8a2be2;">COM3</span><span style="color: #a9a9a9;">,</span><span style="color: #800080;">9600</span><span style="color: #a9a9a9;">,</span><span style="color: #8a2be2;">None</span><span style="color: #a9a9a9;">,</span><span style="color: #800080;">8</span><span style="color: #a9a9a9;">,</span><span style="color: #8a2be2;">one</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">Open</span><span style="color: #000000;">(</span><span style="color: #000000;">)</span> <span style="color: #006400;">#login</span> <span style="color: #0000ff;">Write-Host</span> <span style="color: #8b0000;">"loging in..."</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">write</span><span style="color: #000000;">(</span><span style="color: #8b0000;">"`r`r"</span><span style="color: #000000;">)</span> <span style="color: #0000ff;">Start-Sleep</span> <span style="color: #000080;">-Seconds</span> <span style="color: #800080;">1</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">write</span><span style="color: #000000;">(</span><span style="color: #8b0000;">"root`r"</span><span style="color: #000000;">)</span> <span style="color: #0000ff;">Start-Sleep</span> <span style="color: #000080;">-Seconds</span> <span style="color: #800080;">1</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">write</span><span style="color: #000000;">(</span><span style="color: #8b0000;">"changeme`r"</span><span style="color: #000000;">)</span> <span style="color: #0000ff;">Start-Sleep</span> <span style="color: #000080;">-Seconds</span> <span style="color: #800080;">3</span> <span style="color: #006400;">#hostname/location</span> <span style="color: #0000ff;">Write-Host</span> <span style="color: #8b0000;">"setting hostname, and location..."</span> <span style="color: #0000ff;">Start-Sleep</span> <span style="color: #000080;">-Milliseconds</span> <span style="color: #800080;">500</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">write</span><span style="color: #000000;">(</span><span style="color: #000000;">$(</span><span style="color: #8b0000;">"set /SP hostname={0}`r`n"</span> <span style="color: #a9a9a9;">-f</span> <span style="color: #ff4500;">$Script:Server</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">hostname</span><span style="color: #000000;">)</span><span style="color: #000000;">)</span> <span style="color: #0000ff;">Start-Sleep</span> <span style="color: #000080;">-Milliseconds</span> <span style="color: #800080;">500</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">write</span><span style="color: #000000;">(</span><span style="color: #000000;">$(</span><span style="color: #8b0000;">"set /SP system_location={0}{1}_RU{2}`r`n"</span> <span style="color: #a9a9a9;">-f</span> <span style="color: #ff4500;">$Script:Server</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">row</span><span style="color: #a9a9a9;">,</span><span style="color: #ff4500;">$Script:Server</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">rack</span><span style="color: #a9a9a9;">,</span><span style="color: #ff4500;">$Script:Server</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">ru</span><span style="color: #000000;">)</span><span style="color: #000000;">)</span> <span style="color: #0000ff;">Start-Sleep</span> <span style="color: #000080;">-Milliseconds</span> <span style="color: #800080;">500</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">readexisting</span><span style="color: #000000;">(</span><span style="color: #000000;">)</span> <span style="color: #a9a9a9;">|</span> <span style="color: #0000ff;">out-null</span> <span style="color: #006400;">#clear buffer</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">write</span><span style="color: #000000;">(</span><span style="color: #8b0000;">"show /SP -d properties hostname system_location`r`n"</span><span style="color: #000000;">)</span> <span style="color: #0000ff;">Start-Sleep</span> <span style="color: #000080;">-seconds</span> <span style="color: #800080;">3</span> <span style="color: #0000ff;">Write-Host</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">readexisting</span><span style="color: #000000;">(</span><span style="color: #000000;">)</span> <span style="color: #000080;">-ForegroundColor</span> <span style="color: #8b0000;">'Green'</span> <span style="color: #006400;"># set IP</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">write</span><span style="color: #000000;">(</span><span style="color: #000000;">$(</span><span style="color: #8b0000;">"set /SP/network pendingipaddress={0}`r`n"</span> <span style="color: #a9a9a9;">-f</span> <span style="color: #ff4500;">$Script:Server</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">IP</span><span style="color: #000000;">)</span><span style="color: #000000;">)</span> <span style="color: #0000ff;">Start-Sleep</span> <span style="color: #000080;">-Milliseconds</span> <span style="color: #800080;">500</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">write</span><span style="color: #000000;">(</span><span style="color: #000000;">$(</span><span style="color: #8b0000;">"set /SP/network pendingipnetmask={0}`r`n"</span> <span style="color: #a9a9a9;">-f</span> <span style="color: #ff4500;">$Script:Server</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">Netmask</span><span style="color: #000000;">)</span><span style="color: #000000;">)</span> <span style="color: #0000ff;">Start-Sleep</span> <span style="color: #000080;">-Milliseconds</span> <span style="color: #800080;">500</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">write</span><span style="color: #000000;">(</span><span style="color: #000000;">$(</span><span style="color: #8b0000;">"set /SP/network pendingipgateway={0}`r`n"</span> <span style="color: #a9a9a9;">-f</span> <span style="color: #ff4500;">$Script:Server</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">Gateway</span><span style="color: #000000;">)</span><span style="color: #000000;">)</span> <span style="color: #0000ff;">Start-Sleep</span> <span style="color: #000080;">-Milliseconds</span> <span style="color: #800080;">500</span> <span style="color: #0000ff;">Write-Host</span> <span style="color: #8b0000;">"Setting IP..."</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">write</span><span style="color: #000000;">(</span><span style="color: #8b0000;">"set /SP/network commitpending=true`r`n"</span><span style="color: #000000;">)</span> <span style="color: #0000ff;">Start-Sleep</span> <span style="color: #000080;">-Seconds</span> <span style="color: #800080;">5</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">readexisting</span><span style="color: #000000;">(</span><span style="color: #000000;">)</span> <span style="color: #a9a9a9;">|</span> <span style="color: #0000ff;">out-null</span> <span style="color: #006400;">#clear buffer</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">write</span><span style="color: #000000;">(</span><span style="color: #8b0000;">"show -d /SP/network properties ipaddress ipnetmask ipgateway`r`n"</span><span style="color: #000000;">)</span> <span style="color: #0000ff;">Start-Sleep</span> <span style="color: #000080;">-seconds</span> <span style="color: #800080;">2</span> <span style="color: #0000ff;">Write-Host</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">readexisting</span><span style="color: #000000;">(</span><span style="color: #000000;">)</span> <span style="color: #000080;">-ForegroundColor</span> <span style="color: #8b0000;">'Green'</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">write</span><span style="color: #000000;">(</span><span style="color: #8b0000;">"exit`r`n"</span><span style="color: #000000;">)</span> <span style="color: #ff4500;">$port</span><span style="color: #a9a9a9;">.</span><span style="color: #000000;">Close</span><span style="color: #000000;">(</span><span style="color: #000000;">)</span> |
I considered writing a control loop to handle the whole process, but then remembered my golden rule of scripting… don’t automate more then you have to. In other words I had what I needed, and needed to move on. I wanted to re-factor the whole thing and create something more elegent, but when performing administrative scripting don’t get caught up in all that. We’re not developers we need solutions, and we need them quickly. This script will be used once and then thrown away it simply wasn’t worth my time to optimize it… no matter how bad I wanted too.
Anyways now that I had all the components it was time to trow it all together. At this point I turned my attention to the user interface. I would have prefer a simple function, but the team has members that aren’t scripters, and there was talk of bringing in some extra hands to help. Therefor I chose to put it in a simple GUI to remove any hesitation. Currently my favorite tool for task like this one is PrimalForms it’s just fantastic at whipping up simple winforms in no time at all.
So after a little debugging I finished my little utility. All in all, not only did we successfully configure all the ILOM’s in one night, but I fun doing it.