VM Storage Balancer

One thing I’ve noticed in vCenter 4.0 is that it now has alarms to monitor datastore sizes and places little ‘warning’ or ‘alert’ icons.  I like it, but it also annoys me because I know I need to do clean up and make sure each of our datastores has a minimum of 20% free space.  So here we are: Move-VMStorageBalance.ps1


Running this script will attempt to storage vMotion systems in a specified cluster around to datastores that have more than x% of free space before and after the move. Systems with specified DRS rules are omitted by default.  I’ve left some defaults defined in two variables that you will need to change to work for your environment.


  • Powershell 2.0
  • PowerCLI 4.0
  • vCenter 4.0 or ESX 4.0


  • Use this script @ your own risk, I take no responsibility for any awesomeness that might occur.  Test, test, and test more.
  • Script may be SLOW as it works against 1 VM at a time.
    • Fast if the detected cluster datastores are already balanced.
  • Script is only as smart as what information you provide.
  • Script contains no logic to handle VM’s with vmdk’s located on multiple different datastores.
  • If disk performance is an issue in your enviro, then DO NOT RUN this script.

My Env Before:


My Env After:


Detailed Logic Walkthrough:

1. Prompts user for vCenter Name

  1. a. Checks if name is valid exits if not

2. Prompts for Cluster Name

  1. a. Check if name is valid exits if not

3. Gathers Datastore information and measures whether there is an aggregate of x% free space available.

  1. a. Excludes datastores that have ‘local’ or ‘nfs_share’ in their name.
  2. b. Exits if the aggregate shows less than x% available.
  3. c. Returns what the script calculated as aggregate datastore capacity.

4. Checks DRS Rules

5. Gathers VM’s in cluster and omits any that are apart of DRS Rules

6. Now it begins a loop per VM.

  1. a. Gathers current datastore data
  2. b. Finds datastores with more than x% free space
    1. i. If none found, assumes cluster has been balanced and exits
    2. ii. If number of datastores with free space is equal to total number of datastores, assumes cluster is balanced and exits.
  3. c. Calculates size of VM by adding all HDD’s and RAM.
  4. d. Subtracts datastore free space amount from calculated VM Size, divides result by datastore capacity to get a percentage of free space if VM moves to targeted datastore.
    1. i. If the calculated percentage is less than x%, VM does not move.
      1. 1. Reports back that VM cannot move to target datastore name.
    2. ii. If the calculated percentage is more than x%, VM moves to new datastore.
      1. 1. Reports back that it is moving VM to targeted datastore name.
    3. iii. If VM already resides on that datastore, nothing happens.
    4. iv. Loop

7. After loop is completed, script checks to see if there are any datastores with less than x% of free space.

  1. a. If found, reports that additional space may be required to balance datastores.

If none found, reports that datastores are balanced and should have @ least x% of free space on each datastore.

Script can be viewed and copied from here

Windows 2008 IPv4 gateway keeps disappearing after reboot…



Windows 2008 Std/Ent Sp2 x86


After reboot of system, the system stops responding to pings and RDP. When accessing IPv4 settings, the gateway is missing, and will blank out every time.


  1. Regedit
  2. Navigate to HKLM/System/CurrentControlSet/Services/Tcpip/Parameters/Interface/%CLSID%
    • %CLSID% = A unique ID that is associated with each network adapter that you have on the machine. You should have one for each adapter installed on your server.
  3. Change the "DefaultGateway" Regkey and manually type in the correct IP.

Finding local networked devices via your Mac’s web browser by name instead of IP.



Unable to connect to locally available network devices via their friendly name.


Mac OS 10.x (10.5 or 10.6)


I’ve found this to be only true for Macs. For example:

When I try to connect to my NAS’s web admin console via the name I gave it (http://zterastation), my Mac cannot resolve the name. Yet, my Mac does find it by name in the list of available drives to connect to.

Seems the fix is simply to append ‘.local’ to a locally available network devices friendly name. As so, http://zterastation.local . This could simply be in the way my router configures my DNS entry order, but does not seem to matter to my windows systems.

Exploring VMWare's API using PowerCLI Get-View


How to explore properties of objects using PowerCLI’s Get-View cmdlet.


Figure out the object you want to dig in deeper about. For example, finding out all properties available about an ESX host.

Declare your variable, run the get-vmhost cmdlet, then pipe that to get-view, like so:

   1: $myvariable = get-vmhost myesxserver | get-view

Now by simply typing $myvariable at the powershell prompt, I’ll get a return like this:


If I want to find out more about what is under the “Summary” property, I can simply type $myvariable.summary then hit enter.Get-ViewExample2

You can continue to do dive deeper to find the information you are looking for quickly and effectively by using this method. The ‘tab’ auto-complete function also works. Cheers!

Changing Run Once entries in multiple Virtual Center customization specs...



Script built to update multiple Virtual Center Windows customization scripts in one easy step.

Powershell Code:



I have several customization scripts that all are configured in almost the exact same way minus IP gateway settings (thus the need for many specs). I needed to add a couple more run once commands to to fix an issue we were having with McAfee ePO agents that were statically installed on templates. The agent apparently generates a unique GUID and mac address in the registry associated with the systems name. To fix this when cloning the template I needed to delete these two registry entries so ePO would regenerate new ones when the cloned template builds it would register properly with ePO.

There is probably a bit more that can be done with this script, but it’s done what I need it to do for now.

Send photos from the iPhone to a Japanese Cell Phone

To successfully send e-mails w/ an attached photo from an iPhone to a Japanese cell phone, the photo needs to be resized to either 640x480 or 320x240. Photos taken with the iPhone's camera do not meet these size requirements. One app that I've discovered to help with that is called MailPhotos. It's fairly easy to use and has worked fairly well in my testing. Read below for detailed information.
[Update: Does not apply to all Japanese cell phones apparently. Seems to depend on a combination of phone and/or carrier. My in-laws use AU, which this app works for, my friend in Tokyo uses Docomo and has a crazy phone that works fine with the default size.]

One of my main complaints with using the iPhone was the inability to send photos via e-mail to my friend's cell phones. I couldn't figure out what the issue was for the longest time, until recently when testing. Seems any photo larger than 640x480 sent to a Japanese cell-phone doesn't seem to make it through. So I began my quest to find an app to resize my photos to a compatible size.

I finally came across this app called "MailPhotos". It's 0.99 cents, so I figure the worse that could happen is that I'm out a buck. So I was pleasantly surprised to find that this app does exactly what I need it to do. Below what you see is the main page of the app which is essentially an e-mail template. I configured the app w/ my gmail account and it has worked flawlessly.

This screen below is presented when you select the photo that you want to attach. Again to successfully send a photo to a Japanese cell phone, the photo must be sized as 640x480 or 320x240. Once you've selected the size of your choice, select add photo. Then send it off.

Gather disk.usage.average stats per Datastore

Windows PowerShellImage via Wikipedia

This script isn't perfect as there can be some exceptions to the rule, but it can give you an idea of how much you are utilizing to each of your datastores to determine if there might be a bottleneck.

The script first gathers your datastores, then does a get-vm to list all VM's located in that datastore.
For each VM, get-stat is run to gather the disk.usage.average metric for the date range specified in the $start and $finish variables.
Once that data is gathered for that VM, it takes the KBps data and mathematically averages those numbers then continues to the next VM in that Datastore.
After averages for all VM's in the datastore have been calculated, they are all added up to represent the Average disk usage KBps against that datastore.

This is repeated for each datastore.

  1. If a system has been vmotion'd to another datastore within the specified date range, the averages could be thrown off.
  2. Systems that have multiple drives located on different datastores, the script cannot differentiate disk usage stats between different disks.
  3. Other things that I may not have accounted for, feel free to comment.
Extra Stuff:
  1. CSS Style to make the html output look nice. Place it in the same directory as the htm file. You can dynamically generate this file w/ powershell if so please too.
  2. JavaScript file for dynamic sorting capability by clicking table headers. Place in the same directory as the htm file.

iPhone Google App now includes Ninjas!

The iPhone Google App now includes Ninjas....freakin sweet! LOL

Convertto-html, firefox, chrome, CSS rendering problem

To prevent whitespace and/or bloat in your html file use the "-encoding ASCII" switch for the "out-file" cmdlet.

Problem Statement:
I've finally gotten a script to pull a bunch of information then convert it into a fairly clean looking html page. It renders perfectly hosted on IIS with an IE browser pulling CSS and JS for readability and sort capability. The problem is that firefox, chrome, and safari doesn't render the CSS style and JS. Here is the kicker. It's not that the html code, CSS, or JS are bad, but that the html file seems to be bloated w/ white space.

So, powershell generates the html code that should be only equal to 3KB, but the file ends up being double that @ 6KB. So you can literally copy and paste the code into a blank txt doc, convert it to htm, then low and behold, it renders just the same in all browsers. I'm working to figure out how I can clean up this whitespace. So far, just grabbing the file info, w/ the get-content and out-file cmdlet's doesn't seem to work, but I haven't really tried in depth yet.

[Update: All that is needed is the "-encoding ASCII" switch for the out-file cmdlet. I've updated the w/ this info as well script.]

New Powershell VMWare Summary Report Script using functions

UPDATED and Optimized Script can be found HERE.
I'm hoping this is easier to read for any interested. Things I track in this script are as follows:
  • Cluster Name
  • # of Effective Cluster Hosts
  • # of VM's in the cluster
  • # of allocated vCPU's
  • VMWare supported maximum of vCPU's per core
  • Datastore full size
  • Datastore free space
  • Datastore used space as a percentage
Above is an example pic of what the script generates and how it should look.
The script is posted here. I suggest copying and pasting into a Powershell editor like PowerGUI or Powershell PLUS for readability.
It automatically generates an html and stylesheet file and places them on your C drive. You can change a bunch of variables that are commented toward the top of the script. Hope you can find this useful.

[Update: I've added sort capability to the code via a Javascript library which can be downloaded here.]

Powershell html formatting using convertto-html cmdlet

This was took me a little bit to figure out, but I finally did. Wasn't able to find this solution on the web so I figure I would post what I had to do to make it work. I basically had a 'if else' statement that I wanted the return of an if statement to highlight in red and be bolded in html. Unfortunately, the convertto-html cmdlet converts '<' and '>' to html friendly formats for display like '&lt;'and '&gt;'.

So here is the key:

foreach {$_.replace("&lt;","<").replace("&gt;",">")}

Afterwards, you can pipe to a file where the formatting you placed in your code stays intact.

VI3 Statistics Script

The script does the following:
  1. Grabs Number of Hosts per Cluster
  2. Grabs Number of VM's per Cluster
  3. Determine maximum number of VM's per cluster based on your determined ratio
  4. Current capacity % based on your defined max
  5. Total SAN/Datastore space per cluster
  6. Total SAN/Datastore space per cluster currently in use
  7. Total SAN/Datastore per cluster Free space.
  8. SAN/Datastore space currently in use per cluster in percent.
I'm still getting my feet wet w/ this Powershell thing, but I feel I'm slowly getting the hang of it. As one of my first fully written from scratch scripts, I'm kinda proud. It's an ugly beast that could probably written a lot cleaner, but it's my ugly beast. You'll probably want to copy and paste into PowerGUI for readability.


Windows 7 Beta

Jumping back and forth between Mac (home) and Windows/VMWare (work) has been fun for the past 2 years. If I had my choice, I'd probably dump Windows at work to exclusively use Mac. Although, I'd been reading that the new Windows 7 addresses alot of gripes people had w/ Windows Vista (I use Vista 64-bit and XP at work). So I've downloaded the Beta and installed on one of my extra laptops.

Laptop Specs:
Intel Core Duo T2050 1.6GHz
1024MB RAM
Intel Mobile 945 Graphics

Not the greatest specs in the world, but good enough to trial Windows 7. Install was pretty straight forward, just like Vista. Once I booted into the OS, it was fast and zippy, more so than my Vista box when I first built it. The new windows explorer bar acts much like the Mac dock in that you can 'pin' your applications to it and when run it simply 'highlights' much like the Mac's 'dot'.

The one up that Windows 7 has vs. Mac is that it stacks multiple instances in that one 'pinned' app. So you can just mouse over the stack and it shows you all different instances that app. I kinda like it better than Mac's Expose, but it is essentially the same idea done in more of a Windows/PC user friendly fashion.

Much to my surprise as well as most reviewers, Windows 7 is surprisingly stable for a beta. I would highly suggest you give it a try. For me personally though, I don't think I'm quite convinced to give up my Mac and switch back to PC for my laptops/home use. Resume time from sleep is still somewhat slow in comparison to my Mac.

Set-OSCustomizationSpec Bug?

Here are the required options for the "Set-OSCustomizationSpec" for windows custom spec script.
$Creds = Get-Credentials
Set-OSCustomizationSpec -spec * -domain "mydomain" -DomainCredentials $Creds -Fullname "Chris" -ChangeSID 1
PowerShell 1.0
VI Toolkit Update 1 Build 113525

Full Story:
I have several customization specs setup because of multiple networks segments. They are all pretty much identical in the way they are setup, except the gateway. It's kind of a pain to edit them through the GUI one by one, so I decided to try the "Set-OSCustomizationSpec" cmdlet. It's straight-forward for the most part, but seems to have some bugs associated with it. Here is the string I started with:
Set-OSCustomizationSpec -spec * -domain "mydomain"
This produces an error however, requesting that I also use the "-DomainCredentials" switch. My existing specs already have this information filled out, so it seems stupid that I HAVE to include this information. Anyway, here is what I tried next:
$Creds = Get-Credentials
Set-OSCustomizationSpec -spec * -domain "mydomain" -DomainCredentials $Creds
Success!... well kinda sorta... I went to review the scripts and the "FullName" field was blanked out and the "ChangeSid" checkbox went from True to False. (sigh)... This is an obvious bug in the toolkit. So to work around this here is the final script that worked:
$Creds = Get-Credentials
Set-OSCustomizationSpec -spec * -domain "mydomain" -DomainCredentials $Creds -Fullname "Chris" -ChangeSID 1
I've also posted this to the VMWare Communities.

Netshare App by NullRiver

Those lucky few who were able to swoop in and buy the NetShare app while it was online were lucky to get tethering capability w/ their mac. Sadly since the app was only released for a short while it seems that the app has it's downsides. Mainly being that I can only seem to get internet access using my iPhone through the Safari/Webkit browsers. The moment I try to use firefox or any other internet type of application, I get nowhere or it tries to save a file.

Even setting up the proxy settings within the specific apps (where applicable) gets me no where. While $9.99 for free pseudo-tethering capability is pretty good, it just sucks that I can't use any other app besides Safari. Oh well, can't win them all I suppose.

Picasa for Mac at long last...

Get ready to kick iPhoto to the curb and begin using what PC users have been enjoying for a couple of years now. This was one piece of software that was killing my mac experience because going from Picasa to iPhoto absolutely sucks. A free photo management and editing software. Better yet, you can backup your photos by uploading to your Picasa web album, order prints online, make collages, and touch-up your photos with incredible ease.