Archive for category VMware

Powershell / Powercli script to report on VMs and their VMDKs

Here is a report I put together to quickly view all VMs their VMDKs and the Datastores those VMDKs are sitting on. This is not meant to be a report to view total storage or free space on either the VMs or their Datastores, nor are we looking for orphaned vmdk files. Although I may add those features to this report later on.

Update 3/13/2014: Script now reports on Size and how the data is presented has been improved.

Issue: Review VMDK files for any that don’t have the same name as the VM names in VCenter.

Purpose: Scan and report on VMware VM’s VMDKs and what Datastores they are tied to.

Side Notes:

  • You must have Powercli installed on the machine this report runs off of.
  • The admin account used must have enough permissions to run the given commands.
  • It is possible to have two VMs in vCenter with the same name. So in the report you may see a single server when in fact it is two separate servers.
  • If that happens you’ll see a single instance of that VM’s name with more than the expected number of disk.
#=====================================================================================================#
# Author: Robert Stacks
# Date: 7/18/2012
# Updated: 3/13/2012
# Verson: 1.1
#
# Purpose: 
# Scan and report on Datastores, and related VM's VMDK visible to vCenter
# 
# Updates:
# 3/12/2012
# - Added a column to show the current host ESXi server, Split Folder from VMDK info, and also added size
# - Fixed some spelling and updated comments
# - Fixed some flow logic and adjusted table row color, table padding, and sizing.
#=====================================================================================================#

#Add Snapins
Add-PSSnapin VMware.VimAutomation.Core

#===========================#
#User Adjustable Variables  #
#===========================#

#Vcenter Logon Info
$ESXserver = "vcenterserver.domain.com"
$ESXuser = "username"
$ESXpassword = "password"

#Mail Server Variables
$SMTPserver = "mail.domain.com"
$from = "VMwareReporter@domain.com"
$to = "sysadmins@domain.com"

#===========================#
#Main Script                #
#===========================#

#Determine if already connected to VCenter and if not connect
if ( $DefaultVIServers.Length -lt 1 )
{
  Connect-VIServer -Server $ESXserver -User $ESXuser -Password $ESXpassword -WarningAction SilentlyContinue | Out-Null
}

# Format html report
$htmlReport = @"
<style type='text/css'>
.heading {
 	color:#0B1ABF;
	font-size:14.0pt;
	font-weight:700;
	font-family:Verdana, sans-serif;
	text-align:left;
	vertical-align:middle;
	height:20.0pt;
	width:416pt;
}
.colnames {
 	color:white;
	font-size:11.0pt;
	font-weight:700;
	font-family:Tahoma, sans-serif;
	text-align:center;
	vertical-align:middle;
	border:.5pt solid windowtext;
	background:#730000;
}
.lblueback {
	color:windowtext;
	font-size:10.0pt;
	font-family:Arial;
	text-align:left;
	vertical-align:middle;
	border:.5pt solid windowtext;
	background:#B8CCE4;
}
.greyback {
	color:windowtext;
	font-size:10.0pt;
	font-family:Arial;
	text-align:left;
	vertical-align:middle;
	border:.5pt solid windowtext;
    #background:#D8D8D8;
}

</style>
<table style='border-collapse:collapse;table-layout:auto;width:auto;padding:5px'>
 <tr style='height:15.0pt'>
   <th colspan=6 height=40 width=auto class="heading">
	<center> VM Datastore Report </center></th>
 </tr>
 <tr>
  <th class="colnames">VM Name</th>
  <th class="colnames">Host</th>
  <th class="colnames">DataStore</th>
  <th class="colnames">Folder</th>
  <th class="colnames">FileName</th>
  <th class="colnames">Size/GB</th>
 </tr>
"@

#get a list of VMs
$vmlist = Get-VM -Server $ESXserver | Sort

#counter to manage alternating row color
$colorcounter = 0

#Master part of the script, loops through each VM and creates table with data
ForEach ($vm in $vmlist)
{	
  #If loop to determine color of Rows related to given VM
  if ($colorcounter%2 -eq 0)
	{
		$tablecell = @"
		<td class='lblueback'>
"@
}
  else 
	{ 
		$tablecell = @"
		<td class='greyback'>
"@
}
  
  # Grab VMDK information and the Datastores tied to them.
  $vmdisk = Get-VM $vm | Get-harddisk
  
  # Split out disks where a VM has more than a single disk, also split out the name of the Datastore
  # from the name/path of the vmdk file, then split the Folder Name from the VMDK name.
  $vmdiskDatastore=($vmdisk | %{$_.Filename.Split('[]')[1]})
  $vmdiskfilename=($vmdisk | %{$_.Filename.Split('[]')[2]})
  $vmdiskFolder=($vmdiskfilename | %{$_.Split('/')[0]})
  $vmdiskVMDK=($vmdiskfilename | %{$_.Split('/')[1]})
  $vmdisksize=($vmdisk | %{$_.CapacityKB})
  
  # determine the length of the array so we know if there was more than one hard drive for a given VM.
  $count = $vmdiskfilename.count - 1
  
  # Begin building the html report, inserting the name of the VM in the 1st Column and Host Name into the 2nd 
  $htmlReport = $htmlReport + 
  "<tr>" + $tablecell + $vm.Name + "</td>" +
  $tablecell + $vm.host.Name + "</td>"
  
  # Based on the number of hard drives in the count value the report is generated in one of two ways
  if($count -le 0)
  {
  	# There is only one hard drive so the values will not be in an array we just need to build the table row with data
  	$htmlReport = $htmlReport + 
	$tablecell + $vmdiskDatastore + "</td>" + 
    $tablecell + $vmdiskFolder + "</td>" +
	$tablecell + $vmdiskVMDK + "</td>" +
	$tablecell + $vmdisksize / 1MB + "</tr>"
  }
  else
  {
  	# There is more than one hard drive, because of table formatting we handle the 1st row different from the 2nd row.  Data is in an array.
  	$htmlReport = $htmlReport +
    $tablecell + $vmdiskDatastore[0] + "</td>" + 
    $tablecell + $vmdiskFolder[0] + "</td>" +
	$tablecell + $vmdiskVMDK[0] + "</td>" +
	$tablecell + $vmdisksize[0] / 1MB + "</tr>"
  
  # There is more than one hard drive so we will loop through the array and and place them in the report
 	$x=1
    While($x -le $count)
	{
    	$htmlReport = $htmlReport +
     	"<tr>" + $tablecell + "" + "</td>" + 
		$tablecell + "" + "</td>" +
    	$tablecell + $vmdiskDatastore[$x] + "</td>" + 
    	$tablecell + $vmdiskFolder[$x] + "</td>" +
		$tablecell + $vmdiskVMDK[$x] + "</td>" +
		$tablecell + $vmdisksize[$x] / 1MB + "</tr>"
		$x= $x+1
  	}
   }
   # value used in conjunction with Foreach and if loop to rotate color in table
   $colorcounter = $colorcounter + 1
 }
 
 # We are done gathering data from vCenter so we disconnect
 Disconnect-VIServer -Server $ESXserver -Force:$true -Confirm:$false

# Send email
$subject = "VMware VM Datastore Report"
$emailbody = $htmlReport
$mailer = New-Object Net.Mail.SMTPclient($SMTPserver)
$msg = New-Object Net.Mail.MailMessage($from, $to, $subject, $emailbody)
$msg.IsBodyHTML = $true
$mailer.send($msg)

Example of output:
datastorereportexample

11 Comments

Monitor VMware for SnapShots

Here is something I recently put together to monitor VMware Snapshots. 

The issue: The backup solution creates snapshots daily but if something goes wrong it doesn’t clean up a snap.

The solution: Using this simple powercli script, we monitor and check to see if any VM’s have snapshots over 1 day old. If so we highlight them in the report, other snapshots are simply in the report.

Side Note: Not sure if I’m happy with the colors I used in the report but it does grab ones attention.


#=====================================================================================================#
# Author: Robert Stacks
# URL: RandomTechMinutia.wordpress.com
# Date: 6/18/2012
# Updated: 7/2/2012
# Version: 0.4
#
# Purpose:
# Scan and report on Snapshots that are older than 1 day in VCenter
#=====================================================================================================#

#Add Snapins
Add-PSSnapin VMware.VimAutomation.Core

#Get todays Date
$date = Get-Date

#===========================#
#User Adjustable Variables  #
#===========================#

#Name of your Company for Report Title
$CompanyName="CompanyName"

#Vcenter Logon Info
$ESXserver = "vcenterserver.yourdomain.com"
$ESXuser = "vmwareuser"
$ESXpassword = "password"

#Adjust report +/- age of Snap Shots in days
$TimeinDays = 1

#Mail Server Variables
$SMTPserver = "mail.yourdomain.com"
$from = "VMwareReporter@yourdomain.com"
$to = "admin@yourdomain.com"

#===========================#
#Main Script                #
#===========================#

#Determine if already connected to VCenter and if not connect
if ( $DefaultVIServers.Length -lt 1 )
{
Connect-VIServer -Server $ESXserver -User $ESXuser -Password $ESXpassword -WarningAction SilentlyContinue | Out-Null
}

# Format html report
$htmlReport = @"
<style type='text/css'>
.heading {
color:#0B1ABF;
font-size:14.0pt;
font-weight:700;
font-family:Verdana, sans-serif;
text-align:left;
vertical-align:middle;
height:20.0pt;
width:416pt;
}
.colnames {
color:white;
font-size:10.0pt;
font-weight:700;
font-family:Tahoma, sans-serif;
text-align:center;
vertical-align:middle;
border:.5pt solid windowtext;
background:#730000;
}
.text {
color:windowtext;
font-size:10.0pt;
font-family:Arial;
text-align:center;
vertical-align:middle;
border:.5pt solid windowtext;
background:#EAEAEA;
}
.textlate {
color:#730000;
font-size:10.0pt;
font-family:Arial;
font-weight:bold;
text-align:center;
vertical-align:middle;
border:.5pt solid windowtext;
background:#FFFF00;
}
</style>
<table border=0 cellpadding=.5 cellspacing=0 width=556
style='border-collapse:collapse;table-layout:auto;width:600pt'>
<tr style='height:15.0pt'>
<th colspan=6 height=40 width=555>
<center>- $CompanyName - </center></th>
</tr>
<th colspan=6 height=40 width=555>
<center> vSphere Snapshots Daily Report </center></th>
</tr>
<tr>
<th>Name</th>
<th>Note</th>
<th>Size (MB)</th>
<th>VM</th>
<th>VM State</th>
<th>Date Created</th>
</tr>
"@

$vmlist = Get-VM -Server $ESXserver
$snapshotCount = 0

ForEach ($vm in $vmlist)
{
# List snaphosts
$snapshots = Get-Snapshot -VM (Get-VM -Name $vm.Name) -WarningAction SilentlyContinue

if ($snapshots -ne $null)
{

ForEach ($snapshot in $snapshots)
{
if( $snapshot -ne $null)
{
$snapshotCount = $snapshotCount + 1

if ($snapshot.created -lt (Get-Date).AddDays(-$TimeinDays))
{
$htmlReport = $htmlReport +
"<tr><td class='textlate'>" + $snapshot.Name + "</td>" +
"<td class='textlate'>" + "Snapshot Over 24 Hours Old" + "</td>" +
"<td class='textlate'>" + $snapshot.SizeMB + "</td>" +
"<td class='textlate'>"+ $vm.Name + "</td>" +
"<td class='textlate'>" + $vm.PowerState + "</td>" +
"<td class='textlate'>" + $snapshot.Created + "</td></tr>"
}
else
{
$htmlReport = $htmlReport +
"<tr><td class='text'>" + $snapshot.Name + "</td>" +
"<td class='text'>" + "Snapshot Less Than 24 Hours Old" + "</td>" +
"<td class='text'>" + $snapshot.SizeMB + "</td>" +
"<td class='text'>"+ $vm.Name + "</td>" +
"<td class='text'>" + $vm.PowerState + "</td>" +
"<td class='text'>" + $snapshot.Created + "</td></tr>"
}
}
}
}
}

$htmlReport = $htmlReport + "</table>"

Disconnect-VIServer -Server $ESXserver -Force:$true -Confirm:$false

# Send email
$subject = "vSphere Snapshots Daily Report: " + $snapshotCount + " snapshots"
$emailbody = "No snapshot was found."
if( $snapshotCount -gt 0 )
{
$emailbody = $htmlReport
}
$mailer = New-Object Net.Mail.SMTPclient($SMTPserver)
$msg = New-Object Net.Mail.MailMessage($from, $to, $subject, $emailbody)
$msg.IsBodyHTML = $true
$mailer.send($msg)

Here is what it will look like in a email.

,

2 Comments

Citrix XenDesktop 5 using Machine Creation Services (MCS) and Microsoft KMS Services

Hey all, happy new year!   Been working on our XenDesktop deployment over the holidays and ran into a snafu when working with Microsoft Activation keys.  As any of you know when working with Microsoft products you have the option to use a MAK key or a KMS key with a given product.  However their is a limit on how many times you can use a MAK key and in large deployments this may not be the best solution. When deploying virtual desktops the best solution is to setup a Microsoft KMS host and use KMS client keys so that each clone will have a validate Windows License, this also prevents you from using up your MAK keys when you redeploy your clones during updates/patches/etc.

When we started down the path of using Citrix on top of VMware using MCS we didn’t realize at the time there was a catch using KMS keys.  Both Citrix and VMware when you deploy their solutions have options to reset the SID of the cloned machine however when you mix the two and use MCS it becomes a little more of a challenge.  I found a interesting statement of support from Citrix here: http://support.citrix.com/article/CTX128580

MCS does not support or work with KMS based Microsoft Windows 7 activation by default, however the following workaround has been provided and will be supported by Citrix Support should an issue arise.  So the process to address this while cover in the link in short is to create your image, create a snap shot, run slmgr /rearm from command line on the image, take a 2nd snap shot and label it rearm and then build your Machine Catalog off that.

After doing so, each clone as it boots up for the first time will have a unique sid to register with your KMS key server.

The down side is that anytime you want to update the image you have to perform the above steps all over again before updating the catalog when the updates be they windows updates, virus updates, putting a new icon on the desktop etc.

The whole process is much less of a issue if you have 25 other devices already registered with your KMS host as that is the minimal requirement to active Windows 7 using a KMS host prior to it actually allowing the 1st activation to be successful.  If this is the case then you need not bother with the above as the clones will still activate with the KMS host even if they have the same SID its the first 25 that is a gotcha.

, ,

Leave a comment