Is it possible to click a button in an application using Powershell? - powershell

i am trying to write a powershell script that checks connectivity thru a continuous ping, if the ping is unsuccessful the script should start a process and when a window is opened have the script click on a specific button, i have done my research and have not found much help other than this
but this is dependant on Actions having schortcuts that's why it doesn't work for me, i would like to know if it's even possible to do this using powershell before i procced with my work.
this is my script so far.
$IP = "192.X.X.X"
$TimeOut = 500
$FailureThreshold = 10
$Ping = New-Object System.Net.NetworkInformation.Ping
Do {
$Result = $Ping.Send($IP,$Timeout)
if ($Result.Status -eq "Success") {
Write-Output "Working as intended."
Exit 0
}
else {
Write-Output "Ping Failed!"
$Failures += 1
}
} until ($Failures -ge $FailureThreshold)
Write-Output "Main DHCP is Down, Starting Backup DHCP Server..."
start-process "C:\Users\XXXX\Desktop\DHCP\dhcpsrv2.5.2\dhcpsrv.exe"
everything works great, i just need to get that button clicked.
and here is a photo of the window that pops up and the button that needs to be clicked.

i got it! Maybe this will help someone.
start-process "C:\Users\XXXX\Desktop\DHCP\dhcpsrv2.5.2\dhcpsrv.exe"
$StartDHCP = New-Object -ComObject wscript.shell;
Sleep 1
$StartDHCP.SendKeys('%C')
where % = ALT

Yes it's possible, u can use an app called Auto-it where u Send a mouse click to a specific button in the Window.
it's explained here in details on the Autoit website
https://www.autoitscript.com/autoit3/docs/functions/ControlClick.htm

Related

Start Internet Explorer, wait until the user closes it, then exit the script

I have a script that opened IE with no toolbar and to navigate to a url (below)
Dim IE, URL
URL = "website.com"
Set IE = CreateObject("InternetExplorer.Application")
IE.Navigate URL
IE.Visible = 1
IE.ToolBar = 0
IE.Left = 0
I need to have the window appear like this for reasons,
I cant use kiosk mode.
What I need to do is:
run the script (LaunchIE_noToolbar.vbs)
open IE, hide toolbar, go to url
wait in the background while the user does stuff which might be 10-15 minutes later
recognize it's closed and exit the script
It seems simple enough, but I can't work it out, the waiting part is driving me nuts.
If you can do this in PowerShell that would be great too, I don't mind.
I'm not in front of a computer right now, but as I recall...
You can start a process aka start-process I think. Grab the process ID which is returned. Then wait for the process to complete, might be wait-process? Do a "help process" at the PowerShell prompt for commands and syntax.
There may be a more elegant PowerShell solution, but this seems to work:
$url = "website.com"
$ie = New-Object -ComObject "InternetExplorer.Application"
$ie.Navigate($url)
$ie.Visible = 1
$ie.ToolBar = 0
$ie.Left = 0
# Wait for IE to exit.
while ($null -ne $ie.ReadyState) { # .ReadyState is only $null once the IE instance exits
Start-Sleep -Milliseconds 100
}

Check if a Powershell script has frozen using a separate script

So I'm preforming some automated testing using powershell in jenkins. I'm testing a web application where I must fill out forms, retrieve values, etc.
It is all fine but the web app contains some pop up messages that appear every now and then, which causes the main script to freeze until they are manually closed in the application. Below is a link to a stack overflow thread with a similar problem.
Powershell Website Automation: Javascript Popup Box Freeze
I followed the advice of the first answer. I created a separate powershell script that is executing constantly and can tell if there is a pop up window present (as they have their own process ids, so if there is more then one iexplore process id present it must be a popup) and then uses sendkeys to close it.
Main Script example:
#start application
start C:\Users\Webapp
#start the monitor script
Start-Process Powershell.exe -Argumentlist "-file C:\Users\Monitor.ps1"
#Get app as object
$app = New-Object -ComObject Shell.Application
$ClientSelectPage = $app.Windows() | where {$_.LocationURL -like "http:webapp.aspx"}
#Input value to cause popup message
$MemNumberInput = $ClientSelectPage.Document.getElementByID("MemNum")
$MemNumberInput.Select()
$MemNumberInput.value = "22"
$FindBtn.click()
It is at this point my script will freeze (as pop up window appears to tell me info abotu the client I've inserted) If this popup can be seen as a process, the monitor code will close it.
Example of monitor
$i = 0
while($i -eq 0)
{
#Check what process are currently running under the webapps name
$Mainprocid = Get-Process | where {$_.mainWindowTitle -like "*webapp*" } | select -expand id
$Mainprocid.COUNT
$integer = [int]$Mainprocid
#If there is only one process, no action
if( $Mainprocid.count -eq 1)
{
echo "no popup"
}
else
{
if($integer -eq '0')
{
#If there are no processes close the script
$i = 1
echo "close process"
}
else
#If there are two processes one must be a pop, send 'enter' to the app
{
echo "POP UP!"
$title = Get-Process |where {$_.mainWindowTItle -like "*webapp*"}
#Code to sendkeys 'ENTER' to the application to close the popup follows here
}
}
}
However, for whatever reason, some pop ups cannot be found as processes and the monitor script is useless with them. These are few and far between, so I figured the best way was for the monitor script to check and see if the main script has frozen for a certain amount of time. If so, it can use the sendkeys method it does for the other popups.
Is there a way for me to check and see if the main script has frozen, from the monitor script? I understand I could pass a parameter from the main script every now and then, to let the monitor script know it is still active, but this seems like a messy way of doing it, and an alternative method would be preferable.
Both scripts are saved as .ps1 files.

Check if mouse\keyboard is active using Batch or PowerShell

I have been searching for this for a long time, and can't find one single answer.
Is it possible to check if my mouse or keyboard is in use (the mouse is currently moving or keys are being pressed) using only a Batch or PowerShell script? If yes, how?
As for the mouse movement, you could check the position of the pointer and calculate if there is a change over time.
$p1 = [System.Windows.Forms.Cursor]::Position
Start-Sleep -Seconds 5 # or use a shorter intervall with the -milliseconds parameter
$p2 = [System.Windows.Forms.Cursor]::Position
if($p1.X -eq $p2.X -and $p1.Y -eq $p2.Y) {
"The mouse did not move"
} else {
"The mouse moved"
}
As for the keys, you might want to try a similar technique utilizing the get-keystroke script (which is basically a keylogger).

How to perform keystroke inside powershell?

I have ps1 script to grab some information from the vmware cluster environment.
In some place of ps1 script requires the ENTER button keystroke.
So, How to do that ?
-Thanks
If I understand correctly, you want PowerShell to send the ENTER keystroke to some interactive application?
$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate('title of the application window')
Sleep 1
$wshell.SendKeys('~')
If that interactive application is a PowerShell script, just use whatever is in the title bar of the PowerShell window as the argument to AppActivate (by default, the path to powershell.exe). To avoid ambiguity, you can have your script retitle its own window by using the title 'new window title' command.
A few notes:
The tilde (~) represents the ENTER keystroke. You can also use {ENTER}, though they're not identical - that's the keypad's ENTER key. A complete list is available here: http://msdn.microsoft.com/en-us/library/office/aa202943%28v=office.10%29.aspx.
The reason for the Sleep 1 statement is to wait 1 second because it takes a moment for the window to activate, and if you invoke SendKeys immediately, it'll send the keys to the PowerShell window, or to nowhere.
Be aware that this can be tripped up, if you type anything or click the mouse during the second that it's waiting, preventing to window you activate with AppActivate from being active. You can experiment with reducing the amount of time to find the minimum that's reliably sufficient on your system (Sleep accepts decimals, so you could try .5 for half a second). I find that on my 2.6 GHz Core i7 Win7 laptop, anything less than .8 seconds has a significant failure rate. I use 1 second to be safe.
IMPORTANT WARNING: Be extra careful if you're using this method to send a password, because activating a different window between invoking AppActivate and invoking SendKeys will cause the password to be sent to that different window in plain text!
Sometimes wscript.shell's SendKeys method can be a little quirky, so if you run into problems, replace the fourth line above with this:
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait('~');
function Do-SendKeys {
param (
$SENDKEYS,
$WINDOWTITLE
)
$wshell = New-Object -ComObject wscript.shell;
IF ($WINDOWTITLE) {$wshell.AppActivate($WINDOWTITLE)}
Sleep 1
IF ($SENDKEYS) {$wshell.SendKeys($SENDKEYS)}
}
Do-SendKeys -WINDOWTITLE Print -SENDKEYS '{TAB}{TAB}'
Do-SendKeys -WINDOWTITLE Print
Do-SendKeys -SENDKEYS '%{f4}'
Send "Enter" key to an App, for example for pressing "OK". Works great:
Add-Type -AssemblyName microsoft.VisualBasic
Add-Type -AssemblyName System.Windows.Forms
# Get the desired process:
$ProcessName = Get-Process -Name Calculator
Start-Sleep -Seconds 1
# If the process is actually running, bring it to front:
If ($ProcessName)
{
(New-Object -ComObject.Wscript.Shell).AppActivate((Get-Process $ProcessName -ErrorAction SilentlyContinue).MainWindowTitle)
}
# Send "Enter" key to the app:
[Microsoft.VisualBasic.Interaction]::AppActivate($ProcessName.ProcessName)
[System.Windows.Forms.SendKeys]::SendWait({'~'})
Also the $wshell = New-Object -ComObject wscript.shell; helped a script that was running in the background, it worked fine with just but adding $wshell. fixed it from running as background! [Microsoft.VisualBasic.Interaction]::AppActivate("App Name")

Use powershell to populate dialog box from another program

I am writing a script to uninstall and reinstall a piece of software.
Annoyingly, you have to enter a password as part of the uninstall process. (i.e. the uninstaller pops up with a box, the user enters a password to continue)
I want to be able to detect the dialog box, and enter the password automatically - so the user doesn't have to do anything. I seem to remember there's a way to do this, but not sure how.
Figured it out:
$app = get-process | where {$_.mainwindowtitle -match "Admin Password"}
$processID = 0
foreach ($a in $app) {
if ($a.id -gt $processID)
{
$processID = $a.id
}
}
start-sleep -Milliseconds 500
[Microsoft.VisualBasic.Interaction]::AppActivate($processID)
[System.Windows.Forms.SendKeys]::SendWait("mypassword{ENTER}")
Works great inmy demo app. Trouble is the app I am trying to send the password to is protected from SendKeys.
D'oh. Back to the drawing board...