Internet Explorer PowerShell Script Profile Issue

Hi Guys,

I seem to be having a small issue with a New-Object -comobject InternetExplorer.Application PowerShell script, my script works perfectly when i run it in PS command line as well as within ISE but when i have it trigger within a Scheduled Task or within Orchestrator .Net activity it hangs or doesn't run.

I suspect that is has something to do with when i run it I am running it obviously as my user context with active windows and so on and when trying to run it as the Scheduled Task it doesn't have that.

Any assistance would be appreciated
LVL 8
Leon TaljaardSystem Center Specialist - ArchitectureAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Nadav SolomonCommented:
First thing I would check is powershell execution policy for your user/computer/64bit/32bit, try to run a small script that will write to event viewer or to a file and check if it does it and if it finishes.
maybe try powershell -executionpolicy bypass -file yourscript.ps1
0
Leon TaljaardSystem Center Specialist - ArchitectureAuthor Commented:
Hi Nadav,

This account has full admin rights on the server, it is a service account and does a lot of other scheduled tasks that run PowerShell scripts and they work perfectly.

This is why i suspect the issue might be user context or active window issue because when the script executes i can see the 2 iexplore processes but they never end and the script just hangs, but when i run it with my profile and within ISE or PS command line the same 2 processes span and close without issue.
0
Nadav SolomonCommented:
Without the script itself it's pretty hard to debug
0
Top Threats of Q1 & How to Defend Against Them

WEBINAR: Join WatchGuard CTO and our Threat Research Team on Aug. 2nd to hear the findings from our Q1 Internet Security Report! Learn more about the top threats detected in the first quarter and how you can defend your business against them!

Leon TaljaardSystem Center Specialist - ArchitectureAuthor Commented:
Here is the script, I also have a version of it that accepts parameters

if (!(Get-Variable ie -Scope global -ea SilentlyContinue) -or !$ie.Document)
{
  $global:ie = New-Object -comobject InternetExplorer.Application
}
$ie.silent  = $true
$ie.visible = $false

# First web site #

$username = 'username'
$Password ='password'
$DSN = 'Token'

$ie.Navigate("http://servername/ibsv54/_Ws/context.asmx/Login?Username=$Username&Password=$Password&DSN=$DSN")
while ($ie.busy)                               { Start-Sleep -m 100 }
while ($ie.Document.readyState -ne 'Complete') { Start-Sleep -m 100 }


# Second web site #

$Token = 'Token'
$CustomerID ='ID'
$ie.Navigate("http://servername/ibsv54/_Ws/customer.asmx/LoadOverview?Token=$Token&CustomerId=$CustomerID")
while ($ie.busy)                               { Start-Sleep -m 300 }
while ($ie.Document.readyState -ne 'Complete') { Start-Sleep -m 300 }

# XML Results #

$XML = $ie.Document.body.outertext -match '(\<xml\>.*\</xml\>)' | Out-Null; $matches[1] | Tee-Object -Variable a
$XML


# Stop IE Process #

$Import = '[DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint ProcessId);'
Add-Type -MemberDefinition $Import -Name 'Process' -Namespace 'Custom' -PassThru | Out-Null

$ProcessId = 0
# Get the process ID of the IE COM object
[Custom.Process]::GetWindowThreadProcessId($ie.HWND, [ref] $ProcessId) | Out-Null
if ($ProcessId -eq 0) { Throw 'Could not get process ID of Internet Explorer!' }

Stop-Process -id $ProcessId

Start-Sleep 5

Open in new window

0
Nadav SolomonCommented:
I've closed the process this way:
$ie.Quit()
$ie = $null

Open in new window


but i noticed that from time to time it opens IE again for no apparent reason so I've added:
Start-Sleep(1)

Open in new window

before the $ie.quit() and looks like it was resolved.

give it a try and let me know if it helped.
0
Nadav SolomonCommented:
This is what i've done to test it:
$ie = New-Object -comobject InternetExplorer.Application
$ie.silent  = $false
$ie.visible = $true

# First web site #

$username = 'username'
$Password ='password'
$DSN = 'Token'

$ie.Navigate("http://www.google.com") #servername/ibsv54/_Ws/context.asmx/Login?Username=$Username&Password=$Password&DSN=$DSN")

while ($ie.busy)                               { Start-Sleep -m 100 }
while ($ie.Document.readyState -ne 'Complete') { Start-Sleep -m 100 }


# Second web site #

$Token = 'Token'
$CustomerID ='ID'
$ie.Navigate("http://www.cnn.com") #servername/ibsv54/_Ws/customer.asmx/LoadOverview?Token=$Token&CustomerId=$CustomerID")
while ($ie.busy)                               { Start-Sleep -m 300 }
while ($ie.Document.readyState -ne 'Complete') { Start-Sleep -m 300 }

# XML Results #

$XML = $ie.Document.body.outertext -match '(zone-\d)' | Out-Null; $matches[1] | Tee-Object -Variable a
$XML


# Stop IE Process #
Start-Sleep(1)
$ie.Quit()
$ie = $null

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Leon TaljaardSystem Center Specialist - ArchitectureAuthor Commented:
Ok so I have tried this as well, please note that my previous script also closed IE perfectly, so if I run the script I get 2 iexplore processes spawned, then my script hangs and does not return a result.

If i leave these 2 running and not kill them and trigger my script again, then my script works and returns result and doesnt hang and it opens a 3rd iexplore process, but then if i leave those open and trigger my script over and over again then it works everytime, but if I kill those it hangs again.

It seems like it needs those open for it to work, but this is not the case when i run it from PS command or PS ISE.

3 iexplore processes spawned under the service account
0
Leon TaljaardSystem Center Specialist - ArchitectureAuthor Commented:
I also forgot that the stop process or the $ie.Quit() doesnt close those processes it spawned
0
Leon TaljaardSystem Center Specialist - ArchitectureAuthor Commented:
Ok I have just tested opening ISE as the service account and i tried my script within ISE running as that user and it also just does not end, so looks like its also hanging within ISE but only when running as that service account.

My problem is that this account is a local admin
0
Nadav SolomonCommented:
please try my example it works flawlessly even with all IE processes closed before the task starts.
try it as it is then modify it.
and when it finishes it doesn't leave IE process in task manager.
0
Leon TaljaardSystem Center Specialist - ArchitectureAuthor Commented:
It seems to be working !!!!

So all i really missed was perhaps the global and the sleep requirement ?
0
Nadav SolomonCommented:
Looks like it glad I could help.
0
Leon TaljaardSystem Center Specialist - ArchitectureAuthor Commented:
I am busy testing it now, my only concern is that I hope it will still work when triggered for over 100+ servers and at the moment i have 13 iexplore processes spawned.

I am using Orchestrator to run a workflow and it is doing a XML response check on almost 200 different servers.
0
Nadav SolomonCommented:
i would not do it in separated scripts at the same time but in 1 or as less as I can otherwise you will kill the server's performance.
0
Leon TaljaardSystem Center Specialist - ArchitectureAuthor Commented:
I have just checked the one activity that had a warning, so some return results perfectly but some dont.

I think this is the same issue I had with trying to check so many different servers, my problem is that i think with the $ie.Quit() it might be closing IE the same time the other check is trying to run on the other server/URL.

This is the error i get on some

Creating an instance of the COM component with CLSID {0002DF01-0000-0000-C000-000000000046} from the IClassFactory failed due to the following error: 80004005.
0
Nadav SolomonCommented:
why don't you do all those tests in one script?
0
Nadav SolomonCommented:
maybe just maybe you should try WebClient or Invoke-WebRequest instead of IE if you need so many sessions.
0
Leon TaljaardSystem Center Specialist - ArchitectureAuthor Commented:
I have tried invoke-webrequest, the problem with these is that for each test i need to open the first URL first and then the second URL which returns the XML i want, the reason for this is that the first URL creates an authentication session so i cannot get any result or return from the second url without opening a session with the first.
0
Leon TaljaardSystem Center Specialist - ArchitectureAuthor Commented:
I am trying to run it in a single script now quickly
0
Nadav SolomonCommented:
single script is good, just so you'll know invoke-webrequest can maintain token/session, check out example 2 https://technet.microsoft.com/en-us/library/hh849901.aspx?f=255&MSPPError=-2147217396

This example shows how to use the Invoke-WebRequest cmdlet with a stateful web service, such as Facebook.

 
The first command uses the Invoke-WebRequest cmdlet to send a sign-in request. The command specifies a value of "fb" for the value of the SessionVariable parameter, and saves the result in the $r variable.
When the command completes, the $r variable contains an HtmlWebResponseObject and the $fb variable contains a WebRequestSession object.

$r=Invoke-WebRequest http://www.facebook.com/login.php -SessionVariable fb
 
The second command shows the WebRequestSession object in the $fb variable.

$fb
 
The third command gets the first form in the Forms property of the HTTP response object in the $r variable, and saves it in the $form variable.

$form = $r.Forms[0]
 
The fourth command pipes the properties of the form in the $form variable into a list by using the Format-List cmdlet.

$form | Format-List
 
The fifth command displays the keys and values in the hash table (dictionary) object in the Fields property of the form.

$form.fields
 
The sixth and seventh commands populate the values of the "email" and "pass" keys of the hash table in the Fields property of the form. You can replace the email and password with values that you want to use.

$form.Fields["email"]="User01@Fabrikam.com"
$form.Fields["pass"]="P@ssw0rd"
 
The eighth command uses the Invoke-WebRequest cmdlet to sign into the Facebook web service.
The value of the Uri parameter is the value of the Action property of the form. The WebRequestSession object in the $fb variable (the session variable specified in the first command) is now the value of the WebSession parameter. The value of the Body parameter is the hash table in the Fields property of the form and the value of the Method parameter is POST. The command saves the output in the $r variable.

$r=Invoke-WebRequest -Uri ("https://www.facebook.com" + $form.Action) -WebSession $fb -Method POST -Body $form.Fields
 
The full script, then, is as follows.

# Sends a sign-in request by running the Invoke-WebRequest cmdlet. The command specifies a value of "fb" for the SessionVariable parameter, and saves the results in the $r variable.

$r=Invoke-WebRequest http://www.facebook.com/login.php -SessionVariable fb

# Use the session variable that you created in Example 1. Output displays values for Headers, Cookies, Credentials, etc.

$fb

# Gets the first form in the Forms property of the HTTP response object in the $r variable, and saves it in the $form variable.

$form = $r.Forms[0]

# Pipes the form properties that are stored in the $forms variable into the Format-List cmdlet, to display those properties in a list.

$form | Format-List

# Displays the keys and values in the hash table (dictionary) object in the Fields property of the form.

$form.fields

# The next two commands populate the values of the "email" and "pass" keys of the hash table in the Fields property of the form. Of course, you can replace the email and password with values that you want to use.

$form.Fields["email"] = "User01@Fabrikam.com"
$form.Fields["pass"] = "P@ssw0rd"

# The final command uses the Invoke-WebRequest cmdlet to sign in to the Facebook web service.

$r=Invoke-WebRequest -Uri ("https://www.facebook.com" + $form.Action) -WebSession $fb -Method POST -Body $form.Fields
 
When the command finishes, the StatusDescription property of the web response object in the $r variable indicates that the user is signed in successfully.

$r.StatusDescription
0
Leon TaljaardSystem Center Specialist - ArchitectureAuthor Commented:
The solution works well, I still don't know how it functions when running against my multiple servers as required but its a step in the right direction.

Thanks
0
Nadav SolomonCommented:
Thanks for the feedback, still check out invoke-webrequest might be more appropriate then opening 100+ IE (unless you'll do it in one serial script)
0
Leon TaljaardSystem Center Specialist - ArchitectureAuthor Commented:
Hi Nadav,

Thank you for the extra info, i know within PS the Invoke-WebRequest will keep the session open but this is not the case when using the Invoke-WebRequest activity within Orchestrator.

Thanks again for all the help
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.