21

Is there a way to bring a window in front from powershell? I tried this to hide all windows (working) and bring me the powershell back (not working)

[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
$shell = New-Object -ComObject "Shell.Application"
$shell.MinimizeAll()

$a = Get-Process | Where-Object {$_.Name -like "powershell"}
[Microsoft.VisualBasic.Interaction]::AppActivate($a.ID)

Any suggestions?

CJBS
  • 15,147
  • 6
  • 86
  • 135
Yots
  • 1,655
  • 6
  • 17
  • 25
  • works if I don't minimize windows using $shell.MinimizeAll() – ravikanth Feb 14 '11 at 15:38
  • @ravikanth It seems that you are right, if the windows is not minimized than the code is working. So perhaps I need to change my question title. – Yots Feb 14 '11 at 16:22

3 Answers3

25

The PowerShell Community Extensions has a cmdlet to assist with this. You use it like so:

Set-ForegroundWindow (Get-Process PowerShell).MainWindowHandle

or

Set-ForegroundWindow (Get-Process -id $pid).MainWindowHandle

To activate/show a window try this (assuming you're on PowerShell 2.0):

$sig = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32
Stop-Process -Name Notepad -ea 0;Notepad.exe
$hwnd = @(Get-Process Notepad)[0].MainWindowHandle
# Minimize window
[Win32.NativeMethods]::ShowWindowAsync($hwnd, 2)
# Restore window
[Win32.NativeMethods]::ShowWindowAsync($hwnd, 4)
Stop-Process -Name Notepad
E.V.I.L.
  • 2,120
  • 13
  • 14
Keith Hill
  • 194,368
  • 42
  • 353
  • 369
  • 1
    It seems that it is not working with $shell.MinimizeAll() `$shell = New-Object -ComObject "Shell.Application" $shell.MinimizeAll() Set-ForegroundWindow (Get-Process -id $pid).MainWindowHandle` has no effect – Yots Feb 14 '11 at 16:13
  • 2
    Thanks Keith. ShowWindowAsync is the solution for my problem but I have to put a "sleep" between MinimizeAll() and ShowWindowAsync. It seems that MinimizeAll() is a asyc task and if it has a lot of windows to minimize ShowWindowAsync is called to fast. – Yots Feb 14 '11 at 20:57
  • I had issues with ShowWindowAsync, even though the window is maximized and suppossedly activated it may not be the top-most window. As such you may want to use SwitchToThisWindow afterwards. The definition from PInvoke is: [DllImport("user32.dll", SetLastError=true)] public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab) – Ademola Adesibikan Feb 14 '20 at 21:59
  • 1
    According to the docs of the [ShowWindow](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow) function the value 4 means SW_SHOWNOACTIVATE, whereas the value 9 means SW_RESTORE, which is what the OP was looking for. – Marduk Oct 17 '20 at 13:08
5

This is cheating a bit since it's using WScript, but the following one-liner places the window in the foreground without requiring any external cmdlet installation.

In the example below, "notepad" is the process name associated with the window.

Credit goes to the Idera forum posting here by JSanders:

(New-Object -ComObject WScript.Shell).AppActivate((get-process notepad).MainWindowTitle)
Scott Dudley
  • 3,256
  • 1
  • 18
  • 30
0

Wscript one liner is working for me when I replace .MainWindowTitle to .Description at the end. So the line becomes:

(New-Object -ComObject WScript.Shell).AppActivate((get-process notepad).Description)

Yet to find a similar one liner for maximizing it...

Upo001
  • 26
  • 3