Getting Browser History. The Easy Way.

Recently @ImADataGuy posed an interesting question on Twitter. Is there an easy way to use Powershell to get the Internet Explorer browsing history for all users on a computer?

If you’ve worked long enough in IT you know that this is a pretty common request by managers for a variety of reasons. But posing it in this way is the start to a pretty deep rabbit hole if you aren’t careful.

It’s one thing to target a single user on a single machine. But how can I make it easy to harvest the browser history for all users for a collection of machines?

The Usual Approach

If you start googling around about this problem, probably one of the first links you’ll find will be an excellent post at Richard Siddaway’s blog.

The code is very good, but there is one problem that makes it unsuitable for our task. That code will only get the browsing history for the user currently executing the code. We want the history for all users.

The problem lies in call to $shell.NameSpace(34). Looking at the MSDN documentation we see that 34 in this call is a reference to an enum that in Windows Server 2008+ type systems just translates to C:\Users\currentUser\AppData\Local\Microsoft\Windows\History. In fact if you change the call to say $shell.NameSpace(“C:\Users\currentUser\AppData\Local\Microsoft\Windows\History”) and insert your user folder name, the script works exactly the same.

You might think you could do something like:

function Get-History 
{
        $users = Get-ChildItem C:\Users
    }

        Foreach($user in $users)
        {
            $user = Split-Path $user -leaf
            try
            {
                $ErrorActionPreference = 'Stop'
                $hist = $shell.NameSpace("C:\Users\$user\AppData\Local\Microsoft\Windows\History") 
            }
            catch
            {
                continue
            }
...

But after trying a number of different approaches, including using PSExec to run as the system user, I was unable to solve the fact that trying to get another users history this way just results in permissions errors. It’s just not going to work.

The Solution

The thing is, Nirsoft has already done 90% of the work for us with its BrowsingHistoryView tool. We just need to turn it into a script that will get us across the finish line.

$execPath = "C:\BrowsingHistoryView.exe"

$computers = 'computer1','computer2','computer3','computer4'

$outPath = "c:\"

$computers | 
    ForEach-Object{ `
        Start-Process $execPath `
            -argumentList "/HistorySource 3", 
                          "/HistorySourceFolder ""\\$_\c$\Users""",
                          "/scomma ""$outpath\history_$_.txt"""
    }

The summary is we give the script the location of the executable, the list of computers, and where we want the files to go. Execute the script and you get a nice tidy collection of csv text files, one per machine, with all of the browser history you need.

I have no idea how NirSoft is getting this information, but the script is short and to the point, and uses a nice, lightweight, standalone executable to get the job done. It also gets all of the history on the machine, not just IE history. Oh yeah, and it’s free.