Skip to content

Instantly share code, notes, and snippets.

@lalibi
Forked from Nora-Ballard/Set-WindowState.ps1
Last active August 26, 2023 04:25
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save lalibi/3762289efc5805f8cfcf to your computer and use it in GitHub Desktop.
Save lalibi/3762289efc5805f8cfcf to your computer and use it in GitHub Desktop.
Hide, Show, Minimize, Maximize, etc window from Powershell.
function Set-WindowState {
<#
.LINK
https://gist.github.com/Nora-Ballard/11240204
#>
[CmdletBinding(DefaultParameterSetName = 'InputObject')]
param(
[Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true)]
[Object[]] $InputObject,
[Parameter(Position = 1)]
[ValidateSet('FORCEMINIMIZE', 'HIDE', 'MAXIMIZE', 'MINIMIZE', 'RESTORE',
'SHOW', 'SHOWDEFAULT', 'SHOWMAXIMIZED', 'SHOWMINIMIZED',
'SHOWMINNOACTIVE', 'SHOWNA', 'SHOWNOACTIVATE', 'SHOWNORMAL')]
[string] $State = 'SHOW',
[switch] $SuppressErrors = $false,
[switch] $SetForegroundWindow = $false
)
Begin {
$WindowStates = @{
'FORCEMINIMIZE' = 11
'HIDE' = 0
'MAXIMIZE' = 3
'MINIMIZE' = 6
'RESTORE' = 9
'SHOW' = 5
'SHOWDEFAULT' = 10
'SHOWMAXIMIZED' = 3
'SHOWMINIMIZED' = 2
'SHOWMINNOACTIVE' = 7
'SHOWNA' = 8
'SHOWNOACTIVATE' = 4
'SHOWNORMAL' = 1
}
$Win32ShowWindowAsync = Add-Type -MemberDefinition @'
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
'@ -Name "Win32ShowWindowAsync" -Namespace Win32Functions -PassThru
if (!$global:MainWindowHandles) {
$global:MainWindowHandles = @{ }
}
}
Process {
foreach ($process in $InputObject) {
$handle = $process.MainWindowHandle
if ($handle -eq 0 -and $global:MainWindowHandles.ContainsKey($process.Id)) {
$handle = $global:MainWindowHandles[$process.Id]
}
if ($handle -eq 0) {
if (-not $SuppressErrors) {
Write-Error "Main Window handle is '0'"
}
continue
}
$global:MainWindowHandles[$process.Id] = $handle
$Win32ShowWindowAsync::ShowWindowAsync($handle, $WindowStates[$State]) | Out-Null
if ($SetForegroundWindow) {
$Win32ShowWindowAsync::SetForegroundWindow($handle) | Out-Null
}
Write-Verbose ("Set Window State '{1} on '{0}'" -f $MainWindowHandle, $State)
}
}
}
@lalibi
Copy link
Author

lalibi commented Dec 27, 2021

@Duoquadragesimal, yes it's because of the multiple processes, it should work though. You get an error for each process that doesn't have a main window. I added a -SuppressErrors flag, so you can call it like this:

Get-Process spotify | Set-WindowState -State Show -SuppressErrors
Get-Process spotify | Set-WindowState -State Hide -SuppressErrors

@lalibi
Copy link
Author

lalibi commented Dec 27, 2021

@Nagidal added a flag for that too -SetForegroundWindow

Get-Process someprocess| Set-WindowState -State Show -SetForegroundWindow 

@DasGandlaf
Copy link

Hmm. When I do this, the program gets hidden, but it does not show again
Get-Process program | Set-WindowState -State Hide -SuppressErrors
then
Get-Process program | Set-WindowState -State Show -SuppressErrors

Any idea?

@lalibi
Copy link
Author

lalibi commented Jun 14, 2022

Hmm. When I do this, the program gets hidden, but it does not show again Get-Process program | Set-WindowState -State Hide -SuppressErrors then Get-Process program | Set-WindowState -State Show -SuppressErrors

Any idea?

You need to execute those two commands in the same session. Otherwise it won't work, since a "hidden" application doesn't have a MainWindowHandle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment