MDT Monitoring Dashboard using PowerBI, Part 1/2

Hello,

Lately I’ve spent more time working on producing project management dashboards than deploying Windows or other Server products. Obviously I started doing that using Excel and Access but soon switched to PowerBI and its flexibility made me want to combine it with my all time favorite product: Microsoft Deployment Toolkit.

For those of you who don’t remember, we used to have a Management Pack for SCOM back in the days of BDD Solution Accelerator. And that Management Pack allowed to track progress of the deployments etc. It was not very simple in my opinion and it required to have a SCOM infrastructure which is not always the case for customers. MDT introduced the monitoring feature a couple years ago (can’t remember exactly when) but it doesn’t come with a graphical dashboard that could be used out of the box. I decided to try building a PowerBI dashboard to graphically represent the data provided by the MDT monitoring component.

To start working on that, I needed data, which meant I needed to deploy a significant amount of computers. this first article describes how I deployed 40+ VMs in less than 24h on my tiny lab (1 desktop computer with 8Gb RAM)

The Task Sequence

That was the easy part, I just created a simple Windows 10 task sequence and needed it to last a random amount of time. Therefore, I added a simple application called “Random Wait”

this application just launches a two-liner VBS script that pauses for a random time between 5 and 20 minutes, here’s the code:

waittime = Int( ( 20 - 5 + 1 ) * Rnd + 5 ) * 1000 * 60
wscript.sleep waittime

I added this application to the task sequence in the State Restore phase

Creating the VMs

Ok, I have the Task Sequence, now I need need to deal with the limited amount of resources in the lab and my laziness. Therefore I need something that will

  1. Create one VM at a time, I didn’t want to create more than one since I was using that desktop for other things.
  2. Create a unique new VM each time, since the MDT monitoring feature would recognize if I used the same VM over and over again and wouldn’t generate new monitoring entries.
  3. Make sure that the VM deploys the task sequence in a fully automated fashion
  4. delete the VM and associated resources when done.

I came up with a solution that uses a powershell script to

  1. Create the VM using an incremental name and share that name in a flat file accessible on the Deployment Share
  2. Make sure the VM boots up using a LiteTouch WinPE ISO
  3. A fully configured CustomSettings.ini with a user exit script that will get the Computer Name from the flat file mentioned in #1
  4. Wait for the deployment to be finished by looking at the MDT monitoring data, once again, using the name generated in #1
  5. Delete the VM resources
  6. repeat

Here’s the Powershell script

$VMNameFile = "D:\DeploymentShare\vmname.txt"
cd DS001:
foreach($digit in 01..40){
    if(Test-Path $VMNameFile) {
        Remove-Item $VMNameFile
    }
    $VMNAME = "E6LABDS$digit"
    $VMNAME | Out-File -FilePath $VMNameFile -Encoding default -Force
    $VM = New-VM -NewVHDPath "D:\Hyper-V\Virtual Hard Disks\$VMNAME\$VMNAME.vhdx" 
        -NewVHDSizeBytes 127GB -BootDevice CD -Generation 1 
        -MemoryStartupBytes 1024MB -Name $VMNAME 
        -Path "D:\Hyper-V\Virtual Machines" -SwitchName External
    Set-VMDvdDrive -VMName $VMNAME 
        -Path D:\DeploymentShare\Boot\LiteTouchPE_x64.iso
    Set-VMMemory $VMNAME -DynamicMemoryEnabled $false
    Start-VM -VMName $VMNAME
    $status = 1
    while($status -eq 1){
         #Check Monitoring Status every 3 minutes
         Start-Sleep -Seconds 180
         $MonitoringData = Get-MDTMonitorData | ? {$_.Name -eq $VMNAME}
         $status = $MonitoringData.DeploymentStatus 
    }
    $VM = Get-VM -Name $VMNAME
    if($VM.State -ne "Off") {
         Stop-VM -Name $VMNAME -TurnOff -Force
    }
    Remove-VM -Name $VMNAME -Force
    Remove-Item "D:\Hyper-V\Virtual Hard Disks\$VMNAME" -Recurse -Force
    Remove-Item "D:\Hyper-V\Virtual Machines\$VMNAME" -Recurse -Force
}

Here’s the CustomSetting.ini

[Settings]
Priority=ReadName, Default

[ReadName]
UserExit=ReadVMName.vbs

[Default]
OSInstall=Y
SkipTaskSequence=YES
TaskSequenceID=1
SkipComputerName=YES
OSDComputerName=#GetName()#
SkipDomainMembership=YES
JoinWorkgroup=WORKGROUP
SkipUserData=YES
UserDataLocation=NONE
SkipCapture=YES
SkipAdminPassword=YES
AdminPassword=P@ssw0rd
SkipAdminAccounts=YES
SkipProductKey=YES
SkipComputerBackup=YES
ComputerBackupLocation=NONE
SkipBitLocker=YES
BDEInstallSuppress=YES
SkipLocaleSelection=YES
SkipTimeZone=YES
KeyboardLocale=en-us
UserLocale=en-us
UILanguage=en-us
TimeZoneName=Eastern Standard Time
SkipApplications=YES
SkipSummary=YES
SkipFinalSummary=YES
FinishAction=SHUTDOWN
EventService=http://MDTSERVER:9800
SLShare=\\MDTSERVER\SLShare$

I highlighted the important settings, the UserExit of course but also the skipfinalsummary and finish action that will make sure that the TS will end automatically and monitoring service will notice that so that our powershell script can finally move on with the next VM.

And finally here’s the user Exit script

Function UserExit(sType, sWhen, sDetail, bSkip) 
 UserExit = Success 
End Function 
Function GetName()
 Dim objFSO, objFile, strContents
 Set objFSO = CreateObject("Scripting.FileSystemObject")
 Set objFile = objFSO.OpenTextFile("\\MDTSERVER\DeploymentShare$\vmname.txt", 1)
 Do While objFile.AtEndOfStream = False
 GetName = objFile.ReadLine
 Loop
End Function

Because the User Exit script is called from the VM, the file has to be accessible on the network.

On the next blog article, I’ll describe how I leveraged the data created


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s