Rotating Applications on Desktop Using Windows Powershell

Copper Contributor

Hello all;

 

I am largely unfamiliar with the Microsoft Tech Community forum.  I am also very unfamiliar with Windows PowerShell.  Is there a way to use Windows PowerShell to complete the following tasks:

 

1) Rotate between applications on the desktop.

2) If said applications include a browser, switching between all of the tabs in the browser before switching to the next application.

3) Do this indefinitely for a set period of time intervals?

 

I found this code online which is close, but doesn't quite work.  It does not fulfill task number 2 above, and in fact simply "skips" the browsers altogether, while still accepting the time intervals which separate between rotations, (it pulls the PowerShell console back up for the respective time intervals):

 

Code Part 1Code Part 1Code Part 2Code Part 2

Here is the copy-pasted code in full:

 

 Function Show-Window{
    Param(  [parameter(Mandatory=$false, ValuefromPipeline = $false)] [String[]] [ValidateSet( "Hide", "Normal", "ShowMinimized", "Maximize", "ShowNoActivate", "Show", "Minimize", "ShowMinNoActive", "ShowNA", "Restore", "ShowDefault", "ForceMinimize")] $WindowState = "Normal",
            [parameter(Mandatory=$false, ValuefromPipeline = $true)]  [Int32] $ID = $PID
            )
   $signature = @"
[DllImport("user32.dll")] 
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
"@
    $showWindowAsync = Add-Type -memberDefinition $signature -name "Win32ShowWindowAsync" -namespace Win32Functions -passThru
    switch($WindowState){
        "Hide"               {$WinStateInt =  0}
        "Normal"             {$WinStateInt =  1}
        "ShowMinimized"      {$WinStateInt =  2}
        "Maximize"           {$WinStateInt =  3}
        "ShowNoActivate"     {$WinStateInt =  4}
        "Show"               {$WinStateInt =  5}
        "Minimize"           {$WinStateInt =  6}
        "ShowMinNoActive"    {$WinStateInt =  7}
        "ShowNA"             {$WinStateInt =  8}
        "Restore"            {$WinStateInt =  9}
        "ShowDefault"        {$WinStateInt = 10}
        "ForceMinimize"      {$WinStateInt = 11}
        default    {$WinStateInt =  1}
        }
    $showWindowAsync::ShowWindowAsync((Get-Process -id $ID).MainWindowHandle, $WinStateInt)|Out-Null
    
    <#
            .SYNOPSIS 
            Show, Hide Minimize, Maximize, or Restore the Powershell Console or other Window. 
        
            .DESCRIPTION 
           Show, Hide Minimize, Maximize, or Restore the Powershell Console or other Window. 
            
            .PARAMETER WindowState
            [string] The New Window state Mode.
                May be one of the following:
                        
                    Hide                Hides the window and activates another window.
                    Normal              Activates and displays a window. This is the Default. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.
                    ShowMinimized       Activates the window and displays it as a minimized window.
                    Maximize            Maximizes the specified window.
                    ShowNoActivate      Displays a window in its most recent size and position. This value is similar to SW_SHOWNORMAL, except that the window is not activated.
                    Show                Activates the window and displays it in its current size and position. 
                    Minimize            Minimizes the specified window and activates the next top-level window in the Z order.
                    ShowMinNoActive     Displays the window as a minimized window. This value is similar to SW_SHOWMINIMIZED, except the window is not activated.
                    ShowNA              Displays the window in its current size and position. This value is similar to SW_SHOW, except that the window is not activated. 
                    Restore             Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window.
                    ShowDefault         Sets the show state based on the SW_ value specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started the application. 
                    ForceMinimize       Minimizes a window, even if the thread that owns the window is not responding. This flag should only be used when minimizing windows from a different thread.
            .PARAMETER ID
            [Int32] The Process Identifier (PID) of the Target Window. If this paremeter is not specified the Target window defaults to the current Powershell Console Window.
            .INPUTS
            [Int32] $ID You can pipe Process Identifier (PID) of the Target Window.
            .OUTPUTS
            None Show-Window does not return any data.
            .Example
            PS C:\Users\User\Documents> Show-Window -WindowState Minimize
            This will Minimize the Powershell Console Window.
            #>
}

$PBIDesktop_pid=Get-Process PBIDesktop |select -expand id
$msedge_pid=Get-Process msedge |select -first 1 |select -expand id
$chrome_pid=Get-Process chrome |select -first 1 |select -expand id
$wait_time=15
Show-Window -WindowState Minimize -ID $PBIDesktop_pid
Show-Window -WindowState Minimize -ID $msedge_pid
Show-Window -WindowState Minimize -ID $chrome_pid	
While($true)
{
	Show-Window -WindowState Restore -ID $PBIDesktop_pid
	Show-Window -WindowState Minimize -ID $msedge_pid
	Start-Sleep -s $wait_time
	Show-Window -WindowState Restore -ID $msedge_pid
	Show-Window -WindowState Minimize -ID $chrome_pid
	Start-Sleep -s $wait_time
	Show-Window -WindowState Restore -ID $chrome_pid
	Show-Window -WindowState Minimize -ID $PBIDesktop_pid
	Start-Sleep -s $wait_time}

 

 Any ideas from anybody?  I would be very grateful.  This is a way to possibly set up a kiosk without having to set up a kiosk.

 

Thank you;

 

CKellerFSFT

3 Replies

Hi @CKellerFSFT,

To rotate between applications on the desktop and switch tabs in the browser using Windows PowerShell, you can try to use the following code:

 

# Get the PIDs of the applications you want to rotate between
$pbDesktopPID = Get-Process PBIDesktop | Select-Object -ExpandProperty Id
$msedgePID = Get-Process msedge | Select-Object -First 1 -ExpandProperty Id
$chromePID = Get-Process chrome | Select-Object -First 1 -ExpandProperty Id

# Set the wait time between rotations
$waitTime = 15

# Create a function to switch tabs in the browser
function Switch-BrowserTab() {
  $browser = Get-Process -Id $msedgePID -ErrorAction SilentlyContinue
  if ($browser) {
    $browser.SendKeys('^{%TAB}')
  }
}

# Create a function to rotate between applications
function Rotate-Apps() {
  # Restore the current application window
  Show-Window -WindowState Restore -Id $currentAppPID

  # Switch tabs in the browser
  Switch-BrowserTab

  # Wait for the specified time interval
  Start-Sleep -Seconds $waitTime

  # Minimize the current application window
  Show-Window -WindowState Minimize -Id $currentAppPID

  # Set the next application PID
  $nextAppPID = $currentAppPID
  while ($nextAppPID -eq $currentAppPID) {
    $nextAppPID = Get-Random -Maximum $pbDesktopPID -Minimum 1
  }

  # Set the current application PID
  $currentAppPID = $nextAppPID
}

# Start the rotation loop
$currentAppPID = $pbDesktopPID
while ($true) {
  Rotate-Apps
}

 

 

This code should first get the PIDs of the applications you want to rotate between.
Then, it should set the wait time between rotations and create a function to switch tabs in the browser and a function to rotate between applications.
Finally, it should start a rotation loop that will rotate between the applications and switch tabs in the browser.

To run this code, you can save it as a PowerShell script file (e.g. RotateApps.ps1) and then run it from the command line or directly from PowerShell.

This code is just a starting point. 
For example, you may want to add additional applications to the rotation list, or you may want to change the way that the code switches tabs in the browser.

Please click Mark as Best Response & Like if my post helped you to solve your issue.
This will help others to find the correct solution easily. It also closes the item.


If the post was useful in other ways, please consider giving it Like.


Kindest regards,


Leon Pavesic
(LinkedIn)

Hey, @LeonPavesic;

 

Thank you for your time and for putting together that code.  I attempted to test it using PowerShell ISE (x86), and it did not work properly.  I got the following error:

Error 1Error 1

Here is the text for it:

 

Method invocation failed because [System.Diagnostics.Process] does not contain a method named 'SendKeys'.
At line:13 char:5
+ $browser.SendKeys('^{%TAB}')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound

 

What does this error mean?  What would you recommend as the solution to this error?  Thank you very much for your time.

 

Thank you;

 

CKellerFSFT

 

@CKellerFSFT 

 

Hey!

 

Interesting problem :D

The trick to be able to use the '$browser.SendKeys('^{TAB}')' is that you need to make the $browser object like this: '$browser = New-Object -ComObject wscript.shell'

 

With some adjustments to @LeonPavesic's code, this seems to work when i try it. Should probably be adjusted for your needs though :D

# This script will rotate between the specified applications

$AppNames = @( "edge","chrome","code" )
$wait_time=15
$global:counter=0

# Create a function to switch tabs in the browser
function Switch-BrowserTab($browsername) {
  $browser = New-Object -ComObject wscript.shell 
  if ($browser) {
    $browser.SendKeys('^{TAB}')
  }
}

function Activate-Window ($appname) {
  $app = New-Object -ComObject wscript.shell 
  $app.AppActivate($appname)
}

# Create a function to rotate between applications
function Rotate-Apps() {
  if ($global:counter -eq $AppNames.Length) {
    $global:counter=0
  }
  $global:counter
  Activate-Window -appname $AppNames[$global:counter]
  
  # Restore the current application window
  # Switch tabs in the browser
  Switch-BrowserTab -browsername $AppNames[$global:counter]
  $global:counter++
  # Wait for the specified time interval
  Start-Sleep -Seconds $waitTime

  
}

# Start the rotation loop

while ($true) {
  Rotate-Apps
}

 

 

 

-Ole