Author Archive

Identifying SAN disk usage using WMI – Powershell – Script of the Day

March 11, 2011 Leave a comment

So I was commissioned with identifying the amount of actual disk space used by a bunch of Microsoft Servers that were attached to various SANs on our network. Unfortunately, despite us having a rather expensive vendoir supplied product for doing this reporting, the vendor product(s) is/are dependent on agents running on the servers to actually report back what the performance stats look like.

I fugured that the information must be accessible via WMI so I set about trying to identify something that identified disks as being remote / SAN attached.

I had a crack using several different WMI classes, thinking that I may need to tie the results from a hardware based query to identify physical disks, against the results of something like the win32_logicaldisk class – but was drawing a blank.

to identify similarities / differences betwen hosts I decided to just spit our the results of the Disk / Volume classes for a handful of hosts

I tried the following classes:

After interrogating a few hosts (some SAN attached, some not . I noticed a similarity in the device IDs returned in the following class win32_Volume.

you see all of our servers are set to have local disk for the C: and CDROM for the Z: (so I had a control group)
Executing the following however . . against a LONG list of server seemed to always return C: and Z: with device IDs in the format:


Now I have looked around for an explanation as to why all the Local Disks and Local CD Roms appear with tat number at the end, but I can find no confirmation – but I figured I’d simply create a PowerShell script using this snippet of info to generate the report I require.

First of all, the wmi query that I would need :
gwmi -ComputerName <servername> -class win32_volume | select deviceid, driveletter

Now all I need to do is contruct a method to repeat the above and churn out a nice Excel style report to show disk utilisation . .

Here is the result

Function get-sandisks ([string]$InputFilename,[string]$OutputFilename)
$servers = gc $InputFilename

$MyObj = @()
# Cycle through the servers in the file
foreach ($server in $servers)
{Write-Host $server -ForegroundColor Green
# first test if we can ping the server (quicker than trying WMI straight away)
If (Test-Connection $server -Count 1)
if (Get-WmiObject -ComputerName $server Win32_LogicalDisk -ea 0)
{$disks = gwmi -ComputerName $server -class win32_volume | ?{$_.driveletter} #| ?{$_.deviceid -notmatch "806e6f6e6963"} #| select deviceid, driveletter
If ($disks)
{foreach ($disk in $disks)
$rep = "" | select "Server Name", "Drive Letter", "Disk Space", "Used Space", "Free Space", "DeviceID", "Type"
$Rep."Server Name" = $server
$Rep."Drive Letter" = $disk."driveletter"
$Rep."Disk Space" = $disk | %{$_.Capacity}
$Rep."Free Space" = $disk | %{$_.Freespace}
$Rep."Used Space" = $Rep."Disk Space" - $Rep."Free Space"
If ($disk.deviceid -notmatch "806e6f6e6963"){$rep.Type = "SAN"}
{$Rep.Type = "Local"}
$Rep."DeviceID" = $disk | %{$_.deviceID}
Write-Host $rep
$MyObj += $Rep
$rep = $null
$rep = "" | select "Server Name", "Drive Letter", "Disk Space", "Used Space", "Free Space", "DeviceID", "Type"
$Rep."Server Name" = $server
$Rep."Drive Letter" = "WMI"
Write-Host $rep "WMI" -ForegroundColor Yellow
$MyObj += $Rep
$rep = $null
{              $rep = "" | select "Server Name", "Drive Letter", "Disk Space", "Used Space", "Free Space", "DeviceID", "Type"
$Rep."Server Name" = $server
$Rep."Drive Letter" = "PING"
Write-Host $rep "PING" -ForegroundColor Yellow
$MyObj += $Rep
$rep = $null
$MyObj | sort | Export-Csv -Path $OutputFilename -NoTypeInformation

While I appreciate that this is  not 100% accurate, I simply wanted to report on space that is in use by the SAN and is no local disk, so the result is fit for my purpose.

Copying data to a VM datastore using PowerCli – Script of the Day

March 8, 2011 Leave a comment

Ever needed to copy data from your local machine to a VMware datastore . .and not felt like messing around with winSCP / FastSCP, the Datastore browser etc?

PowerCli / PowerShell lets you create a new PSProvider item for your datastore, which in turn lets you copy data using the normal Copy-Item syntax. (though using Copy-DatastoreItem instead)

So, if you have a Datastore in your ESX environment called ‘Datatstore1’ and you want to copy an iso from your C:\ISO directory, it would be as simple as

PS: >new-PSDrive -location (get-datastore 7523_local) -name myds -PSProvider VimDatastore -Root '\'
Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
myds                                   VimDatastore  \lonlab001@443\Prod\7523_local
PS: >Copy-DatastoreItem -item C:\ISO\install.iso -Destination myds:\ISOS\Myiso.iso -force

Also, as the drive is now a normal PSProvider path, normal commands like get-childitem work like they do on a local drive

PS: >gci myds:
   Datastore path: [7523_local]

            LastWriteTime            Type       Length Name
            -------------            ----       ------ ----
     21/04/2010     07:40          Folder              esxconsole-4bcdbd...
     08/03/2011     16:31          Folder              ISOS


Of course this gives you full access to all of the datat on your datastores directly form a PowerCli session, so you can run any sort of reports / inventories etc that you may need. Happy days . .

Categories: Powershell, Scripting, VMWare

‘Upgrading’ from ESX to ESXi – a multipart series – Tools

March 2, 2011 Leave a comment

Setting up the test environment

In order to get this whole build tested, we need a repeatable and accessible Lab environment.

If you are unfortunate enough to not have an ESX lab environment that you can play on, you could build a workstation and emulate your production environment right on your desktop using VMware workstation.

Tools that we’ll require (so need to download if you do not have them already) are as follows:


· Installation guide

· Download : (you’ll need a free logon)

You favourite script editor

· I use PowerGui : – but you can use anything you like

A VMware ESXi Server, or VMware workstation to run tests on, along with a copy of the ESXi Installable media

· – you can get trials of both from here

Copies of the various tools we’ll be testing

· UDA (Ultimate Deployment Appliance) –

· EDA (ESX Deployment appliance) –

· VMware’s own ‘Auto Deploy’ –

· SD / USB duplication – WinImage –

· V-PXEServer –

· Manual installation – Just the Install ISO above

Assuming that not everyone has spare hardware at their disposal, I guess it would be useful to create VMs to act as ESXi hardware on which to test our installations.

If you’re using VMWare workstation as your lab – Full guide at:

Quick Video:

If you are using an ESX(i) host to run your test ESXi VMs on, follow the guide at :

For each appliance based deployment method, we’ll create a new VM – these will be detailed as we test each appliance

Categories: Virtualisation, VMWare

‘Upgrading’ from ESX to ESXi – a multipart series – Intro

March 2, 2011 Leave a comment

‘Upgrading’ from VMWare ESX 4.0 to ESXi 4.1(u1) – with as few button clicks as possible.

Anyone reading the official docs from VMware at : is likely to be annoyed and frustrated at the lack of actual information as to how to manage the ‘upgrade’ (migration) from ESX to ESXi.

There is no direct way to upgrade directly as the 2 products are effectively 2 different operating systems that behave in exactly the same way. (well not really, but they are installed totally differently and are managed slightly differently)

Anyway, we have about 80 ESX hosts to migrate to ESXi, so I decided to find the easiest method to do so.

A scour of the web found several great resources. – and some valuable information. It seems that nobody has yet delivered a full ‘upgrade’ solution, but several people have provided automated deployments of the core installation and several other people have created configuration scripts for the newly installed ESX. So I have decided to add an additional ‘information gathering’ step, then ‘borrow’ some of the work done elsewhere and put together an ‘upgrade’ solution.

Scratching my head, I have been working on a simpler way to manage the deployment / upgrade.

The way I see it, the ‘upgrade’ needs 3 parts:

1) Capture configuration from the existing ESX host that we will be replacing (we may need to interpret and reformat it for our new ESXi Host

2) Deploy new ESXi instance on the hardware

3) Deploy captured config to our new ESXi host.

Whilst I realise that this probably will not be enough to make it a full ‘upgrade’ the idea is to get as much done as quickly as possible.

Coming up will be several posts, documenting comparisons of 5 methods of deployment, as well as some PowerCli code and a look into Host Profiles for easing this process.

On the off chance that one of the vendors that do ‘migration’ tools feel like offering me a free license to trial their tool and write up a process doc, I may even be inclined to review that for people with $$$ – but it is important that it is noted that I promise no allegiance to any tools, as would like this review to be fair and open to all. The end product of the series should provide a decision as to my preferred FREE method for doing the migration.

At the end of the series, I’ll create a comparison table comparing the various products, as a springboard for anyone who’ll soon be in the same situation as me.

For environments where there are only 2 or 3 ESX hosts, I’d consider building a solution like this going overboard, so I will make the assumption that readers of the series are people who have large numbers of hosts to upgrade and therefore will be wanting to work on ESX / ESXi rather than VMware workstation. As such, I will endeavour to get all tools working on ESXi and will highlight tweaks required (several of the tools I have tested so far were created on VMware workstation and therefore do not import directly to ESX hosts)

Products that I will be including in my review for the deployment include:

1. UDA (Ultimate Deployment Appliance) –

2. EDA (ESX Deployment appliance) – (0.90 in VMware appliance Marketplace, but 0.94 available at: )

3. VMware’s own ‘Auto Deploy’ –

4. SD / USB duplication

5. Manual installation (I will include this as a benchmark – remember ESXi requires very few clicks as is to get running, so manual may still be the way to go)

I will go through the options for the deployment of ESXi, before doing the capture and deploy steps above (I need a deployment workframe to work on, so it makes sense in this case)

All tests for now will be run in my isolated lab, with the convenient luxury of the deployment servers being located on the same subnets etc as the Hosts I’ll be deploying to, but once I have selected a solution and start the migration of 80 ESX hosts to ESXi, I will of course post details of any further tweaks required for deployment.


Categories: Virtualisation, VMWare Tags:

Script of the Day – Scripted start of Virtual Center when hosted as a VM

February 25, 2011 Leave a comment

There are many threads on the VM communities, debating whether it is better to run a VC on a physical host, or a VMWare host.

My answer is always that running it as a VM is better, but the arguement always comes back that if I have catastrophic faiilure and don’t know where my VC last lived . . I will be in trouble.

Of course, plan a is to simply set the restart policy on the VM to start with the host, but people tell me they have had mixed results with this approach.

The alternative is a quick PowerCli script that quickly connects to each ESX host in the cluster, checks if it owns the VM, then starts the VM.


$vCenters = "ESXHost1", "ESXhost2", "ESXHost3"
$VCServer = "VCServer"
$userName = "username"
$passwd = Read-Host ("Password for " + $userName) -AsSecureString:$true
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $userName,$passwd


One catch to be aware of though is that if you are using AD for DNS and all AD servers are VMs, you will be unable to resolve the ESX host names for the script to work, so you’ll need to specify IP addresses to the ESX hosts.

You do not however need to specify the DNS server IP for the VM, as the script look s as VM Names and

You could extend the above script then to start a series of VMs with a set wait time between VMs (e.g. start the DC for DNS etc, then start the SQL server, then start the VC, wait 60 seconds between each start)

<pre>Disconnect-VIServer * -Confirm:$false
$vCenters = "", "", ""
$vms = "DNSServer", "SQLServer", "VCServerName"
$userName = "root"
$passwd = Read-Host ("Password for " + $userName) -AsSecureString:$true
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $userName,$passwd
# time to wait before starting next VM
$waittime = 60

Foreach ($vm in $vms){
 ForEach ($vCenter in $vCenters) {
 connect-VIServer -Server $vCenter -Credential $cred
 If (get-vm $VCServer -ea 0)
 Start-VM $vm
 Write-Host "VM $VM Starting on $vCenter" -ForegroundColor Green
 Write-Host "Sleeping for $waittime to allow $vm to start up"
 sleep $waittime
 disconnect-VIserver -confirm:$false

And if you are feeling really flash, you could get each VM start, then monitor that VM for a particular services on thon that VM to run, before starting the next VM (if you have relevant access rights etc)

Prime example here is where I need a VM running my AD/DNS to start, before I can start the SQL server. Then, I want te SQL server to start and the service running, before I can start the Virtual Center.

# remove any VI connections that you may create in your PS Profile
Disconnect-VIServer * -Confirm:$false
# List of ESX hosts (by IP here as we are assuming DNS lives on a VM)
$ESXHosts = "", "", ""
# 2 dimensional array, each row reflecting the VM to start and the service that I need to monitor
$vms = ("ADDNSServerName", "DNS"), ("SQLServerName","MSSQLSERVER"),("VCServerName","vpxd")
$userName = "root"
$passwd = Read-Host ("Password for " + $userName) -AsSecureString:$true
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $userName,$passwd

# Connect to all ESX hosts in array $ESXHosts
ForEach ($ESXHost in $ESXHosts) {connect-VIServer -Server $ESXHost -Credential $cred}
Foreach ($vm in $vms){
 Write-Host "Searching for $vm[0]" -ForegroundColor Blue
 ForEach ($ESXHost in $ESXHosts) {
 If (get-vm -Name $vm[0] -server $ESXHost -ea 0)
 Start-VM -VM $vm[0] -Server $ESXHost
 Write-Host "VM $VM Starting on $ESXHost" -ForegroundColor Green
 $i = 0
 $running = "no"
 do {$running = Get-Service -ComputerName $vm[0] -Name $vm[1] -ea 0 | % {$_.status}; sleep 1; $i++; Write-Host "Waiting for $vm[1] service to start on $vm[0]- $i seconds elapsed" -ForegroundColor Yellow}
 while ($running -ne "Running")
 Write-Host "$vm[1] service started on $vm[0]" -ForegroundColor Green
Write-Host "VC should now be up and running" -ForegroundColor Red

Specifying your own MAC address on a VM

February 24, 2011 Leave a comment

So let’s say we have a VM and it has a VMWare assigned Mac Address – but we want to specify a different MAC for the VM (either a previously assigned automatic VM one, or a 3rd Party one)

You have a few options.

1) VMware provide this: – but I have had mixed results and sometimes needed to use MAC addresses that are not VM specific

2) 3rd party tools for changing the MAC in the OS (Windows in this case)

3) Edit the Mac Address on the NIC itself in TCPIP properties for the NIC (though often software can get around this .

4) Have a hack around the VMX files:


But we need to assign our own Mac Address. How do we do it?

Well there are a few posted articles, showing us how to assign VMware approved Macs (00:50:56:XX:XX:XX), but let’s say my software is licensed to a MAC 00:50:56:22:22:44 . and I have converted the host using a P2V . . what now?

Using the edit settings option for a VM only allows Macs within the alloted range. Annoyingly, even the the MAC address is stored in the .vmx file . . changing it here does not always reflect a change, as the minute you make a change to the NIC (e.g. change port group) it will validate the Mac Address and again kick up errors and get all emotional.

Even worse, the database for the VC saves the old MAC, so it may even revert to the VMware assigned MAC that was provisioned when you created the NIC – or will do so each time you make a subsequent change to the vNic.

Well first of all, let’s have a look at the .vmx file (stored at /vmfs/volumes/<datatsore>/<VMname>/<VMname.vmx> (by default at least)

You can access this by using a tool like WinSCP to connect to the ESX host directly.

If we look in this .vmx file, we see the following Ethernet related entries:

ethernet1.present = “true”
ethernet1.virtualDev = “vmxnet3”
ethernet1.networkName = “BACKUP_32_10.0.224.0”
ethernet1.addressType = “vpx”
ethernet1.generatedAddress = “00:50:56:b2:63:25”
ethernet1.pciSlotNumber = “160”
ethernet1.features = “1”
ethernet1.startConnected = “TRUE”

OK, we want to flush the history in the VC and create a new adapter with our own select MAC.

First of all, let’s remove the NIC from the VM (Right click the VM – Edit Settings)

If we now re-open the .vmx file we get the following ethernet entries:

ethernet1.present = “false”

Great, the remaining entries have been flushed.

Now, we’d like to edit the .vmx file and commit changes, so we need to unregister the VM – we can use the VC for this (right-click Vm and select ‘remove from Inventory’

Now let’s re-add the old details to the .vmx file, but

Sspecify these for a new adapter number

Amend the Mac Address

Amend the PCI Slot Number (incremented it by 10 this time – hit and miss though)

ethernet2.present = “true”
ethernet2.virtualDev = “vmxnet3”
ethernet2.networkName = “BACKUP_32_10.0.224.0”
ethernet2.addressType = “STATIC”
ethernet2.address = “00:00:00:12:34:56”
ethernet2.pciSlotNumber = “180”
ethernet2.features = “1”
ethernet2.startConnected = “TRUE”

Note, if the MAC is a non VMware one, you’ll need to specify :

ethernet2.addressType = “STATIC”
ethernet2.address = “00:00:00:12:34:56”

If it is a VMware on that you are recycling:
ethernet1.addressType = “vpx”
ethernet1.generatedAddress = “00:50:56:b2:63:25”

Now simply right click the .vmx file from the Datastore Browser and Viola!

Of course, I under no circumstance endorse or support this, but I have to mention that I have been forced to use this for applications where applications were licensed to Mac addresses and I had migrated to VMware.

Categories: VMWare Tags:

Script of the day – Powercli one liner to get ESX host versions

February 24, 2011 Leave a comment

So I was looking at an ESX estate that is managed by someone else and was hoping to do a few ‘Get-EsxCli’ queries.
Of course Get-EsxCli only works properly from 4u2, so I needed to find a host that was patched up to date.

The easy way? PowerCli of course.

get-view -ViewType HostSystem -Property Name,Config.Product | select Name,{$_.Config.Product.FullName}

Of course, Craig likes it to be a little prettier, so suggested a quick tidy up:

get-view -ViewType HostSystem -Property Name,Config.Product | select Name,@{N=&quot;Build&quot;;E={$_.Config.Product.FullName}} | sort build,name