recently I began to learn PowerShell to automate my job tasks.
So I want to access a web page and click on a button that download automatically an Excel file. This is the button that I want to click on:
<div class="NormalButton">
<a class="ActiveLink" title="Excel" alt="Excel" onclick="$find('ctl32').exportReport('EXCELOPENXML');" href="javascript:void(0)" style="padding:3px 8px 3px 8px;display:block;white-space:nowrap;text-decoration:none;">Excel</a>
</div>
This would be my PowerShell script:
$ie = New-Object -com "InternetExplorer.Application"
$ie.Navigate("http://test.test/")
$ie.Visible = $true
$link = $ie.Document.getElementsByTagName('a') | Where-Object {$_.onclick -eq "$find('ctl32').exportReport('EXCELOPENXML');"}
$link.click()
If I try to run it from the console I receive the error "You cannot call a method on a null-valued expression."
If its useful I'm using PowerShell 4.0 and the webpage has a delay until the report is loaded.
I have completed it by the following code:
[void][System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
$url = "https://webpage.com"
$ie = New-Object -com internetexplorer.application
$ie.navigate($url)
$ie.StatusBar = $false
$ie.ToolBar = $false
$ie.visible = $true
#Get Excel
Start-Sleep -s 40
$btnExcel = $ie.Document.links | where-object { $_.outerText -eq 'Excel' -and $_.innerText -eq 'Excel' }
$btnExcel.click()
# Get Internet Explorer Focus
Start-Sleep -s 5
[Microsoft.VisualBasic.Interaction]::AppActivate("internet explorer")
[System.Windows.Forms.SendKeys]::SendWait("{F6}");
[System.Windows.Forms.SendKeys]::SendWait("{TAB}");
[System.Windows.Forms.SendKeys]::SendWait(" ");
Start-Sleep 1
[System.Windows.Forms.SendKeys]::SendWait("$file");
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}");
# Get Internet Explorer Focus
Start-Sleep -s 1
[Microsoft.VisualBasic.Interaction]::AppActivate("internet explorer")
[System.Windows.Forms.SendKeys]::SendWait("^{F4}");
Thank you all for you time :)
I Think the Your problem is because you are using Double Quotes which powershell threat it like variable and Try to expand it, so try to change it to Single quote, from:
$link = $ie.Document.getElementsByTagName('a') | Where-Object {$_.onclick -eq "$find('ctl32').exportReport('EXCELOPENXML');"}
to:
$link = $ie.Document.getElementsByTagName('a') | Where-Object {$_.onclick -eq '$find('ctl32').exportReport('EXCELOPENXML');'}
Also, you can change the -eq to -match and take just a portion of it like:
$_.onclick -match '$find('ctl32').exportReport'
For more information see: About Quoting Rules
Related
I am doing an IE Automation with ServiceNow where there is an option to fill the search data but there is no search button available to use the CLICK method. So I am looking for the method to enter key like {ENTER} or {~} once I filled the search data. But I am in a middle stage of PowerShell scripting and not sure how to use that.
If someone could help me with the method that would be greatly appreciate.
$IE = New-Object -ComObject InternetExplorer.application
$IE.FullScreen = $false
$IE.Visible = $true
$IE.Navigate($ServiceNowURL)
While ($IE.Busy -eq $true)
{
Start-Sleep -Milliseconds 50
}
$Enter = Read-Host 'To continue press ENTER'
#Enter
$Search = $IE.Document.IHTMLDocument3_getElementsByTagName('input') | ? {$_.id -eq 'sysparm_search'}
$EnterValue = $Search.value() = $TicketNumber
First, you need to active IE window and bring it to front using AppActivate, then set focus to the search area using focus(). After that, you can send Enter key using SendKeys.
I use https://www.google.com to search as an example and you can refer to my code sample below. I test it and it works well:
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
$ie = New-Object -ComObject 'InternetExplorer.Application'
$ie.Visible=$true
$ie.Navigate("https://www.google.com") #change it to your own url
while($ie.ReadyState -ne 4 -or $ie.Busy) {Start-Sleep -m 100}
$search=$ie.Document.getElementsByName("q")[0] #change it to your own selector
$search.value="PowerShell" #change it to your own search value
Sleep 5
$ieProc = Get-Process | ? { $_.MainWindowHandle -eq $ie.HWND }
[Microsoft.VisualBasic.Interaction]::AppActivate($ieProc.Id)
$search.focus()
[System.Windows.Forms.SendKeys]::Sendwait("{ENTER}");
I need to use PowerShell to hit close on this pop up window which appears when I open internet explorer. Hitting enter key also closes the pop up.
What I've tried
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
$ie = new-object -com internetexplorer.application
$ie.visible = $true
$ie.navigate('http://website/')
while ($ie.busy) { Start-Sleep 3 }
[Microsoft.VisualBasic.Interaction]::AppActivate("internet explorer")
[System.Windows.Forms.SendKeys]::Sendwait("{ENTER}");
Start-Sleep 3
$link = $ie.Document.getElementsByTagName('Button') | where-object { $_.innerText -eq 'Simple Setup' }
$link.click()
Start-Sleep 2
$ie.quit()
Continuing from my comment.
Others have run into this dialog and others, and, as stated, used Selenium, AutoIT, et., to deal with that; while others have tried different means.
For Example:
# using the process handle of that dialog
$ws = New-Object -ComObject WScript.Shell
$ld = (gps iex* | where {$_.MainWindowTitle }).id
if($ld.Count -gt 1)
{
$ws.AppActivate($ld[1])
$ws.sendkeys("{ENTER}")
}
# Using the WASP module
# (note - though the code for this module is still available, the DLL is not. So, you have to compile that yourself.)
Import-Module WASP
while ($true) {
[System.Threading.Thread]::Sleep(200)
$confirmation = Select-Window iexplore
if ($confirmation -ne $null)
{
Select-ChildWindow -Window $confirmation |
Select-Control -title "OK" -recurse |
Send-Click
}
}
btw..
"Hitting enter key also closes the pop up"
... that is because modal dialogs always take focus until they are dismissed.
I am trying to download file on IE Version 21H from Website using powershell.
when I click Download button using powershell, it asks me for download Popup window with below massage.
You Want to Open or Save XYZ.log from www.XYZ.com
below is the code I am using
$ie = New-Object -ComObject 'internetExplorer.Application'
$ie.Visible=$true
$ie.Navigate("www.xyz.com/ab/sder23445sdfrty") #please note this is random URL I provided
$link=$ie.Document.getElementsByTagName("Button") | where-object {$_.outerhtml -like "*download*"}
$link.click()
You can first active the IE window and bring it to front using AppActivate, then using SendKeys to send keystrokes Ctrl+S to save the file.
The sample code is like below, you can change the url and element selector to your owns:
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
$ie = New-Object -ComObject 'internetExplorer.Application'
$ie.Visible=$true
$ie.Navigate("https://www.example.com/download.html") #change it to your own url
while($ie.ReadyState -ne 4 -or $ie.Busy) {Start-Sleep -m 100}
$link=$ie.Document.getElementById("btnDowload") #change it to your own selector
$link.click()
Sleep 5
$ieProc = Get-Process | ? { $_.MainWindowHandle -eq $ie.HWND }
[Microsoft.VisualBasic.Interaction]::AppActivate($ieProc.Id)
[System.Windows.Forms.SendKeys]::Sendwait("%{s}");
I am having an issue with selecting a checkbox. I have been able to successfully login and navigate via the ID tags, but this one doesn't have one. The only tags it has is type and class.
I can find this section using $ie.document.IHTMLDocument3_getElementByTagName("input"), but I can't find any way to utilize it.
Here's the html I'm working with:
<th class="cText sorting_disabled cHeader" rowspan="1" colspan="1" style="width: 5px;" aria-label="">
<input type="checkbox" class="selectall">
</th>
What I have thus far:
$ie = New-Object -ComObject "InternetExplorer.Application"
$ie.visible = "true"
$ie.navigate("https://some.site.com")
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
# login
$usernameField = $ie.document.IHTMLDocument3_getElementByID("userid")
$passwordField = $ie.document.IHTMLDocument3_getElementByID("Password")
$usernameField.value = "email#domain.com"
$passwordField.value = "supercoolpassword"
$btn_Submit = $ie.document.IHTMLDocument3_getElementByID("btn_signIn")
$btn_Submit.click()
# go to downloads page
$ie.navigate("https://some.site.com/pages/mydownloads.aspx")
# selectall packages to download has me clueless
When the checkbox is clicked the result should be all checkboxes should be ticked.
This is common place, so, you have to approach this differently.
$SiteSource.AllElements | Where{$_.TagName -eq 'input'}
or, like if it were a button
($ie.Document.IHTMLDocument3_getElementsByTagName('button') |
Where-Object innerText -eq 'SIGN IN').Click()
But how are you walking the site to get the needed objects?
An approach I regularly use before making coding decisions.
$SiteSource = Invoke-WebRequest -Uri 'SomeUrl'
# single form site
$SiteSource.Forms | Format-List -Force
# multi-form sites
$SiteSource.Forms[0] | Format-List -Force
$SiteSource.Forms[1] | Format-List -Force
# Check for what can be used.
$SiteSource.Forms.Fields
$SiteSource.InputFields
Then once gathering the above... code for what can be found and used.
$ie = New-Object -com InternetExplorer.Application
$ie.visible=$true
$ie.navigate('SomeUrl')
while($ie.ReadyState -ne 4) {start-sleep -m 100}
$UserID = $ie.document.getElementsByTagName('INPUT') |
Where-Object {$($_.Name) -match 'userid'}
$UserId.value = 'UserID'
$UserPassword = $ie.document.getElementsByTagName('INPUT') |
Where-Object {$($_.Name) -match 'password'}
$UserPassword.value = 'password'
$Submit = $ie.document.getElementsByTagName('INPUT') |
Where-Object {$($_.Value) -match 'SomeString'}
$Submit.click()
I want to click this Button: (Google.com)
<input value="Google-Suche" aria-label="Google-Suche" name="btnK" type="submit" jsaction="sf.chk">
This is my code:
$ie = New-Object -Com InternetExplorer.Application
$ie.Visible = $true
$ie.navigate("http://google.com")
Start-Sleep 5
$ie.Document.IHTMLDocument3_getElementById("lst-ib").value = $Keywords
$Link = $ie.Document.getElementsByTagName("input") | Where-Object {$_.name -eq "btnK"}
$Link.Click()
If I run it everything works fine, but it doesn't press the Button. However if I manually execute $Link.Click() it works.
Any idea how to fix this? Or has my Code some flaws? I am getting no Error Messages. I already trying putting a Start-Sleep 10 before clicking the Button, but that doesn't work either.
PS: I use Google just for testing. This Code will be for another Site, but I can't Access it at the moment.
You should sleep while ie is busy. This works for me:
$ie = New-Object -Com InternetExplorer.Application
$ie.Visible = $true
$ie.navigate("http://google.com")
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
$ie.Document.IHTMLDocument3_getElementById("lst-ib").value = "cheesecake"
$Link = $ie.Document.getElementsByTagName("input") | Where-Object {$_.name -eq "btnK"}
$Link.Click()