Taking Control of VM Sprawl (Part 7)

by [Published on 8 Sept. 2015 / Last Updated on 8 Sept. 2015]

This article continues the discussion of VM reporting for the sake of sprawl prevention by examining event log entries through PowerShell.

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

In the previous article in this series, I showed you how to pull event log entries from multiple Hyper-V hosts using PowerShell. That’s a great start, but my ultimate goal is to give you a technique that you can use to track virtual machine creations because such information can be useful in preventing virtual machine sprawl.

The step in achieving this goal is to figure out which even log entries are going to be the most beneficial to us. Ultimately, this part is going to be up to you. In all likelihood there are going to be specific types of events that you find useful for tracking virtual machine usage. For the purposes of this article, I am going to focus primarily on virtual machine creation, but please understand that VM creation statistics are not the only useful metrics.

The event number used for virtual machine creation is 13002. Incidentally, 13003 is used for virtual machine deletion. As such, you could even go so far as to use PowerShell to build a report that shows the number of VMs created as opposed to the number of VMs deleted.

So how can you filter the event logs by event type? It’s actually pretty easy to do. If you think back to the previous article, you will recall that I used the following two lines of code to display the five most recent event log entries:

$MyLog = Get-EventLog –Log System –Newest 5

$MyLog | Format-List –Property EventID, EntryType, Message

The trick to filtering the logs by event type is to know which parameters you are allowed to reference.

Let me just say up front that the commands that you will have to use will vary considerably depending on the type of log that you are analyzing. That being the case, I want to show you two different methods for looking for specific event log entries. The reason why I am showing you two different techniques is because everybody has their own ideas about what types of event IDs are useful when tracking down VMs. Some event IDs require using one technique, while other event IDs can use the other. I want to show you both techniques so that you will be able to search for any event ID that you want.

Let’s get started by taking a look at the first line from the block of commands shown above. The first line of code listed above declares a variable. For what I want to show you, we don’t need to declare a variable, so we will just use the Get-EventLog portion of the command, along with the various parameters. There are two other changes that we need to make. Let’s change the command so that it only displays the most recent log entry by changing Newest 5 to Newest 1. The other change that I want to make is to append Select-Object * to the end of the command. That way, we can see an unabridged version of the output. The final command looks like this:

Get-EventLog –Log System –Newest 1 | Select-Object *

You can see the output from this command in Figure A.

Figure A: This is an unabridged event log entry.

As you look at the figure shown above, pay close attention to the column on the left. This column is filled with attribute names. Not only can these attributes be displayed, you can filter the output based on any of these attributes.

Since our goal is to filter the list of event log entries based on the event ID, we will have to use the Where-Object cmdlet. The syntax for the Where-Object cmdlet tends to be a little bit cryptic, but the cmdlet is actually pretty easy to use.

To use the Where-Object cmdlet, there are three things that we have to specify. First, we have to specify the name of the attribute that we want to examine. In this case that attribute is called EventID. Remember though, that EventID is an attribute of the EventLog object. We are using Get-EventLog to retrieve the EventLog object. The way that we tell the Where-Object cmdlet that we are looking at an attribute of an object that is being piped to it is by using $_ to represent the name of the object, and then entering the attribute name after a period. In this case it would look like this: $_.EventID.

The next thing that we have to specify is an operator. In our case, the operator needs to be –EQ because we want to look at the Event ID to see if it is equal to (EQ) a specific number.

The third and final item that we must specify is of course the event ID number that we are looking for. For the sake of demonstration, we will search for Event ID 7036, which is the event ID shown in the figure above.

To see how this works, let’s take a look at the five most recent virtual machine creations. We can do this by entering the following command:

Get-EventLog –Log System –Newest 5 | Where-Object {$_.EventID –EQ 7036}

This command displays the five newest occurrences of event 7036. You can see what this looks like in Figure B.

Figure B: These are the five most recent occurrences of Event 7036.

As you look at the figure above, keep in mind that we can filter the output so as to display exactly the information that we are interested in.

So what if we want to see information related to virtual machine creation? Well, believe it or not, that opens up a whole can of worms. In theory, looking for VM creation events should be as simple as using the same command that I just showed you, but using Event ID 13002. But here is the problem… Event ID 13002 isn’t logged in the System log. It’s logged in the Microsoft-Windows-Hyper-V-Worker\Admin log.

So no problem. Just replace System with Microsoft-Windows-Hyper-V-Worker\Admin, right? Well, not quite. If you do that then you will get a message telling you that the log doesn’t exist. In fact, if you enter Get-EventLog –Log * into PowerShell, you will see that the Get-EventLog command is only able to see seven event logs. You can see what I mean in Figure C.

Figure C: The Get-EventLog command can only see seven event logs.

So what do we do now? If your goal is to parse the Hyper-V related event logs, then you will need to use the Get-WinEvent cmdlet instead of using Get-EventLog. For example, if you wanted to see all of the events in the Microsoft-Windows-Hyper-V-Worker log, you would need to enter the following command:

Get-WinEvent –FilterHashTable @{LogName =”Microsoft-Windows-Hyper-V-Worker*”}

You can see an example of this command in Figure D.

Figure D: This is the contents of the Microsoft-Windows-Hyper-V-Worker log.


In this article, I have explained that there are two different methods for retrieving event log entries through PowerShell, and that the method that you must use depends on which log contains the event ID that you are looking for. In Part 8 I will show you how to use the Get-WinEvent cmdlet to retrieve the information that you are interested in.

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

See Also

The Author — Brien M. Posey

Brien M. Posey avatar

Brien Posey is an MCSE and has won the Microsoft MVP award for the last few years. Brien has written well over 4,000 technical articles and written or contributed material to 27 books.


Featured Links