How to avoid powershell going into wait mode automatically - powershell

I have a powershell script which automates the upload of a report. After the file upload dialog box opens in Internet Explorer, My code tries to get it's id and then send keys and send the file address and sendkeys enter. But unfortunately as soon as the file upload dialog box pops up my script doesn't proceed further and waits there. If I hit close (in the file upload dialog) then the script continues. Is there any way by which I can tell powershell to not wait for anything?
Here's my code :-
$dummy = get-process iexplore | where {$_.mainWindowTitle -eq "ArkAngelWeb - Hitachi Systems Security Inc. - Internet Explorer"} | select -expand id
Sleep 1
$temp = $ie.Document.documentElement.getElementsByClassName("v-button-caption") | Where-Object {$_.innerHTML -eq "Select file"}
$temp.click()
Sleep 2
$swshell=New-Object -ComObject wscript.shell
$fileUploadDialog = get-process iexplore | where {$_.mainWindowTitle -eq "ArkAngelWeb - Hitachi Systems Security Inc. - Internet Explorer" -and $_.Id -ne
$dummy.Id} | select -expand id
$swshell.AppActivate($fileUploadDialog.Id)
$swshell.SendKeys("H");
$swshell.SendKeys("{TAB}")
$swshell.SendKeys("C:\Users\ratns1\Desktop\TEST_FILE.txt")
$swshell.SendKeys("~")
Thanks

This is the issue with SendKeys, timing, UI controls, etc.
You are popping a model dialog box, and that is what's causing the wait.
By design, your script will not continue until you dismiss it. This is the design for dialogs.
PoSH notwithstanding, it is your use case that is the catch 22, not PoSH itself.
Take a look at the Wasp module to take the load off all the sendkey and Window lookup stuff off your plate.
Occasionally, the only way of automating processes is to send
keystrokes or mouse clicks to UI elements. A good and free PowerShell
extension is called "WASP" and is available here:
http://wasp.codeplex.com/
Once you install the module (do not forget to unblock the ZIP file
before you unpack it, via right-click, Properties, Unblock), the WASP
module provides the following cmdlets:
Get-WindowPosition
Remove-Window
Select-ChildWindow
Select-Control
Select-Window
Send-Click
Send-Keys
Set-WindowsActive
Set-WindwowPosition
Here is a simple automation example using the Windows calculator:
Import-Module WASP
# launch Calculator
$process = Start-Process -FilePath calc -PassThru
$id = $process.Id
Start-Sleep -Seconds 2
$window = Select-Window | Where-Object { $_.ProcessID -eq $id }
# send keys
$window | Send-Keys 123
$window | Send-Keys '{+}'
$window | Send-Keys 999
$window | Send-Keys =
# send CTRL+c
$window | Send-Keys '^c'

Related

Need to minimize a particular window

I had tried with below script. While using the below command it will minimize all opened applications. I need minimize only the policy updating window only(Gpupdate.exe). please find the attached gpupdate windows screenshots.
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "gpupdate.exe"
Start-Sleep -s 1
$shell = New-Object -ComObject "Shell.Application"
$shell.minimizeall()
Check out Set-WindowState.ps1 at https://gist.github.com/Nora-Ballard/11240204
It utilizes user32.dll ShowWindowAsync function.
After dot sourcing the function, I can use this in a script:
Get-Process -ID $PID | Set-WindowState -State MINIMIZE
Start-Sleep 3
Get-Process -ID $PID | Set-WindowState -State RESTORE
As long as my script is running within its own window this works. You need to have the process that is the window you want to minimize.
When using Windows 11 (and the Windows Terminal), this script may not work properly with using $PID.
To minimize the Windows Terminal, use
(Get-Process | Where-Object {$_.name -Match 'Terminal'}) | Set-WindowState -State MINIMIZE
The problem is, that it minimizes all Windows Terminal windows.

Kill a task based on its windows title

I'm looking to kill a process using it PID when a particular file is open on my computer, so that it doesn't interfere with another script
I have an excel sheet that is referenced by other parts of my system, it is fed information from many different sources I want to automate my workflow to work more smoothly.
Get-Process |where {$_.mainWindowTItle -eq "RASP transfer.xlsx - Excel"} |Write-Output
I'm stuck on how to extract the PID and use it as a variable in a task Stop-Process -ID PID
maybe I'm missing something help
in the end it should look something like this
Get-Process |
Where {$_.mainWindowTItle -eq "RASP transfer.xlsx - Excel"} |
Write-Output $pid=id |
Stop-Process -ID $PID
edit: 6/6/19
Currently I'm able to identify the PID of the specific workbook
by running
Get-Process |where {$_.mainWindowTItle -eq "RASP transfer.xlsx - Excel"} |Write-Output
which I can identify here in the taskmanager
However when the files are run with scripts the excel file is hidden and can't be searched with the windows title....
One of the nice features of Powershell is that you can pass an object on the pipeline. You don't even need the Process ID:
Get-Process | Where {$_.mainWindowTItle -eq "RASP transfer.xlsx - Excel"} | Stop-Process
However it's important to know what type of object you're passing along at each stage in the pipeline. The input to Stop-Process in the line above is a Process object, that has an ID property.
If you wanted to get the Process ID you could assign it to a variable.
$PID = (Get-Process | Where {$_.mainWindowTItle -eq "RASP transfer.xlsx - Excel"}).ID
... which will usually only get a single Process ID because Excel doesn't allow opening the same spreadsheet in two windows. But you can't rely on the window title to be unique because it would be the same if you opened two copies of the same spreadsheet from different folders.
If you wanted to close all Excel windows, this code would get all the Excel windows' processes into an Object[] array:
$ExcelProcs = Get-Process | Where {$_.mainWindowTItle -like "* - Excel"}
Stop-Process is smart enough to use the array of [Object] as input and stop all their processes:
$ExcelProcs | Stop-Process
Why not just re- enable the visibility before you check for the open sheet with:
$x1.Visible = $true
$PID = (Get-Process | Where {$_.mainWindowTItle -eq "RASP transfer.xlsx - Excel"}).ID

how to bring forward an IE window with powershell

I have the following powershell command that will run on users pc on a scheduled basis, based on a REST API Call to know if they havent submitted the timesheet.
It works fine, but I would like to put the IE window as the main window at that moment.
$msgBoxInput = [System.Windows.MessageBox]::Show('You havent submitted the timesheet. Please do it now','xyz is watching you','OK','Error')
$IE=new-object -com internetexplorer.application
$IE.navigate2("www.microsoft.com")
$IE.visible=$true
Is it doable with powershell? in an easy way
It should be doable.
Have a look at this example:
## Find all Active Windows Titles
$windows=Get-Process | Where-Object {$_.MainWindowTitle -ne ""} | Select-Object MainWindowTitle
## Find Specific name
$WindowTitle=($windows | ? {$_ -match "Internet Explorer"} ).MainWindowTitle
## Add Type and Focus Activate the Window
$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate($WindowTitle)
You just have to make sure that you have the correct MainWindowTitle.
Hope it helps

Is there a way in powershell to easily signal when a long-running command finished (e.g. file move command)

I've started a file move command at CMD.EXE and wait minutes and hours for completion of my administrative transfer of TBs of data. To get a signal when it's finished, it would be great to get a signal somehow after the command finished
What I've got:
window with CMD.EXE> MOVE G:. T:
window with powershell
I already found some helpful code to identify the process
Get-Process |where {$_.mainWindowTitle -like "*move*"} | format-table id,name,mainwindowtitle -AutoSize
which shows something like
PS L:\srvcl01> Get-Process |where {$_.mainWindowTitle -like "*move*"} | format-table id,name,mainwindowtitle -AutoSize
Id Name MainWindowTitle
-- ---- ---------------
2820 cmd Administrator: C:\Windows\System32\cmd.exe - move l:srvcl01_hdd2_data.vhdx .
Now it just needs to wait for disappearing of this main window title and then send an e-mail or system sound
Now it just needs to wait for disappearing of this main window title and then send an e-mail or system sound
While (Get-Process | Where-Object {$_.mainWindowTitle -like '*move*'}) { }
[Console]::Beep(1000,1000)
#OR
Send-MailMessage ...
Once the process ends, the loop will end and fall through to the options below.
I solved it by myself in parallel - but thanks to #TheIncorrigible1 who already provided a first solution
This is now my code - which waits a few seconds between each interval (reduces CPU load):
while (#(Get-Process |where {$_.mainWindowTItle -like "*move*"}).length -gt 0){
Start-Sleep -s 15
}; Send-MailMessage -to "me.myself#company.com" -from "admin-server123#company.com" -Subject "DONE: File copy/move task finished" -body "Finished :-)" -SmtpServer smtp.company.local -Port 2567
And by the way: my file move job finished after approx. 6 hours successfully ;-)

How to disable touch screen of laptops using PowerShell script?

My clients are using "HP Elitebook 840" touch screen laptop and recently we launched a website for their service, unfortunately click events on buttons did not worked in the web site. After a long R&D we realized it was touch screen issue and mouse click events started working after disabling it.
More info here: Click events are not working in Chrome, but event fires when we execute it manually from console
Since there are more than 40 users having same touch screen laptops, we would like to run a script to disable the touch feature of these laptops. I think network admin needs to run powershell script to do it, but I could not figure it out how to write single script to disable the touch screen of systems
I was reading http://www.surfaceforums.net/threads/disable-the-touch-screen-to-use-the-pen.12338/ but since I am new to PowerShell so need more detailed steps.
Powershell nuggets to disable/enable laptop touch screen. Tested in Windows 10 on Asus UX 501. Run as administrator.
Get-PnpDevice | Where-Object {$_.FriendlyName -like '*touch screen*'} | Disable-PnpDevice -Confirm:$false
Get-PnpDevice | Where-Object {$_.FriendlyName -like '*touch screen*'} | Enable-PnpDevice -Confirm:$false
(Source)
Use this in PowerShell:
Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Wisp\Touch -Name TouchGate -Value 0 -Type DWord
Restart machine after.
You can use the following registry key to disable touch input (requires a reboot):
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Wisp\Touch]
"TouchGate"=dword:00000000
Or with PowerShell:
Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Wisp\Touch ompany -Name TouchGate -Value 0 -Type DWord
After some trial and error, I decided the best thing for me was to save two .bat files to handle this so that I could easily launch it using Launchy. Code below - you might need to add in logic to for the ExecutionPolicy based on your configuration, but works for me as written.
Copy this into notepad and save it as a .bat - just switch out "Disable" for "Enable" and you're good to go either direction
#ECHO off
Powershell.exe -Command "& {Start-Process Powershell.exe -ArgumentList '-Command ""& {Get-PNPDevice | Where-Object FriendlyName -Like ''*touch screen*'' | Disable-PNPDevice -Confirm:$false} ; Get-PNPDevice | Where-Object FriendlyName -Like ''*touch screen*'' ; if ($Host.Name -eq ''ConsoleHost'') {Write-Host ''Press any key to continue...'' ; $Host.UI.RawUI.FlushInputBuffer() ; $Host.UI.RawUI.ReadKey(''""NoEcho,IncludeKeyUp''"") > $null}""' -Verb RunAs}"
I found this question and saw the answers, which are good. However, I found that I didn't want two different scripts to enable/disable the touch screen. I wanted to have it under one to just toggle it's state, so I wrote this script:
# To allow script to be executed on double click
# https://stackoverflow.com/a/30644946/1366368
# To sign script
# https://adamtheautomator.com/how-to-sign-powershell-script/
# To automatically elevate script to admin privs, I used this code fromn https://superuser.com/a/532109/222708
param([switch]$Elevated)
function Test-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
$currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
if ((Test-Admin) -eq $false) {
if ($elevated) {
# tried to elevate, did not work, aborting
} else {
# Removed -noexit as it will force the powershell instance to keep running after finishing
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
}
exit
}
# If Status of touch screen is Error, then it is off.
$result = (Get-PnpDevice|Where-Object {$_.FriendlyName -like '*touch screen*'}|Select -ExpandProperty 'Status')
if ($result -eq 'Error') {
Write-Host "Enabling touch screen"
Get-PnpDevice|Where-Object {$_.FriendlyName -like '*touch screen*'}|Enable-PnpDevice -Confirm:$false
} else {
Write-Host "Disabling touch screen"
Get-PnpDevice|Where-Object {$_.FriendlyName -like '*touch screen*'}|Disable-PnpDevice -Confirm:$false
}