Get Details About VM Task Reconfigure Events – PowerCLI

When troubleshooting an issue, many times I’ll see a “Reconfigure virtual machine” task in the VM Event log in vCenter. However, there is very little information as to what was actually done.

1

Luckily, you can get some of this information from PowerCLI by querying the event manager. Make sure you have PowerCLI loaded and are connected to vCenter to start

I’m going to use a test VM here which I’ve named “test”. I’m also going to specify that I want to look back 30 days into the event manager

$vmObj = Get-VM -Name "test"
$daysBack = 30

Now I just need to setup the filter to look only for events that have to do with the VM I’m specifying as well as the time frame I’m specifying. I’m using the VMware.Vim.EventFilterSpecByEntity to target the VM and the VMware.Vim.EventFilterSpecByTime to target my time frame.

$dateCurrent = Get-Date
$si = get-view ServiceInstance
$em = get-view $si.Content.EventManager
$EventFilterSpec = New-Object VMware.Vim.EventFilterSpec

#only target reconfiguration events
$EventFilterSpec.Type = "VmReconfiguredEvent"

#only target events on the specified VM
$EventFilterSpec.Entity = New-Object VMware.Vim.EventFilterSpecByEntity
$EventFilterSpec.Entity.Entity = ($vmObj | get-view).MoRef

#only query back to the specified number of days
$EventFilterSpec.Time = New-Object VMware.Vim.EventFilterSpecByTime
$EventFilterSpec.Time.BeginTime = $dateCurrent.adddays(-$daysBack)
$EventFilterSpec.Time.EndTime = $dateCurrent

Now to run the query

#run query
$evts = $em.QueryEvents($EventFilterSpec)

You can see that I’ve gotten back the 5 events seen in my screenshot above from vCenter

2

Since I’m troubleshooting, I don’t really care about every little event. Things like updating the notes or annotations on a VM will show up as events here. I’d rather just look at events where devices on the VM have been changed, which you can see is only 4 events

$deviceChangeEvts = $evts | ?{$_.ConfigSpec.DeviceChange}
$deviceChangeEvts.Length

4

Now I just want to look at a couple details about each change operation. So I’m going to select the device type, the change type, and the file operation in case it was a virtual disk event

$deviceChangeEvts | %{$_.ConfigSpec.DeviceChange} | select Operation,FileOperation,Device | ft -AutoSize

1

You may notice in the output above that there are 5 operations even though there are only 4 events I’m looking at. This is because a single event may have multiple operations. In this example, the first time I edited the VM settings I added a hard drive AND a vNIC at the same time, which you can see if I look only at that first event’s details

5

Now maybe I want some details on the hard drive that was added, like how big it is. You can drill into this info as well. Here I’m looping through each device changed and outputting additional information about the devices. You can see the capacity of that added drive was 10485760KB or 10GB

2

A couple things I’ve run into here. Changing the number of cvPU or the amount of vRAM on a VM doesn’t show up as a device change. So if you care about that and filter out anything that’s not a device change you’ll miss it.

Also, if you look at a change event I wasn’t able to find a way to see what the value was before the change. For example, I grew the size of a virtual hard disk from 40GB to 100GB. I can see the change event and the size of the drive as 100GB, but I don’t think it retains the old value of 40GB anywhere. So this isn’t going to help you get back to the original settings. You will need to do more investigation elsewhere for that ability

Scheduled Task – Audit AD Group Membership with PowerShell

There are a number of AD groups which I must provide membership reports on. Let’s say for the sake of this article that it has to be a weekly report. I can easily set this up using the PowerShell module for AD (provided in the RSAT for desktop OS) and my email function Email Array of Objects Using PowerShell. Once that’s working, I just need to add the full script as a scheduled task on a Windows server.

First off, I’m going to setup the information needed to send out the email

$dateSimple = get-date -UFormat "%m/%d/%Y"
$groupName = "Admin Group"
$to = "myemail@mydomain.com"
$from = "DoNotReply-AdminGroupReport@mydomain.net"
$subject = "Group Membership Report for $groupName on $dateSimple"
$smtp = "mySmtpRelay.mydomain.net"

Now let’s grab the group membership information we need and send the email using my function. Couple notes here. First, you may need to include a line to manually import the AD PS module (Import-Module ActiveDirectory) at the begining of the script. Newer versions of PS do this for you automatically. Also, you need to include the code for my email function in the script or import it as a module.

$groupMembers = Get-ADGroupMember $groupName -Recursive | select Name,SamAccountName,DistinguishedName | sort samaccountname
Send-EmailHTML -To $to -From $from -Subject $subject -SMTPServer $smtp -BodyAsArray $groupMembers

Here is an example of the full code: AuditGroupMembership

The resultant email will look something like this:

1

Now I just need to schedule a task to run this script every week on a Windows server that has PowerShell and the AD PS module installed. I’ll copy the full script out to C:\AuditScript.ps1 on the server. Now I just need to setup the task

I’m going to create a new task on one of my Windows Server 2008 R2 boxes. I’m going to name the task and select the option to run it whether the user is logged in or not. You may want to specify a different user ID here as well. Ideally you would use an account where the password doesn’t change. Otherwise you will have to update the stored password periodically.

2

Going to set my trigger here for weekly on Mondays at 5AM

3

Last, I need to set up the action to run my script with PowerShell. It’s probably best to use the full path to the PowerShell executable, but for simplicity I’m not going to do that here. Then I’m going to pass the full path to my script in as an argument

4

When I go to save the task it will ask me to enter the password for the user ID that will run the script and I’m done. Now I don’t have to manually gather this information for the report, nor do I have to email it off to someone manually. PowerShell and the task scheduler will do all that for me each week!