For a while now, I noticed a weird behavior on my PC where I’d see instances of iexplore.exe and ielowutil.exe running when I’d review my Task Manager’s list of processes. I’ve tried to understand where these were coming from as I haven’t used Internet Explorer in a long time.
What perplexed me even more, is I was able to see the same behavior with a client’s PC that I performed a fresh install of Windows on.
So I was looking for a way to identify when the process(es) were initiated and decided on PowerShell because it is baked into Windows so available.
Quick and Dirty
Initially, I created a simply PS script that performed a loop every second and checked for the specified process. It looked like:
while ($true) {
$ieProcess = Get-Process | Where-Object { $_.Name -eq "iexplore" }
if ($ieProcess) {
Write-Host "Internet Explorer process found!"
# break #Uncomment to only report it once and then stop monitoring
}
Start-Sleep -Seconds 1
}
Obviously, simply change the ‘1’ to any interval (number of seconds) you’d like to use for your sampling.
Furthermore, PowerShell makes it extremely easy to change the loop delay measurement unit between milliseconds, seconds, minutes, … here’s a few examples of how it would be done:
Start-Sleep -Milliseconds 250 #Check every 250 milliseconds
Start-Sleep -Seconds 30 #Check every 30 seconds
Start-Sleep -Minutes 15 #Check every 15 minutes
Start-Sleep -Hours 3 #Check every 3 hours
A Litlle More Pizzazz
Now the above worked, but it simply displays a notification within the PS ISE window and if I was doing something else it was easy to overlook it. As such, I wanted to up my game a little and display a notification that wasn’t so easy to ignore. That’s when I remembered my Toast work for displaying Windows level notifications and thus I created:
while ($true) {
$ieProcess = Get-Process | Where-Object { $_.Name -eq "iexplore" }
if ($ieProcess) {
New-BurntToastNotification -Text "Alert", "Internet Explorer process found!" -Sound 'Alarm'
# break #Uncomment to only report it once and then stop monitoring
}
Start-Sleep -Seconds 1
}
Then, I adjusted the code slightly so it would check for both processes instead of just the one.
while ($true) {
$ieProcesses = Get-Process | Where-Object { $_.Name -in ("iexplore", "ielowutil") }
if ($ieProcesses) {
$processNames = $ieProcesses.Name -join ", "
New-BurntToastNotification -Text "Alert", "Internet Explorer-related processes found: $processNames" -Sound 'Alarm'
# break #Uncomment to only report it once and then stop monitoring
}
Start-Sleep -Seconds 1
}
And that where I left things for my needs.
Log It Instead
Now, if instead of wanting to display some pop-up notification we simply wanted to log the activity to a text file, we could simply do:
$logFile = "C:\Temp\IEProcessLog.txt"
while ($true) {
$ieProcesses = Get-Process | Where-Object { $_.Name -in ("iexplore", "ielowutil") }
if ($ieProcesses) {
$processDetails = $ieProcesses | ForEach-Object { "$($_.Name) (PID: $($_.Id))" }
$processInfo = $processDetails -join ", "
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Alert: Internet Explorer-related processes found: $processInfo"
Add-Content -Path $logFile -Value $logMessage
# break #Uncomment to only report it once and then stop monitoring
}
Start-Sleep -Seconds 1
}
We could easily pursue this further and send a notification e-mail, … but that will be for another day.
Terminate the Identified Process(es)
The last step I examined was automatically terminating the found processes.
Prompt The User For Confirmation
while ($true) {
$ieProcesses = Get-Process | Where-Object { $_.Name -in ("iexplore", "ielowutil") }
if ($ieProcesses) {
$processNames = $ieProcesses.Name -join ", "
New-BurntToastNotification -Text "Alert", "Internet Explorer-related processes found: $processNames" -Sound 'Alarm'
$confirmation = Read-Host "Do you want to terminate these processes? (Y/N)"
if ($confirmation -eq 'Y') {
foreach ($process in $ieProcesses) {
Stop-Process -Id $process.Id -Force
Write-Host "Terminated process: $($process.Name) (ID: $($process.Id))"
}
}
# break #Uncomment to only report it once and then stop monitoring
}
Start-Sleep -Seconds 1
}
Terminate Without User Intervention
while ($true) {
$ieProcesses = Get-Process | Where-Object { $_.Name -in ("iexplore", "ielowutil") }
if ($ieProcesses) {
$processNames = $ieProcesses.Name -join ", "
New-BurntToastNotification -Text "Alert", "Internet Explorer-related processes found: $processNames" -Sound 'Alarm'
foreach ($process in $ieProcesses) {
Stop-Process -Id $process.Id -Force
Write-Host "Terminated process: $($process.Name) (ID: $($process.Id))"
}
# break #Uncomment to only report it once and then stop monitoring
}
Start-Sleep -Seconds 1
}
VBA You Say
Yes, of course, VBA offers us the ability to perform the same type of monitoring. Below would be one possible approach:
Sub ProcessMonitor()
Dim oWMI As Object
Dim oProcesses As Object
Dim oProcess As Object
Dim sProcessNames As String
Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
Do
Set oProcesses = oWMI.ExecQuery("Select * from Win32_Process Where Name='iexplore.exe' OR Name='ielowutil.exe'")
If oProcesses.Count > 0 Then
sProcessNames = ""
For Each oProcess In oProcesses
If sProcessNames <> "" Then sProcessNames = sProcessNames & ", "
sProcessNames = sProcessNames & oProcess.Name
Next oProcess
ShowNotification "Alert", "Internet Explorer-related processes found: " & sProcessNames
Exit Do
End If
Wait 1
Loop
Set oProcess = Nothing
Set oProcesses = Nothing
Set oWMI = Nothing
End Sub
Sub ShowNotification(sTitle As String, sMessage As String)
Dim oWscript As Object
Set oWscript = CreateObject("Wscript.Shell")
oWscript.Popup sMessage, 5, sTitle, vbInformation + vbSystemModal
Set oWscript = Nothing
End Sub
Sub Wait(seconds As Long)
Dim endTime As Date
endTime = DateAdd("s", seconds, Now())
Do While Now() < endTime
DoEvents
Loop
End Sub