HOWTO: Get Webroot Endpoints using Unity REST API and PowerShell

Webroot has recently released a new REST API that allows us as administrators to pull detailed endpoint data programmatically. What this effectively means is that all of the information that is presented to us in the Webroot Global Site Manager can now be extracted directly and integrated into other processes. I very much wanted a script that would be able be able to run on a scheduled task and compare all the systems in Active Directory with those registered in Webroot and then report on those AD systems that either do not have Webroot installed or haven’t checked in for more than a week.

It took some reading and trial and error but I managed to create a PowerShell script that can connect to Webroot and pull all of the details for every endpoint for a given keycode into an object which you can then do whatever you want with. I figured I’d save you the frustration of figuring out how to make this. Of course this code is presented as is. It’s working for me but your mileage may vary.

Here’s how it works:

Continue reading

HOWTO: Check CPU Usage of VMs with VMware Workstation

Do you use VMware Workstation on Windows?  Do you run more than a handful of VMs?  Have you ever had your host CPU pinned by one of the instances of vmware-vmx.exe but the only way you could figure out which VM was the issue was by logging into each one and checking CPU usage there?  I found myself in this situation and figured there had to be a better way.  I realized that each VM runs as its own separate vmware-vmx.exe process.  I further figured out that the .VMX file that includes the name of the running VM is part of the command line arguments used to call it.  Putting this information together, I wrote a simple PowerShell script that is intended to be run on the Windows Host that will show all running VMs and their current CPU usage.  Note that the totals are for each VM, not of the host.  This is why multiple VMs can show 100% usage.

Continue reading

HOWTO: Write Vietnamese on a computer

I have previously discussed how to use a Windows based computer to write in Japanese and Chinese.  The time has come to tackle the next of the Asian languages, Vietnamese.  As before, the same disclaimer applies.  The information below is what I was able to figure out based on information primary from Google and Wikipedia.  Some or perhaps even much of it may be incomplete but it does appear to at least be logically consistent.  At first I thought typing in Vietnamese would be considerably easier since the language at first blush appeared to use the Roman alphabet, just as English does.  Therefore, I expected it to be as simple as “Select the Vietnamese keyboard and start typing”.  As I started researching however, I found this was not the case at all.

There are a couple of important things to be aware of when trying to write Vietnamese on an English keyboard.  Let’s assume you’ve used the “Language” Control panel applet and added the “Vietnamese” language already.  Once installed, you press the “Preview” button to see what the keyboard looks like this:


The first thing that will probably jump out at you is that all of the numeric digits on the keyboard have been replaced with special characters along with the open and closed square brackets, dash and equals keys.  Why is that?  To understand this, we’ll have to look at how the Vietnamese alphabet is constructed.

Continue reading

Deploy Office 365 and HA ADFS From Scratch

Are you interested in Office 365 and ADFS but are intimidated by it and not sure where to begin?  If that’s the case, you’ve come to the right place.  I have been studying to write my 70-346 (Managing Office 365 Identities Exam) and realized that I was still really weak on ADFS and how all the pieces work together.  I decided I wanted to build a fully fleshed out ADFS environment in my own lab complete with a new Office 365 tenant and ADFS configured in high availability with the recommended 4 servers (redundant federation and redundant proxy servers). So that’s what I did and I’m going to walk you through the entire setup, starting from the very beginning.


All the links download are free for testing purposes. To follow along with this HOWTO you will need:

Description URL/Notes
Registered Domain Including access to modify public DNS records – I used
Purchased SSL certificate that you have saved as a .PFX file I recommend a wildcard certificate.  I used one from
Office 365 for Business Trial Setup
Access to a phone Capable of receiving text messages or phone calls
PFSense Firewall
Windows 2012 R2 180 Day Trial
Windows 10 Enterprise 90 Day Trial
Exchange 2016
Microsoft Unified Communications Managed API
Office 2016 Administrative Templates
Microsoft Online Services Sign-In Assistant
Azure AD Module

Credit where credit is due.  This HOWTO is based on basic ADFS deployment documentation found here: :

Continue reading

Windows 10 Bitlocker Recovery Gotcha

I recently upgraded my laptop from the now four year old Lenovo W530 to a shiny new Lenovo P50 complete with a Xeon 2.8Ghz CPU, 64GB of RAM and an NVME M.2 boot drive.  Not only did I upgrade the hardware but I also switched from Windows 8.1 to Windows 10.  So far so good.

Being that I’ve always owned laptops, I always try to take precautions against data loss through theft via full disk encryption.  With the release of BitLocker, this has been an remarkably seamless security improvement and I’ve used Bitlocker transparently for years.  So far so good.

Continue reading

HOWTO: Convert binary to human readable text

This is a quick fun little HOWTO.  The was an article on CollegeHumor today that looked like this:


01010100 01101000 01100101 00100000 01110010 01101111 01100010 01101111 01110100 01110011 00100000 01100001 01110010 01100101 00100000 01100001 01101101 01101111 01101110 01100111 00100000 01110101 01110011 00100000 01100001 01101110 01100100 00100000 01110111 01100101 00100000 01100001 01110010 01100101 00100000 01100001 01101100 01101100 00100000 01101001 01101110 00100000 01100100 01100001 01101110 01100111 01100101 01110010 00101110 00100000 01001000 01100101 01101100 01110000 00100000 01110101 01110011 00101100 00100000 01000111 01101111 01100100 00101110

I was of course curious what the message above actually said so I wondered how quickly I could figure that out with PowerShell.  The answer?  Pretty gosh darn quick.

((gc c:\temp\binary.txt) -split " " | % { [char]([convert]::ToInt32("$_",2)) }) -join ""

Continue reading

HOWTO: Determine what wmiprvse.exe is actually doing (aka Troubleshoot WMI)

This HOWTO came about after watching the excellent video series on using Process Explorer available here:

Case of the Unexplained: Troubleshooting with Mark Russinovich

In this video, he talks about a case where wmiprvse.exe was causing Bluray video playback to stutter. 
If you have worked in IT for any length of time, you’ve probably seen this executable come up during your troubleshooting.  It’s the "WMI provider host".
I’ve known that for a while but what happens inside this process has always been a black box for me… until now that is.

If you ever run into an issue where wmiprvse.exe is misbehaving, follow these simple troubleshooting steps:

1) Launch Event Viewer, go to View and enable Show Analytic and Debug Logs

Continue reading

HOWTO: Real world use case for Convert-FromString

This HOWTO covers a real world example of how to use Convert-FromString which was introduced in PowerShell 5.  As a reminder, this is the powerful new cmdlet that allows you to parse any kind of text data and convert the resulting data into structured PowerShell objects by defining “templates” for how the data is laid out and what information you want to extract.

The largest mall in my city includes literally hundreds of stores. I needed to shop for a particular kind of thing and wanted to know what stores I might want to check out.  I started by visiting the website for the mall.  This ended up giving me output that looked like this:


It’s not bad certainly but I would like to apply some filters to the dataset.  Now in reality, I could have certainly figured out what I wanted from this website but I realized this would be a great opportunity to see if I could make the ConvertFrom-String and FlashExtract do something useful.  Could I make a PowerShell object out of this data?

The first thing I did was download the webpage in PowerShell using the Invoke-WebRequest cmdlet.  Powershell includes a “parseddata” object that tries to break down any webpage into its component parts and return the results as nested objects.  I looked at the output and discovered that all of the data I was interested in was stored in parseddata.documentElement.outertext.  This gave me the following results:


Continue reading

HOWTO: Convert Complex Text Data into PowerShell Objects

PowerShell 5.0 introduces a wonderful new cmdlet called ConvertFrom-String.  Don’t let the simple name deceive you though.  There is some exceptionally complex math running behind the scenes here to do some truly wonderful things.
In fact, the code that gets executed inside this function is based upon the "FlashExtract" project completed by Microsoft Research.  How much math? Well here is a portion of the algorithm that was published in their whitepaper.


The idea here is to give us as administrators the ability to take some existing complex text data, intelligently analyze it and convert it into native PowerShell objects. 
Technically we can already do this today using regular expressions.  But coming up with the right combination of letters and characters to produce the intended results is no easy task.  At least until now.
The idea here is that instead of trying to micro manage exactly character-by-character how you want to extract the data to get to the content you want, you instead simply ‘tell’ PowerShell want you want.
Specifically, you pass the ConvertFrom-String function a marked up template of the data that indicates which data is important.

It’s hard to understand in writing but will make a lot more sense once you see it in action.  This is also when the "ah ha" moment comes and you realize the power this new cmdlet offers.

For our example, we’re going to take a look at the c:\windows\windowsupdate.log.  This is a plain text log file that contains several columns:


Continue reading

HOWTO: Monitor a webpage and alert on change

This is admittedly kind of a silly HOWTO but does contain a number of very useful concepts.

I am eagerly awaiting the Lenovo Thinkpad P50 laptop.  The official webpage for this laptop went live today but for pricing it simply says “Coming Soon”.
Rather than refresh the page constantly, I figured I’d let PowerShell do the work for me.  Specifically:

1) Connect to the website every hour and check if the “Coming Soon” pricing has changed
2) If the text is still present, do nothing
3) If the the “Coming Soon” text has been removed (presumably replaced by actual pricing) do the following:
4) Create a pop up tooltip in the Windows System tray alerting me that the pricing is now available
5) In case I miss the popup, email me as well.

To accomplish this, take the code below, save it to a file and create a scheduled task to run it every hour.  That’s it.  You will now be notified as soon as the laptop is available for purchase!

Note: You may be wondering why I didn’t use the built-in Invoke-WebRequest cmdlet.  Normally I would but for Lenovo’s website specifically, I would consistently get “403 – Forbidden” errors.
I tried adding custom user agents and even went as far as using Fiddler to figure out what a good header looks like and then copied that.
The issue appears to be that the Lenovo website is compressed with Gzip and encoded in such a way that (I couldn’t figure out anyway) how to make it work with the built in tool.


Function Show-BalloonTip($Text)
# Set notification title and message.
$Title = "Lenovo P50 Countdown"
$Message = $Text

# How long to display the notification in milliseconds.
# Must be between 10 and 30 seconds.
$Timeout = 30000

# Balloon icon type: None, Info, Warning or Error.
$BalloonIcon = "Info"

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$NotifyIcon = New-Object System.Windows.Forms.NotifyIcon
$HostProcessPath = Get-Process -id $pid | Select-Object -ExpandProperty Path
$NotifyIcon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($HostProcessPath)
$NotifyIcon.BalloonTipTitle = $Title
$NotifyIcon.BalloonTipText = $Message
$NotifyIcon.BalloonTipIcon = $BalloonIcon
$NotifyIcon.Visible = $True

Start-sleep -Seconds 10

Function Get-Webpage($URL)
$request = New-Object System.Net.WebClient

# Custom headers required to access as the page is compressed with gzip and otherwise returns 403 Forbidden errors
$request.headers.add("User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko")
$request.headers.add("Accept-Language: en-US")
$request.headers.add("X-Requested-With: XMLHttpRequest")
$request.headers.add("Accept: text/html, application/xhtml+xml, */*")
$request.UseDefaultCredentials = $true
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
$request.Proxy.Credentials = $request.Credentials

$RawHTML = $request.DownloadString($URL)

# The text comes in one long string. Seperate out each line on each carriage return
$RawHTML -split "`r`n"

$HTML = Get-Webpage ""

# Currently Coming Soon appears 3 times in the code. Once pricing appears this should no longer be present so display the message
if (($HTML | select-string "coming soon" | measure-object).count -ne 3)
Show-BalloonTip "The Thinkpad P50 is ready for purchase!"

$smtpServer = ""
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = ""
$msg.IsBodyHTML = $false
$msg.Subject = "Lenovo P50 Pricing is a go!"
$msg.Body = "The Lenovo P50 website is no longer saying coming soon and presumably has pricing now!"