Category Archives: Windows Server 2008

An adventure in Powershell and the vSphere PowerCLI

I’ve always found a good way to get started with a new language is to just go head into it trying to solve some problem you’re working on, then ask the Internet via a search engine how to do something you want to do.

Today I started for the first time with PowerShell. Here’s the problem I was trying to solve:

I have a lot of VMs that I want to bring up for a class that I’m giving. There could be between 10-50 people at any given class. What I need to do is clone a master VM from a template, change its MAC address to something I have reserved in my DHCP server, and then power it up.

All of this can be done via vCenter.  But its a slow and painful point-and-click-yourself-to-death process. Automation is the way to get this done.

All of this can be done via xCAT.  But I figured why not give it a try.  Other people can live without xCAT.  Maybe I can too.

I have a history of perl. Yes, I have lots of skeletons in the closet with that language. So I was going to do all of this with Perl. But I figured that since I was going to be doing power shell scripts anyway for the UCS emulator portion, why not just do it all with the same thing? So I gave it a shot.

First off, the Windows editors suck. I had to stick with VIM because there’s nothing better for me. Let’s not even argue about that. +1 for me for retaining my dignity.

Next, after installing the VMware PowerCLI tool it was pretty easy.

CreateVMs.ps1

Here’s the script to clone 9 VMS from a template called UCSPEMaster.  I just change it depending on how many I need.

1..9 | foreach {
    # pad each name with 0s so we have: ucspe08,ucspe09,ucspe10,...
    $strNum = [Convert]::ToString([int]$_)
    $suffix = $strNum.padLeft(2,"0")
    New-VM -VMHost 192.168.1.4 -datastore datastore1 -Template UCSPEMaster \
           -Folder 'UCS-Name UCSPE0$suffix -diskstorageFormat Thin \
           -Location 'UCS Emulators' -runAsync
}

Notice that each machine will be called UCSPEXX, where XX is the range I specify. That way if
4 more people walk into the class after I’ve configured 14, then I can do 15..8.

I also put all of them on the same host (192.168.1.4), the same datastore (datastore1), the same Folder (UCS Emulators), and made them thin clones.

If you have a cluster running Storage DRS (vSphere 5.0+) then you don’t have to specify the datastore and DRS will put it where it sees fit.

ConfigVMs.ps1

The only thing I need to do now is change the MAC address to something that I have reserved.  That way, I can tell the user to just log into the IP address that I’ve set up beforehand.  I’ve configured 60 IP addresses so that I’m ready for a big class.

get-vm UCSPE* | foreach {
    $number = $_.name.Replace("UCSPE","")
    $hexNumber = [Convert]::ToString([int]$number, 16)
    $lastPart = $hexNumber.PadLeft(2,"0")
    $adapter = Get-NetworkAdapter $_
    write-host "Changing MAC address for $_"
    Set-NetworkAdapter -NetworkAdapter $adapter \
          -MacAddress 00:50:56:00:01:$lastPart -Confirm:$false
}

Most of the script is made up of getting the last number part of the VM name. Since each VM is named UCSPE01-UCSPE60 then it grabs the 60, converts it to hex, then adds that as the last part of the MAC address of the adapter. This will work as long as I don’t have more than 255 VMs.

I could have put a Start-VM on the end of this.  Generally, that’s just a powershell one-liner:

Get-VM UCSPE* | Start-VM

removeVMs.ps1

The last script will just remove these VMs.  As I tweak around with them, or as people in the class tweak around with them, I just want to erase them and start fresh for the next class.  This is fairly easy:

Get-VM UCSPE* | foreach {
    Stop-VM $_ -confirm:$false
    Remove-VM $_ -DeleteFromDisk -confirm:$false
}

The only thing I need to update this with is to not power it off if it isn’t on.  It throws some nasty errors if it’s not powered on.  But I’ll do that some other time.

I’ll get this lab working with PowerShell.  It’s not a bad language.  It’s another tool in the handbag.  I still prefer command line scripting with Bash or Perl.  But every now and then its fun to go over and see how the other side lives.  Now, back to xCAT.

ImageX Windows 2008 with vCenter Server

With xCAT I used the imagex capabilities to clone a machine (virtual machine) with vCenter on it and now I’m installing that captured image to another virtual machine.  One reason I do it this way as opposed to creating a VM Template is that now I’m able to deploy to physical and virtual servers.  In addition I can deploy to KVM VMs and VMware VMs.

Anyway, when I restarted the cloned disk, I couldn’t start vCenter Server on it. This is something that I assume happens with all windows images that you run sysprep on regardless or not whether its xCAT induced.

There were a lot of error messages as I trolled through the logs and I searched on all of them:

“Windows could not start the VMware VirtualCenter Server on Local Computer.  For more information, review the System Event Log.”

“the system cannot find the path specified. c:\Program Files (x86)\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\master.mdf” (odd to me, since the file did actually exist!)

“could not start the SQL Server (SQLEXP_VIM) on Local Computer”

I tried all these google terms with little success:

“Virtual Center will not start after reboot”

Finally, I found this post: that finally made sense to me, so I gave it a shot.  Here’s exactly what needs to be done:

Step 1

Log into Windows Server 2008 machine and go to ‘Services’

Step 2

Right click on ‘SQL Server (SQLEXP_VIM)’  and click on Properties

Step 3

Under ‘Log On’ check the Local System account and also check ‘Allow service to interact with desktop’

Step 4

Start the ‘SQL Server (SQLEXP_VIM)’ service.  It should start up without errors.

Step 5

Do the same procedure (Steps 2-4) to the ‘VMware VirtualCenter Server’ service.  This should now start up and you should be able to connect to Virtual Center.

Well, that wasted about 4 hours of my time, but its nice to have a happy ending.