VMware Cloud Community
Brucky
Contributor
Contributor

Monitoring DRS VMotion via Powershell

Hi all,

Is there any way to monitor whether a VM has been ( or is being ) migrated by DRS via a PowerShell script?

The reason I ask is that I would like to use the Automatic DRS facility within a cluster but have any movements monitored and the VM, its Source and its Destination reported or alerted upon. In this manner I could keep our company Configuration Database up to date and thus keep the pencil pushers off my back.

I appreciate it may be simpler to run a script on a regular basis rather than have it perpetually loop waiting for a migration and thus wasting resources.

I assume that the Recent Task list needs to be searched but if anyone has any brighter ideas I would be very appreciative.

Apologies if this has been asked before and already has an answer only I have Googled this request and have yet to find any pointers.

Thanks

Brucky

0 Kudos
52 Replies
langleyj
Contributor
Contributor

LucD, I would really love to run this script against an ESX cluster or esx host. Any chance I could get you to update the current script Smiley Wink

0 Kudos
LucD
Leadership
Leadership

I'll give it a shot this evening.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
langleyj
Contributor
Contributor

That would be awesome...thanks!

0 Kudos
LucD
Leadership
Leadership

All the vMotion tasks run against a guest not against an ESX server.

Putting an ESX server in the Entity property won't show any vMotion tasks.

I updated the attached script to catch all vMotion tasks (not only the DRS initiated ones).

The results are returned in the array $report.

If you only want to see the vMotion tasks against a specific ESX server you could easily use a Where-Object to filter on specific hostnames in the To or From properties.

Hope it makes you any wiser in analysing the spike you had on your ESX server.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
langleyj
Contributor
Contributor

LucD, this is an awesome script...very helpful! Thanks!!

0 Kudos
mOOky8D
Contributor
Contributor

This is a really fantastic script. We just upgraded our environment to ESX3.5 and are piloting using DRS to manage the environments performance. We have it in "Partially Automated" right now, mainly because one of the features wholly MISSING from VI is the ability to ALERT on DRS actions or recommendations...you have to have the console open to see them!

So, with your script I can now expose the events after they take place, which is great. Can you help me tweak it a little to be able to poll for DRS recommendations, and perhaps fire off an eMail when a recommendation pops in there? My PowerShell knowledge is "just installed ten minutes ago" but I was able to connect to VI and run your script after reviewing it. (I do have a programming background, just have to get comfortable with the syntax)

0 Kudos
LucD
Leadership
Leadership

I don't think the event history is the correct place to monitor for DRS actions.

This can better be done via the recommendation property in the ClusterComputeResource.

The following script shows one way of doing this

$reportName = "C:\DRS-Report.csv"
$report = @()
Get-Cluster | Get-View | %{
  foreach($rec in $_.Recommendation){
    foreach($act in $rec.Action){
      $row = "" | Select Cluster, Time, VM, Source, Destination, Reason
	  $row.Cluster = $_.Name
	  $row.Time = $rec.Time
	  $row.VM = (Get-View -Id $act.Target).Name
	  $row.Source = (Get-View -Id $act.DrsMigration.Source).Name
	  $row.Destination = (Get-View -Id $act.DrsMigration.Destination).Name
	  $row.Reason = $rec.ReasonText
	  $report += $row
	}
  }
}
$report | Export-Csv $reportName -noTypeInformation

# Send report via email
$SmtpClient = New-Object system.net.mail.smtpClient
$MailMessage = New-Object system.net.mail.mailmessage
$SmtpClient.host = <SMTP-servername>
$MailMessage.from = <from-addr>
$MailMessage.To.add(<to-addr>)
$MailMessage.Subject = "DRS action report"
$MailMessage.body = "report attached"
$MailMessage.Attachments.Add($reportName)
$SmtpClient.Send($MailMessage)

You could schedule this script to run at regular intervals.

And perhaps add a test to only send emails when there are actions pending.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
mOOky8D
Contributor
Contributor

Just fantastic. I had seen the ComputeClusterResource API object but didn't know how to expose it from PowerShell. And you replied in just a couple hours too!

You should get paid for this stuff. Smiley Happy

THANK YOU.

I figured out the smtp thing from another post, and so now I have (thanks to mostly your well written code) two scripts that can check for recommendations and also check for migration events.

Now, I'm embarrassed to admit this, but I have two unrelated to DRS/vMotion but related to powershell questions.

I'd like to set both scripts to loop ad infinitum with a delay between iterations, or better, re-trigger automatically if a new event occurs. The later I understand may not be possible since the object collection is static (at least I think it is), but the former shoul dbe achievable. i tried doing it with a "do while" construct and a system delay sleeper, but it ended up breaking the ability to define the collection at the Impl line.

My other embarrassing problem is that I can't seem to concatenate the collected fields into a string that i can eMail as the subject line. I can Write-Host them, but the same syntax, even with +, doesn't seem to work. Any pointers?

0 Kudos
LucD
Leadership
Leadership

Unfortunately there are currently no alarm triggers for DRS recommendations.

That would have been the easiest method.

As a possible alternative you could use the Windows Task Scheduler on the VC.

There are several entries in this community on how to schedule a PS-VITK script this way.

You could schedule the script to run every 'x' minutes.

For you 2nd question, adding all the fields together seems to work for me without a problem.

Do you intend to send an email for each recommendation ?

If you go for an email per recommendation you could do something like this

But watch out, there can be quit a lot of recommendations depending on the size of your environment and servers.

function Send-Email($subject)
{
     $SmtpClient = New-Object system.net.mail.smtpClient
     $MailMessage = New-Object system.net.mail.mailmessage
     $SmtpClient.host = <SMTP-server>
     $MailMessage.from = <From-email-addr>
     $MailMessage.To.add(<To-email-addr>)
     $MailMessage.Subject = $subject
     $SmtpClient.Send($MailMessage)
}

Get-Cluster MyCluster | Get-View | % {
     foreach($rec in $_.Recommendation){
          foreach($act in $rec.Action){
               $subject = $_.Name + " " + $rec.Time + " " + (Get-View -Id $act.Target).Name + " " + `
                         (Get-View -Id $act.DrsMigration.Destination).Name + " " + $rec.ReasonText
               Send-Email $subject 
          }
     }
}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
mOOky8D
Contributor
Contributor

Yeah, I though that doing it in the Task Scheduler would be the easiest workaround. Doing so, however, necessitates I hard-code my username/password to the VIC into the script though, and even though I can secure the file by NTFS, I'm not necessarily comfortable doing that.

0 Kudos
LucD
Leadership
Leadership

You could use the VICredentialStoreItem cmdlets (see ).

At least you won't have to hard-code your user/password info in the script.

And there is at least 1 commercial solution announced that I know of that will provide scheduling scripts combined with a user/password vault.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
mOOky8D
Contributor
Contributor

I see you sleep as little as I do. Smiley Happy

That's a good idea, to use credentials, and I may have found a way to export them mostly-securely: http://halr9000.com/article/531

Thanks!

Oh, and I figured out what was making my string concatenation fail, I had to cast the date into a string first.

0 Kudos
simonadams
Contributor
Contributor

Does anyone know how to restrict this (the report LucD attached to post 15) to a single cluster  ?

0 Kudos
LucD
Leadership
Leadership

Instead of

Get-Cluster

you can do

Get-Cluster -Name MyCluster


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
simonadams
Contributor
Contributor

Thanks LucD - although I'm not sure where to add that as I don't have any get-cluster (attached is the version of the script I'm using)

0 Kudos
LucD
Leadership
Leadership

My mistake, I apparently looked at the wrong post.

The attached script allows you to pass the name of a cluster as a parameter.

In the handling of the events, the script then only takes those events that were raised for a guest inside that cluster.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
simonadams
Contributor
Contributor

You are brilliant as always Smiley Happy

Many thanks

0 Kudos
simonadams
Contributor
Contributor

This doesn't seem to work ?? It doesn't select events/VM's from the cluster and instead the ESX host names are missing ....

I've tried working out what the problem is but its beyond me at this point - all the syntax etc seems correct...

0 Kudos
LucD
Leadership
Leadership

If you change the foreach from

foreach($event in ($ecollection | where{$_.ComputeResource.Name -eq $tgtCluster})){

back to

foreach($event in $ecollection){

do you see all vMotions, including the ones for the cluster you're after ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
simonadams
Contributor
Contributor

Yes that works fine...

The cluster name had spaces and commas in it and I've renamed it which seems to have solved the formatting issues but its still not selecting events from that cluster .... it lists all events

0 Kudos