This is a Powershell script that runs just fine under Server 2003. We're needing to move to Server 2008 R2 and the script isn't working. Specifically the script is not sleeping while waiting for IE to finish loading the page.
$objIE = New-Object -ComObject "InternetExplorer.Application"
if($objIE.ReadyState -notmatch "0|1|2|3|4")
{
$objIE = [System.Runtime.InteropServices.Marshal]::GetActiveObject("InternetExplorer.Application")
if($objIE.ReadyState -notmatch "0|1|2|3|4")
{
Stop-Process -processname iexplore
$objIE = New-Object -ComObject "InternetExplorer.Application"
}
}
$objIE.Visible = $giShowResults
$objIE.Navigate($gsURL + "APAdmin.asp?cmd=login&loginname=" + $gsAdminName + "&password=" >>+ $gsAdminPassword)
while($objIE.Busy -eq $true)
{
$dtNow = Get-Date
Start-Sleep 1 # Sleep for one second
}
$objIE.Navigate($gsURL + "APAdmProcessClosings.asp?cmd=run&AutomatedProcess=y")
while($objIE.Busy -eq $true)
{
Start-Sleep 1 # Sleep for one second
}
When I run with Visible set to true I can see IE open, the APAdmin.asp page loads, and then the script says it's finished without running the APAdmProcessClosings.asp page.
I've searched the Net but haven't been able to find any reason why yet.
It appears the Enhanced Security Configuration was the problem. Once I added the site to the list of trusted sites then the job would run successfully.
Related
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.
My case happens when I run $IE.quit() already, but internet explorer still exists in the task manager.
if I run the quit function at "quit IE 1" there, the Internet Explorer will close/end (not exits in Task Manager),
but when I run it at "quit IE 2" there, the IE not end (still exist in Task Manager)
if run with $IE.Visible = $true it has no such problem.
Environment: Windows Server 2016, PowerShell v5.1
May I know what may cause this?
May I know after the "confirm page loaded", what happened to $IE? And possibly cause IE not to quit.
Or how I can trace this kind of problem?
I do try to run this without try/catch, but the same thing happens. I try to put $IE = null, but the same, while, the $IE.Quit() description as to force the end of IE, suppose no wonder what is running on the IE. It will end the task.
Here is the PowerShell script:
$looping = 10
timenowhms = (Get-Date -f HH:mm:ss)
try {
$Url = "http://localhost:8080/commandcenter/checking.aspx"
$IE = New-Object -Com InternetExplorer.Application
$IE.Height = 700
$IE.Width = 750
$IE.Top = 10
$IE.Left = 10
$IE.Visible = $false; # can turn on for testing purpose
$IE.Navigate2($url);
$IEPID = [IntPtr]::Zero
[Win32Api]::GetWindowThreadProcessId($IE.HWND, [ref]$IEPID);
# quit IE 1
$IE.Quit();
} catch {
$timenowhms = (Get-Date -f HH:mm:ss);
echo "$td_date $timenowhms Open website failed";
if ((Get-Process -Name "iexplore*" | ? {$_.Id -eq $IEPID} | measure).Count -eq 1) {
Stop-Process -Id $IEPID -force
};
exit 1
}
# confirm page loaded
while ($ie.Busy -eq $true) {
if ($looping -eq 0) {
$timenowhms = (Get-Date -f HH:mm:ss);
echo "$td_date $timenowhms Timeout, page not show";
if ((Get-Process -Name "iexplore*" | ? {$_.Id -eq $IEPID} | measure).Count -eq 1) {
Stop-Process -Id $IEPID -Force
};
exit 1
} else {
Start-Sleep -Milliseconds 2500;
$looping--;
}
}
# quit IE 2
# $IE.Quit();
exit
I have a powershell script I'm running on startup to open a website and log in. It works fine whenever I run the script manually, or whenever I sign out of my profile in Windows and sign back in. However, when I restart the computer, the script opens the website, but then fails to edit the DOM to change the username and password text fields and click the submit button. It seems to attempt to change the values because the cursor stops blinking, but nothing happens.
Here is the code.
$IEProcess = [System.Diagnostics.Process]::Start("iexplore", "-k https://www.website.com")
Sleep -Seconds 1
$IE = $(New-Object -ComObject "Shell.Application").Windows() | ? {$_.HWND -eq $IEProcess.MainWindowHandle}
while ($IE.ReadyState -ne 4)
{
Start-Sleep -Milliseconds 100
}
$IE.Document.getElementById(“userNameInput”).value = $Username
$IE.Document.getElementByID(“passwordInput”).value= $Password
$IE.Document.getElementById(“submitButton”).Click()
Using this code, I was able to get it to work. It may have to do with how you are configuring it to run on startup.
$Url = "https://stackoverflow.com/users/login?ssrc=head&returnurl=https%3a%
2f%2fstackoverflow.com%2f"
$Username="name#email.com"
$Password="password"
$IE = New-Object -com internetexplorer.application;
$IE.visible = $true;
$IE.navigate($url);
while ($IE.Busy -eq $true)
{
Start-Sleep -Milliseconds 2000;
}
$IE.Document.getElementById("email").value = $Username
$IE.Document.getElementByID("password").value=$Password
$IE.Document.getElementById("submit-button").Click()
I did the following:
Open gpedit.msc
User config > Windows Settings > Scripts (Logon/Logoff)
"PowerShell Scripts" tab
Add script
On the second run of this script, I can open Microsoft and Yahoo if I first close Bing; how can I open those sites without first closing Bing? The error:
Method invocation failed because [System.Object[]] doesn't contain a method named 'Navigate2'.
+ $ie.Navigate2 <<<< ("www.microsoft.com", $navOpenInNewTab);
+ CategoryInfo : InvalidOperation: (Navigate2:String) [], Runtime Exception
+ FullyQualifiedErrorId : MethodNotFound
Why does it fail when I have Bing and Google open, but not when I have Google open?
# Set BrowserNavConstants to open URL in new tab
# Full list of BrowserNavConstants: https://msdn.microsoft.com/en-us/library/aa768360.aspx
$navOpenInNewTab = 0x800;
$navOpenInBackgroundTab = 0x1000;
$ie = $null
if (Get-Process iexplore -ea silentlycontinue | Where-Object {$_.MainWindowTitle -ne ""}) {
$ie = (New-Object -COM "Shell.Application").Windows() | ? { $_.Name -eq "Internet Explorer" }
} else {
$ie = New-Object -COM "InternetExplorer.Application"
sleep -milliseconds 50
$ie.visible = $true
}
$today = (get-date).DayOfWeek
switch ($today) {
"Someday" {
$ie.Navigate("www.bing.com");
$ie.Navigate2("www.yahoo.com", $navOpenInBackgroundTab); break
}
default {
$google = $false
# Check if Google open
foreach ($tab in $ie) {
if ($tab.LocationURL.Contains("google"))
{ $google = $true; break }
}
# If Google open on second run, open Microsoft and Yahoo
if ($google) {
$ie.Navigate2("www.microsoft.com", $navOpenInNewTab);
$ie.Navigate2("www.yahoo.com", $navOpenInBackgroundTab);
} else {
# On first run, open Bing and Google
$ie.Navigate("www.bing.com");
$ie.Navigate2("www.google.com", $navOpenInBackgroundTab);
}
break
}
}
# Cleanup
'ie' | ForEach-Object {Remove-Variable $_ -Force}
Your problem seems to be, that the script fails to find (the right) open IE instance on the second run. Debug the Script in the PowerShell ISE (or the PowerShell PowerGUI) and set a breakpoint at $ie=(New-Object -COM "Shell.Application").Windows() | ? {$_.Name -eq "Internet Explorer"}
Run the following command in the interactive PowerShell Window below: (New-Object -COM "Shell.Application").Windows() | Select-Object { $_.Name }
Do you get something like this as output?
File Explorer
Internet Explorer
Internet Explorer
Internet Explorer
Internet Explorer
Try to adjust your code as needed when your IE windows have different Names.
The following code works on my machine: I select just the first IE instance (otherwise you get problems since you open multiple sites).
...
# If Google open on second run, open Microsoft and Yahoo
if ($google) {
sleep -milliseconds 50
$ie[0].Navigate2("www.microsoft.com", $navOpenInBackgroundTab);
sleep -milliseconds 50
$ie[0].Navigate2("www.yahoo.com", $navOpenInBackgroundTab);
} else { ...
I have created a CentOS 7 minimal VM running under Hyper-V. To this I have installed Transmission and set it to start the service on boot using systemctl enable transmission-daemon.service
I want to write a powershell script that will start the server, wait until it is active and then open a url to see the Transmission web interface.
I have used Get-VMIntegrationService but this returns a value of OK for the heartbeat partway through boot. I've therefore had to resort to Start-Sleep to wait another 15 seconds so that when my script opens the browser it doesn't get a timeout.
Is there a way to establish the login screen has been reached? Or a more elegant way of doing this?
This is my current startup powershell script:
$vmToStart="CentOS_7_minimal"
$url="http://"+$vmToStart+":9091/"
if ((Get-VMIntegrationService $vmToStart | ?{$_.name -eq "Heartbeat"}).PrimaryStatusDescription -ne "OK")
{
Write-Host "Starting Transmission server..." -foregroundcolor "blue"
start-vm $vmToStart
do {Start-Sleep -milliseconds 100}
until ((Get-VMIntegrationService $vmToStart | ?{$_.name -eq "Heartbeat"}).PrimaryStatusDescription -eq "OK")
Write-Host "Transmission server started." -foregroundcolor "yellow"
Write-Host "Starting Transmission service..." -foregroundcolor "blue"
Start-Sleep -seconds 15
}
Start-Process $url
Elegant it is not, but you could simply check if the site you need from the VM is available by just polling for it. The .NET Webclient is quite straightforward to use. See my example below.
$webClient = New-Object System.Net.WebClient
$url = "http://www.stackoverflow.com"
Do {
Start-Sleep -Seconds 1
try { $content = $webClient.DownloadString($url) }
catch { Write-Host "Page not yet retrieved . . ."}
} While ( $content -eq $null)