PowerShell: Detect if a window or program is foreground or background

Solution 1:

What are you trying to accomplish or why?

You do not say what you have tried, or show it and what errors you are getting. Everything running on your system has a process name and ID and you can say get the start time and whichever is more recent potentially is what is active.

# get all object members of a process
get-process | Select * -First 1 | Get-Member


Name                       : aesm_service
Id                         : 19420
PriorityClass              : Normal
FileVersion                : 2.0.101.44237
HandleCount                : 169
WorkingSet                 : 8597504
PagedMemorySize            : 2203648
PrivateMemorySize          : 2203648
VirtualMemorySize          : 87666688
TotalProcessorTime         : 00:00:00.1250000
SI                         : 0
Handles                    : 169
VM                         : 4382633984
WS                         : 8597504
PM                         : 2203648
NPM                        : 2189736
Path                       : C:\WINDOWS\System32...aesm_service.exe
Company                    : Intel Corporation
CPU                        : 0.125
ProductVersion             : 2.0.101.44237
Description                : Intel® SGX Application Enclave Services Manager
Product                    : Intel® Software Guard Extensions
__NounName                 : Process
BasePriority               : 8
ExitCode                   : 
HasExited                  : False
ExitTime                   : 
Handle                     : 6280
SafeHandle                 : Microsoft.Win32.SafeHandles.SafeProcessHandle
MachineName                : .
MainWindowHandle           : 0
MainWindowTitle            : 
MainModule                 : System.Diagnostics.ProcessModule (aesm_service.exe)
MaxWorkingSet              : 1413120
MinWorkingSet              : 204800
Modules                    : {System.Diagnostics....
NonpagedSystemMemorySize   : 2189736
NonpagedSystemMemorySize64 : 2189736
PagedMemorySize64          : 2203648
PagedSystemMemorySize      : 102120
PagedSystemMemorySize64    : 102120
PeakPagedMemorySize        : 3158016
PeakPagedMemorySize64      : 3158016
PeakWorkingSet             : 9588736
PeakWorkingSet64           : 9588736
PeakVirtualMemorySize      : 99708928
PeakVirtualMemorySize64    : 4394676224
PriorityBoostEnabled       : True
PrivateMemorySize64        : 2203648
PrivilegedProcessorTime    : 00:00:00.0937500
ProcessName                : aesm_service
ProcessorAffinity          : 255
Responding                 : True
SessionId                  : 0
StartInfo                  : System.Diagnostics.ProcessStartInfo
StartTime                  : 9/7/2018 1:16:52 PM
SynchronizingObject        : 
Threads                    : {12776, 19072}
UserProcessorTime          : 00:00:00.0312500
VirtualMemorySize64        : 4382633984
EnableRaisingEvents        : False
StandardInput              : 
StandardOutput             : 
StandardError              : 
WorkingSet64               : 8597504
Site                       : 
Container                  : 


get-process | 
Select StartTime,ProcessName | 
Sort-Object StartTime | 
Format-Table -AutoSize


StartTime           ProcessName                                 
---------           -----------                                 
                    Idle                                        
9/7/2018 1:14:17 PM Secure System                               
9/7/2018 1:14:17 PM Registry 
….

Now, if you say, you are trying to do this on a remote host, that is a whole different issue, as it would not potentially matter what process was the most recent, the user is going to be using whatever they are.

You do not say what you searched for and tried and if it was working for you are not. There are several examples in various places on the web that talks to similar use case.

See these discussions and answers and as you will note, it requires calling into C code and Windows DLL's.

https://stackoverflow.com/questions/9722252/how-can-i-get-the-current-active-window-at-the-time-a-batch-script-is-run

Add-Type @"
  using System;
  using System.Runtime.InteropServices;
  public class Tricks {
    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();
}
"@

$a = [tricks]::GetForegroundWindow()

get-process | ? { $_.mainwindowhandle -eq $a }

https://techibee.com/powershell/get-active-window-on-desktop-using-powershell/2178

[CmdletBinding()]            
Param(            
)            
Add-Type @"
  using System;
  using System.Runtime.InteropServices;
  public class UserWindows {
    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();
}
"@            
try {            
$ActiveHandle = [Windows]::GetForegroundWindow()            
$Process = Get-Process | ? {$_.MainWindowHandle -eq $activeHandle}            
$Process | Select ProcessName, @{Name="AppTitle";Expression= {($_.MainWindowTitle)}}            
} catch {            
 Write-Error "Failed to get active Window details. More Info: $_"            
}

https://social.technet.microsoft.com/Forums/en-US/4d257c80-557a-4625-aad3-f2aac6e9a1bd/get-active-window-info

This will change its output when you select different windows. Make the widows small enough so you can watch the output as you select a new window.

If you have dual monitors then put PS on the second monitor and select windows on the other.

$code = @'
    [DllImport("user32.dll")]
     public static extern IntPtr GetForegroundWindow();
'@
Add-Type $code -Name Utils -Namespace Win32
while(1){
    $hwnd = [Win32.Utils]::GetForegroundWindow()
    Get-Process | 
        Where-Object { $_.mainWindowHandle -eq $hwnd } | 
        Select-Object processName, MainWindowTItle, MainWindowHandle
    sleep -Milliseconds 200
}

Or buy this module ...

https://www.vexasoft.com/pages/get-window
Get-Window

Synopsis
Gets the application windows that are open on the local desktop. 
Syntax
• Get-Window [-Process] [-ShowBackgroundWindows]
• Get-Window [-Title] [-ShowBackgroundWindows]
• Get-Window [-ProcessID] [-ShowBackgroundWindows]

Description
The Get-Window cmdlet gets the application windows that are open on the local desktop.