Taking Control of VM Sprawl (Part 13)

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

So far in this article series, I have spent a lot of time showing you how to pull virtual machine creation and deletion data from the Windows Server event logs. In this article, I want to show you how you can analyze a years’ worth of data so as to spot VM sprawl or general growth trends.

Near the end of my previous article, I explained that I was going to be creating a script that used about 48 different variables. I went on to explain that there were ways of accomplishing the same task using far fewer variables, but that I wanted to avoid getting into any super complex PowerShell code. As I prepare to write this article, I realize that my initial variable estimate was incorrect. This script will actually use 72 variables.

Why so many variables? It’s because we are going to be analyzing a year’s worth of data and I need to have several variables for each months’ worth of data. Rather than just jumping right in and declaring all those variables, I want to show you what I have in mind for each month. Here is a short block of code that I wrote to analyze virtual machine creation and deletion for January 2016:

#January 2016

$JanStartDate = ‘01/01/2016 12:00:00 AM’

$JanEndDate = ‘01/30/2016 11:59:59 PM’

$JanCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$JanStartDate;EndTime=$JanEndDate}

$NumJanCreateEvents = $JanCreateEvents.count

$JanDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$JanStartDate;EndTime=$JanEndDate}

$NumJanDeleteEvents = $JanDeleteEvents.count

Write-Host “In January 2016, there were ” -NoNewLine; Write-Host $NumJanCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumJanDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

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

Image
Figure A: This is the output from the code listed above.

I will be the first to admit that there are less tedious ways of getting the same results. Keep in mind however, that the eventual goal is to be able to analyze a full years’ worth of VM data and to plot that data on a chart. Doing so will be easier in the long run if we use variables.

The variables that I am using are fairly self explanatory. The first two variables that I am declaring are $JanStartDate and $JanEndDate. These variables define the first day of January and the last day of January. I am also declaring variables named $JanCreateEvents and $JanDeleteEvents. These variables retrieve all of the virtual machine creation or deletion events that have occurred between the start date and the end date. Finally, I have declared the variables $NumJanCreateEvents and $NumJanDeleteEvents. These variables track the number of virtual machines created and deleted in January. The remaining lines of code simply display the virtual machine creation and deletion count for the month. If I wanted to display the actual events themselves, I could easily do so by calling the $JanCreateEvents and $JanDeleteEvents variables like this:

#January 2016

$JanStartDate = ‘01/01/2016 12:00:00 AM’

$JanEndDate = ‘01/30/2016 11:59:59 PM’

$JanCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$JanStartDate;EndTime=$JanEndDate}

$NumJanCreateEvents = $JanCreateEvents.count

$JanDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$JanStartDate;EndTime=$JanEndDate}

$NumJanDeleteEvents = $JanDeleteEvents.count

$JanCreateEvents

Write-Host “In January 2016, there were ” -NoNewLine; Write-Host $NumJanCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

$JanDeleteEvents

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumJanDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

You can see the output in Figure B.

Image
Figure B: Here are the actual virtual machine creation and deletion events for January 2016.

As you can see, I’m not doing anything overly complicated in this script. It’s just that a lot of variables are required. This is especially true when you consider that I am going to need similar variables for the other months of the year. So with that said, here is what the full variable declaration script looks like:

#January 2015

 

$JanStartDate = ‘01/01/2016 12:00:00 AM’

$JanEndDate = ‘01/30/2016 11:59:59 PM’

$JanCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$JanStartDate;EndTime=$JanEndDate}

$NumJanCreateEvents = $JanCreateEvents.count

$JanDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$JanStartDate;EndTime=$JanEndDate}

$NumJanDeleteEvents = $JanDeleteEvents.count

Write-Host “In January 2015, there were ” -NoNewLine; Write-Host $NumJanCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumJanDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

 

#February 2015

 

$FebStartDate = ‘02/01/2015 12:00:00 AM’

$FebEndDate = ‘02/28/2015 11:59:59 PM’

$FebCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$FebStartDate;EndTime=$FebEndDate}

$NumFebCreateEvents = $JanCreateEvents.count

$FebDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$FebStartDate;EndTime=$FebEndDate}

$NumFebDeleteEvents = $JanDeleteEvents.count

Write-Host “In February 2015, there were ” -NoNewLine; Write-Host $NumFebCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumFebDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

 

#March 2015

 

$MarStartDate = ‘03/01/2015 12:00:00 AM’

$MarEndDate = ‘03/31/2015 11:59:59 PM’

$MarCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$MarStartDate;EndTime=$MarEndDate}

$NumMarCreateEvents = $MarCreateEvents.count

$MarDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$MarStartDate;EndTime=$MarEndDate}

$NumMarDeleteEvents = $MarDeleteEvents.count

Write-Host “In March 2015, there were ” -NoNewLine; Write-Host $NumMarCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumMarDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

 

#April 2015

 

$AprStartDate = ‘04/01/2015 12:00:00 AM’

$AprEndDate = ‘04/30/2015 11:59:59 PM’

$AprCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$AprStartDate;EndTime=$AprEndDate}

$NumAprCreateEvents = $AprCreateEvents.count

$AprDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$AprStartDate;EndTime=$AprEndDate}

$NumAprDeleteEvents = $AprDeleteEvents.count

Write-Host “In April 2015, there were ” -NoNewLine; Write-Host $NumAprCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumAprDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

 

#May 2015

 

$MayStartDate = ‘05/01/2015 12:00:00 AM’

$MayEndDate = ‘05/31/2015 11:59:59 PM’

$MayCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$MayStartDate;EndTime=$MayEndDate}

$NumMayCreateEvents = $MayCreateEvents.count

$MayDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$MayStartDate;EndTime=$MayEndDate}

$NumMayDeleteEvents = $MayDeleteEvents.count

Write-Host “In May 2015, there were ” -NoNewLine; Write-Host $NumMayCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumMayDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

 

#June 2015

 

$JunStartDate = ‘06/01/2015 12:00:00 AM’

$JunEndDate = ‘06/30/2015 11:59:59 PM’

$JunCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$JunStartDate;EndTime=$JunEndDate}

$NumJunCreateEvents = $JunCreateEvents.count

$JunDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$JunStartDate;EndTime=$JunEndDate}

$NumJunDeleteEvents = $JunDeleteEvents.count

Write-Host “In June 2015, there were ” -NoNewLine; Write-Host $NumJunCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumJunDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

 

#July 2015

 

$JulStartDate = ‘07/01/2015 12:00:00 AM’

$JulEndDate = ‘07/31/2015 11:59:59 PM’

$JulCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$JulStartDate;EndTime=$JulEndDate}

$NumJulCreateEvents = $JulCreateEvents.count

$JulDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$JulStartDate;EndTime=$JulEndDate}

$NumJulDeleteEvents = $JulDeleteEvents.count

Write-Host “In July 2015, there were ” -NoNewLine; Write-Host $NumJulCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumJulDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

 

#August 2015

 

$AugStartDate = ‘08/01/2015 12:00:00 AM’

$AugEndDate = ‘08/31/2015 11:59:59 PM’

$AugCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$AugStartDate;EndTime=$AugEndDate}

$NumAugCreateEvents = $AugCreateEvents.count

$AugDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$AugStartDate;EndTime=$AugEndDate}

$NumAugDeleteEvents = $AugDeleteEvents.count

Write-Host “In August 2015, there were ” -NoNewLine; Write-Host $NumAugCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumAugDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

 

#September 2015

 

$SepStartDate = ‘09/01/2015 12:00:00 AM’

$SepEndDate = ‘09/30/2015 11:59:59 PM’

$SepCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$SepStartDate;EndTime=$SepEndDate}

$NumSepCreateEvents = $SepCreateEvents.count

$SepDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$SepStartDate;EndTime=$SepEndDate}

$NumSepDeleteEvents = $SepDeleteEvents.count

Write-Host “In September 2015, there were ” -NoNewLine; Write-Host $NumSepCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumSepDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

 

#October 2015

 

$OctStartDate = ‘10/01/2015 12:00:00 AM’

$OctEndDate = ‘10/31/2015 11:59:59 PM’

$OctCreateEvents = Get-WinEvent –FilterHashTable
@{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$OctStartDate;EndTime=$OctEndDate}

$NumOctCreateEvents = $OctCreateEvents.count

$OctDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$OctStartDate;EndTime=$OctEndDate}

$NumOctDeleteEvents = $OctDeleteEvents.count

Write-Host “In October 2015, there were ” -NoNewLine; Write-Host $NumOctCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumOctDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

 

#November 2015

 

$NovStartDate = ‘11/01/2015 12:00:00 AM’

$NovEndDate = ‘11/30/2015 11:59:59 PM’

$NovCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$NovStartDate;EndTime=$NovEndDate}

$NumNovCreateEvents = $NovCreateEvents.count

$NovDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$NovStartDate;EndTime=$NovEndDate}

$NumNovDeleteEvents = $NovDeleteEvents.count

Write-Host “In November 2015, there were ” -NoNewLine; Write-Host $NumNovCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumNovDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

 

#December 2015

 

$DecStartDate = ‘12/01/2015 12:00:00 AM’

$DecEndDate = ‘12/31/2015 11:59:59 PM’

$DecCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$DecStartDate;EndTime=$DecEndDate}

$NumDecCreateEvents = $DecCreateEvents.count

$DecDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$DecStartDate;EndTime=$DecEndDate}

$NumDecDeleteEvents = $DecDeleteEvents.count

Write-Host “In December 2015, there were ” -NoNewLine; Write-Host $NumDecCreateEvents -NoNewLine; Write-Host ” New virtual machines created.”

Write-Host “In the same time period, there were ” -NoNewLine; Write-Host $NumDecDeleteEvents -NoNewLine; Write-Host ” virtual machines deleted.”

When I run this script, it does display the number of virtual machines created and deleted on a month by month basis, but there is a problem. Right now, this script works on a single server and I don’t always create and delete virtual machines on every server, every month. That being the case, PowerShell displays the correct output, but it also displays a lot of errors, as shown in Figure C.

Image
Figure C: PowerShell displays a lot of errors.

Thankfully, these errors are easy to get rid of. The easiest way to do so is to append -ErrorAction ‘SilentlyContinue’ to the end of the lines that retrieve data from the event logs. You can see what this looks like in the code excerpt below:

$JanCreateEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13002;StartTime=$JanStartDate;EndTime=$JanEndDate} -ErrorAction ‘SilentlyContinue’

$NumJanCreateEvents = $JanCreateEvents.count

$JanDeleteEvents = Get-WinEvent –FilterHashTable @{LogName=”Microsoft-Windows-Hyper-V-VMMS-Admin”;ID=13003;StartTime=$JanStartDate;EndTime=$JanEndDate}-ErrorAction ‘SilentlyContinue’

As you can see in Figure D, the output is now much more legible.

Image
Figure D: Getting rid of the errors makes the output easier to read.

Conclusion

In the next article in this series, I will show you how to adapt the script to compile data from multiple servers. After that, my plan is to show you how to plot the data on a chart. I may even take it so far as to export all of the data to an HTML based report or an Excel spreadsheet.

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

About The Author

Leave a Comment

Your email address will not be published. Required fields are marked *

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

Scroll to Top