0

I'm trying to fill out some text input/drop-down boxes in IE with a PowerShell (PoSH) script, and I've been using examples provided on the Internet, including here, and here.

However, I haven't been able to get or identify the text boxes via GetElementsByTagName() - I think it acts like they're not populating in the variable. I'm not sure what's going on, I've been looking around on the internet (Google searches), but haven't seen anything that says there's more to it than just these few lines of code.

Code and pictures, as well as error to follow:

$url = "[webPage]";

#initialize browser
$ie = New-Object -Com InternetExplorer.Application;
$ie.Visible = $true;
$ie.ParsedHTML;
$ie.Navigate($url);
while ($ie.busy) {Start-Sleep 4}

#get form
$doc = $ie.Document;
$form =  $doc.Forms[0];
$inputs = $form.GetElementsByTagName("input");

#fill out form fields
#either this: 
$ie.Document.GetElementByID("sys_display.IO:69c7ac57db7f7a00d7efb96c4e9619ae").Value = "Jonathan Rotter"
#or this:
($inputs | where {$_.Name -eq "sys_display.IO:69c7ac57db7f7a00d7efb96c4e9619ae"}).Value = "Test"

I've tried adding the following to the top of this (from here), but no change:

[void][System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")

I can see the ID/Name/(Tag-Name??) in the page:

InputField

I've entered the PoSH script line-by-line (to make sure the web-page loaded properly) and checked on the output, and (as an example), the following line results in this error message:

($inputs | where {$_.Name -eq "sys_display.IO:69c7ac57db7f7a00d7efb96c4e9619ae"}).Value = "Test"


The property 'value' cannot be found on this object. Verify that the
property exists and can be set. At line:1 char:1
+ ($inputs | where {$_.name -eq "sys_display.IO:69c7ac57db7f7a00d7efb96 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound

After running all the steps, these two lines show the following:

PS> $inputs | Select-Object Type,Name
type   name
----   ----
hidden sysparm_ck 
search sysparm_search

PS> $doc.IHTMLDocument3_getElementsByTagName("input") | Select-Object Type,Name
type     name
----     ----
hidden   sysparm_ck
search   sysparm_search
checkbox 843.8919931998148glide_ui_accessibility
checkbox 265.6701858983173glide_ui_compact
checkbox 689.5920854347255glide_ui_short_date_format
radio    884.3975056898055my_home_navigation_page
radio    884.3975056898055my_home_navigation_page
radio    38.12548394764709glide_ui_date_format
radio    38.12548394764709glide_ui_date_format
radio    38.12548394764709glide_ui_date_format
radio    theme
radio    theme
radio    theme
radio    theme
radio    theme
radio    theme
radio    theme
radio    theme
checkbox 246.5551307536581table_wrap
checkbox 498.31620519246865tabbed_forms
radio    436.6892116346038glide_ui_related_list_t...
radio    436.6892116346038glide_ui_related_list_t...
radio    436.6892116346038glide_ui_related_list_t...
checkbox 693.6896755526656connect_notifications_m...
checkbox 68.17405211392419connect_notifications_d...
checkbox 958.4840125981943connect_notifications_e...
checkbox 276.20029685304047connect_notifications_...
hidden   sysparm_ck
search   filter
search   leftSearch
search

Please help point me somewhere for a next step, I'm not sure what I'm missing.

Edit 20181218 It looks like the fields I need are inside an "iframe." I'm still struggling with drilling down into it with code, and have been playing with this line found Here, but I'm still not sure how to get to it (adjusted for my web-page with the above code):

$form=$doc.frames.document.forms

Gives me more stuff to look at, but this errors changed this:

PS U:\> $ie.document.getElementByID("gsft_main")
Exception from HRESULT: 0x800A01B6

To this and looking some more:

$frame=$ie.document.IHTMLDocument3_getElementByID("gsft_main")

Images from inspection (F11):

iframe1 iframe2

JGR
  • 171
  • 1
  • 15
  • 1
    I have recently struggled with this as well. I had better luck using something like `$doc.querySelectorAll('input[id="..."]')`. But it seems to depend on the website or something. – mhhollomon Dec 14 '18 at 20:08
  • Thank you, @mhhollomon. There's a few things here now to look at. Still not having a ton of luck. On a side note: I installed "RoboForm" and it seems to find the fields every time (I just don't want to use it long-term, because of app policies); the field names that RoboForm find don't work in my PoSH script. – JGR Dec 17 '18 at 18:28

2 Answers2

2

You do not show the target URL, why? IS this an internal site, hence the sanitation?

You can walk the form fields directly using, say this approach...

$w = Invoke-WebRequest -Uri 'Some url'
$w.StatusCode
$w.AllElements
$w.Links
$w.Forms
$w.Forms[0].Fields
$w.RawContent
$w.ParsedHtml

Then once you have that, you can do your remaining use case.

postanote
  • 15,138
  • 2
  • 14
  • 25
  • postanote: yes, it's an internal form (requires login), so the URL (and much of the webpage) is edited out. Than you for the response, I'm looking at these. – JGR Dec 17 '18 at 16:47
  • So, I ran a few of these, @postanote, and noticed that an IE page loads to a "home" page (instead of the form webpage) after I try to get some aspect of $w. For example, I run the first line with the catalog view in the URL (my form page), and if I run "$w" or "$w.Forms" it opens IE with the main "Navigation" (home) page, and I can find values on this page (the home page) in my PoSH output. Does this mean I need to do an extra step, or do commands in a single line? I don't understand it. – JGR Dec 17 '18 at 19:32
  • 1
    Anytime you have these multipage deployments, yep, you are going to have to address that directly in code. Many public sites have this sort of this as well. So, each page must be navigated. I run into this sort of thing regularly at customer sites and more often on other sites as well, example aircanada.com was a real challenge to deal with. Try working with form enum, meaning, $w.Form, $w.Forms[0], $w.Forms[1], etc... to see where that lands you. – postanote Dec 17 '18 at 20:48
  • Thank you, @postanote - I'm still not having much luck, and I think it's trying to do a redirect as soon as I ask for an element (??) of the webpage URI/URL. If I open a new IE and browse to it, or invoke it, it seems to pull the page I ask for, but then asking for $w.Forms (or enum), it looks like it maybe redirects and grabs the home page. Maybe I'm activating a button/link when I do that?? – JGR Dec 18 '18 at 14:36
  • I tried the following with the following result - it seems like the redirect is messing me up here, maybe there's a way of grabbing the information without invoking the re-direct? `PS U:\> $w = Invoke-WebRequest -URI "https://*******.service-now.***/nav_to.do?uri=%2Fcom.glideapp.servicecatalog_cat_item_view.do%3Fv%3D1%26sysparm_id***...***catalog_default" -MaximumRedirection 0 Invoke-WebRequest : The maximum redirection count has been exceeded. To increase the number of redirections allowed,supply a higher value to the -MaximumRedirection parameter.` – JGR Dec 18 '18 at 15:51
  • I edited my original post - it looks like there's an iframe that I might have to dig into (??). I'm still working on it, I think I'm making progress. – JGR Dec 18 '18 at 20:38
  • I had to dig through the fields a lot more, discovering the IFRAME was a big breakthrough, but wouldn't have been found without digging into it much like what you suggested and doing a lot of Google searches. Thank you for the answer. – JGR Dec 20 '18 at 15:09
1

It looks like whatever backend for this website is dynamically generating these inputs and doesn't assign them a fixed name. Instead of looking directly for the element, I would suggest looking for the Parent Element and then searching for your elements under possible parent matches

So instead of looking for sys_display.IO:69c7ac57db7f7a00d7efb96c4e9619ae you can start by looking for <div class='input-group' and then searching for the <input> then matching the name to sys_display. You can also try and match ac_colums=email and the parent of <div class='input-group' which will help narrow the parameters you need to search.

*Fair warning, I've only done this with Selenium and not IE Webform... If possible, you might need to use XPath searching instead so you can match a Tag/Class/Name at the same time.

Shadowzee
  • 537
  • 3
  • 15
  • Thank you, @Shadowzee, I'll look into this, too – JGR Dec 17 '18 at 16:51
  • 1
    I try to make a test with the power shell script code to enter the value in textbox with the similar id as yours. I find that, If I don't run the script as an administrator than it is not inserting the value. But if I run the script as an administrator than it is adding the value. So I suggest you to make a test on your side and let us know about your testing result. – Deepak-MSFT Dec 18 '18 at 08:07
  • Just wanted to let you know: after digging into it more and doing a lot of "Googling," I've found that it was nested inside an IFRAME and was able to reach it with PoSH. There are some fields that are dynamically _filled in_, but most the form is static (although "hidden", sometimes). Thank you for the answer. – JGR Dec 20 '18 at 15:07