Taking Control of VM Sprawl (Part 5)

If you would like to read the other parts in this article series please go to:

In my previous article, I explained that the Windows event logs are often the best source of information when it comes to gathering virtual machine history. Unfortunately, it really is impractical to search the event logs manually, except for in some very specific one-off situations. Think about it for a moment. A clustered Hyper-V deployment can consist of over five dozen Hyper-V servers and functions such as live migration or cluster aware updating can move virtual machines among cluster nodes on a frequent basis. This means that the event logs pertaining to a virtual machine probably aren’t going to be located in a single place. The relevant log entries are likely to be scattered across a number of different host servers.

Your only real option for parsing the log entries without the aid of a third-party tool is to delve into PowerShell and create a tool yourself. Fortunately, PowerShell is surprisingly straightforward when it comes to the event logs. It’s relatively easy (relatively being the key term) to use PowerShell to parse multiple event logs, filter the log entries, and then write those log entries to a report. The key to making the process work is to understand how PowerShell interacts with the event logs and how to perform PowerShell filtering and queries. It is going to take me some time to explain the various concepts and techniques that we will need to use, but I would rather take my time and explain what I am doing and why than to simply give you a script to use.

OK, so let’s get started. As I explained in the previous article, most of the event log entries that are related to Hyper-V are stored in the aptly named Hyper-V log. That being the case, the first thing that I need to show you is how to view log entries through PowerShell.

The PowerShell cmdlet that is used for retrieving and displaying event log entries is Get-WinEvent. However, if you enter this cmdlet by itself then PowerShell will spew a seemingly endless stream of “the data is invalid” errors. That being the case, we have to give the Get-WinEvent cmdlet a little bit of guidance by telling it what it is that we want to see. For example, suppose that we want to peer into the application log and see the five most recent entries. We could accomplish this by entering the following command:

Get-WinEvent –LogName Application –MaxEvents 5

You can see what the results of this command look like in Figure A.

Figure A: PowerShell returns the five most recent events from the Application log.

Right about now I’m sure that some of you are wondering what just happened. I mentioned that Hyper-V events show up in the Hyper-V logs, but I just showed you how to look at the Application log. So what gives? Well, take a close look at Figure B. The Hyper-V log isn’t actually a log at all. It’s really a custom view.

Figure B: The Hyper-V log is actually a custom view.

For the benefit of those who might not be familiar with custom views, they are exactly what they sound like. A custom view is just a filtered view of the various events. Windows contains some built-in, server role specific custom views but also makes it possible to create your own custom views. The good news is that these custom views give us a really good starting point for performing advanced PowerShell queries. Of course you could always just create a custom view that gives you the information that you need directly through the Event Viewer. I will show you how to do both.

Let’s start out by taking a peek behind the scenes at what a custom view is really doing and how we can expose a custom view through PowerShell. Begin by right clicking on the Hyper-V custom view and selecting the Filter Current Custom View option from the shortcut menu. When you do, Windows will display the dialog box shown in Figure C.

Figure C: This is the code used to create the custom view.

As you look at the figure above, you will notice that the code shown in the dialog box is XML, not PowerShell. Even so, we can put it to good use. To do so, select the code with your mouse and then press Ctrl+C to copy the text to the clipboard. Next, create a text file and copy the code into your newly created text file. Save your changes and then give the text file an XML extension. For the purposes of this article, I have named my file HyperVLog.xml and saved it into a folder named C:\Scripts.

The XML file doesn’t really do anything by itself, but you can use PowerShell to perform an event log query based on the contents of the XML file. As a matter of fact, you can do this with a single line of code. The command is:

Get-WinEvent –FilterXML([XML](Get-Content C:\Scripts\HyperVLog.xml))

You can see what this command’s output looks like in Figure D. Like the previous command that I showed you, this command produces a seemingly endless list of events, but there are ways of filtering the results.

Figure D: These are the Hyper-V specific results.

OK, so the command that I just showed you results in an excessive number of events being displayed, but remember that even though we are making use of an XML file, the PowerShell portion of things is still using the Get-WinEvent cmdlet. That means that any command that normally works with Get-WinEvent is still viable for use. For instance, we could append –MaxEvents 5 to the end of this command and it would display only the five most recent Hyper-V events.

This technique is obviously useful, but we can do better. We have finally reached the point at which we can display Hyper-V events through PowerShell. Now we need to filter those events so that only those events that are interesting to us are displayed.

The key to being able to do this is knowing the object names that are used by Get-WinEvent. Once we know the object names we can filter based on those object names.

To see the object names enter the following command:

Get-WinEvent –FilterXml ((Get-Content C:\Scripts\HyperVLog.xml)) –MaxEvents 1 | Select-Object *

This command displays the most recent Hyper-V related log entry, as shown in Figure E. More importantly however, the log entry is displayed in its entirety. Every available object is displayed along with the object name. It is these object names that we can use to build some meaningful filters that can help us to track down our VMs.

Figure E: These are the object names that we can work with.


As you can see, it is relatively easy to display Hyper-V related events through PowerShell. As the series progresses I will show you how to filter the results in a meaningful way and then write the filtered results to a report. I will also show you how to make your own custom event filters using the Event Viewer GUI.

If you would like to read the other parts in this article series please go to:

Leave a Comment

Your email address will not be published.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top