Leo Torres
asked on
Powershell need to find this value
OK, I need to find "Run by:" on web page so I need to if it exists return "Run by:" or True.
right now it returns blank or false because it cant find value on page and value does exists on page.
or here is some sample code
$RunByTest = $ie.Document.getElementsByTagName("span") | ? { $_.InnerText -like 'Run by:*' } | select -First 1 -expandProperty classname
right now it returns blank or false because it cant find value on page and value does exists on page.
or here is some sample code
<table style="border-collapse:collapse;width:100%;" class="table" cellpadding="0" cellspacing="0"><tr class="tableRow"><td class="reportTitle"><span class="textItem">Daily Employee Overtime Report</span></td></tr></table></div><table style="border-collapse:collapse;width:100%;" class="table" cellpadding="0" cellspacing="0"><tr class="tableRow"><td class="tableCell"><table style="border-collapse:collapse;width:100%;" class="reportSubtitle" cellpadding="0" cellspacing="0"><tr class="tableRow"><td class="tableCell"><span class="textItem">Run by:</span></td><td class="tableCell"><span class="textItem">WORKBRAIN</span></td></tr></table></td><td class="tableCell"><table style="border-collapse:collapse;width:100%;" class="reportSubtitle" cellpadding="0" cellspacing="0"><tr class="tableRow">
ASKER
I have never used item object. Not sure how that link helps sorry I am still very green on powershell
How do i Even get my result in the item object?
How do i Even get my result in the item object?
Well, XPath is just another access method for web content, and Invoke-WebRequest just simplifies the access to a page in IE. Both doesn't change the need of knowledge for the internals of the web page to parse, though the path to get there is different.
Up to now (viewing the questions posted prior) using $ie wasn't hitting a road block, and so I would stay with it. Invoke-WebRequest however is worth it to use - if you are on PS 3 or later, as it waits for the web page to be built completely before returning, sparing you some code lines for waiting.
Up to now (viewing the questions posted prior) using $ie wasn't hitting a road block, and so I would stay with it. Invoke-WebRequest however is worth it to use - if you are on PS 3 or later, as it waits for the web page to be built completely before returning, sparing you some code lines for waiting.
Your code line should give you the string "textItem", as that is the class name of the table cell containing "Run by:". Doesn't make much sense that way, you only want to check existence, so this would be better:
@($ie.Document.getElementsByTagName("span") | ? { $_.InnerText -like 'Run by:*' }).Count -gt 0
But, using "span" as filter tag is clumsy, and should only be used if the page does not contain many "span" entries. On the other hand the HTML snippet does not provide unique tags to search for, and that means you might have no better means.
ASKER
Your Code suggestion above is not returning a value. See line 57 below.
Just so you understand the Run By: string tells me that the page loaded correctly by Automated user and that the page works.
Else I set integer set to -200 and collect the error string from page and I will store values into array and display array as report so see what Links are down. Just so you have an over view.
Add-Type -Path "C:\Windows\System32\WindowsPowerShell\v1.0\Modules\HtmlAgilityPack.1.4.6\Net45\HtmlAgilityPack.dll"
CLS
$url = "https://yazaki.company.com"
#$url = "https://psecu.company.com"
#$url = "https://quickenloans.company.com"
$ie = New-Object -comobject InternetExplorer.Application
$ie.visible = $true
$ie.silent = $true
$ie.Navigate( $url )
while($ie.busy){Start-Sleep 1}
Start-Sleep -s 5
#$ie.Document.getElementsByTagName("span") | ft -a classname, tagname, innerText
$ie.Document.getElementsByTagName("input") | ? { $_.Id -eq 'loginField' } | % { $_.value = "User" }
$ie.Document.getElementsByTagName("input") | ? { $_.Id -eq 'passwordField' } | % { $_.value = "pass" }
$ie.Document.getElementsByTagName("button") | ? { $_.Type -eq 'button' } | % { $_.Click() }
$ReportPart = "/interface/folderTree.jsp?rootId=216&expandLevel=1&clearUIPath=true&uiPathLabel=Reports"
$ReportLink = $url + $ReportPart
$ie.navigate($ReportLink)
#$ie.Document.getElementsByTagName("a") | ft -a classname, tagname, innerText
Start-Sleep -s 5
$link = $ie.Document.getElementsByTagName("a") | ? { $_.InnerText -like '*Overtime Report' } | select -First 1 -expandProperty href
if($link) {
$link = $link
}
else {
$link = $ie.Document.getElementsByTagName("a") | ? { $_.InnerText -like '*Count' } | select -First 1 -expandProperty href
}
$ie.navigate($link)
Start-Sleep -s 5
$ie.Document.getElementsByTagName("a") | ft -a classname, tagname, innerText
$ie.Document.getElementsByTagName("button") | ? { $_.innerText -eq 'Go' } | % { $_.Click() }
Start-Sleep -s 25
$ie.Document.getElementsByTagName("span") | ft -a classname, tagname, innerText #Gets you error
#$ie.Document.getElementsByTagName("span") | select className
#$RunByTest = $ie.Document.getElementsByTagName("span") | ? { $_.InnerText -like 'Run by:*' } | select -First 1 -expandProperty innerText
#$RunByTest = $ie.Document.getElementsByTagName("span") | ? { $_.InnerText -like 'Run*' } | % select -First 1 -expandProperty classname
$RunByTest = @($ie.Document.getElementsByTagName("span") | ? { $_.InnerText -like 'Run by:*' }).Count -gt 0
if($RunByTest) {
$TestValue = 200
}
else {
$TestValue = -200
}
Write-Host $TestValue
Just so you understand the Run By: string tells me that the page loaded correctly by Automated user and that the page works.
Else I set integer set to -200 and collect the error string from page and I will store values into array and display array as report so see what Links are down. Just so you have an over view.
Here's a quick breakdown of what I was referring to in: stackoverflow.com/question s/20334928 /issue-par sing-html- using-powe rshell-and -xpath
It looks very similar to what you're trying to accomplish. This is the same way I parsed HTML for a Dell Service Tag look-up for Warranty information and thought it would lead you down the path to success.
$url = 'http://www.example.com/path/to/some.html'
$html = (Invoke-Webrequest $url).ParsedHTML
$html.getElementsByTagName('p') | ? { $_.className -eq 'row' } | % {
$ID = $_.getAttributeNode('data-pid').value
$Date = $_.getElementsByTagName('span') | ? { $_.className -eq 'date' } |
% { $_.innerText }
# do stuff with $ID and $Date
"{0}: {1}" -f $ID, $Date
}
It looks very similar to what you're trying to accomplish. This is the same way I parsed HTML for a Dell Service Tag look-up for Warranty information and thought it would lead you down the path to success.
ASKER
OK, looks promising but as the code above shows when I am looking for Run by: string I dont know the site url is. I land on this page after a series of button clicks. Unless I can grab it from $ie object I don't know what it is.
As said, you can interchange (Invoke-WebRequest $url).ParseHTML and $ie.Navigate($url); <# wait until ready #> $ie.Document arbitrarily. It doesn't change anything.
If line 52 throws out something useful, line 57 should be valid. Only reasons I can see for not working is
a) the page is still not ready to full extend
b) the search string is incorrect.
The comment in line 52 is "Gets you error" - does that mean it displays the error, if the page is not working (at all) and hence the condition to check for, or is there an error when trying to execute that line?
If line 52 throws out something useful, line 57 should be valid. Only reasons I can see for not working is
a) the page is still not ready to full extend
b) the search string is incorrect.
The comment in line 52 is "Gets you error" - does that mean it displays the error, if the page is not working (at all) and hence the condition to check for, or is there an error when trying to execute that line?
ASKER
You would think that your last statement would be true but its not. If page errors out I got the Error text on that span I noticed this by mistake when page errored I got page error in that Item. How ever when page was successful that line returns NULL. As far as time goes if you notice I am waiting 25 seconds to make sure report is ready for scan.
I have attached a copy of html Page that is displayed when successful and a page with a failure so you can see the differences.
Html-Test.txt
Html-Test-error.txt
I have attached a copy of html Page that is displayed when successful and a page with a failure so you can see the differences.
Html-Test.txt
Html-Test-error.txt
Sorry having to say that, but Html-Test.txt results in $true with
@($ie.Document.getElementsByTagName("span") | ? { $_.InnerText -like 'Run by:*' }).Count -gt 0
The error page does not.
ASKER
(received real-life URL and credentials)
The issue is that we have a frameset consisting of two frames, of which the second contains the string we search for. I can get to the frame, but not further, with
But you should be able to post that HTML code of the report here, maybe with some obfuscation in regard of names and URLs.
The issue is that we have a frameset consisting of two frames, of which the second contains the string we search for. I can get to the frame, but not further, with
$ie.Document.body.childnodes.item(1)
and have to give up here.But you should be able to post that HTML code of the report here, maybe with some obfuscation in regard of names and URLs.
ASKER
Qlemo, where did you place the code line you specified above.
Just curious in terms of array wouldn't 1 be in the second array. If array is ie.. 0,1,2,3...
Aren't you in the right Frame with item(1)?
Just curious in terms of array wouldn't 1 be in the second array. If array is ie.. 0,1,2,3...
Aren't you in the right Frame with item(1)?
That line is executed at about line 52 of http:#a40252055 (and instead of all following lines).
And yes, we are in the second array element (second frame). The first contains some "header" stuff, the second the report data.
And yes, we are in the second array element (second frame). The first contains some "header" stuff, the second the report data.
ASKER
Oh FYI
The HTML of the report is already here its post ID 40254089
https://www.experts-exchange.com/questions/28494276/Powershell-need-to-find-this-value.html?anchorAnswerId=40254089#a40254089
You said you got success? I dont understand when you did real test thru web and could not produce same result. On the file you said you got true.
The HTML of the report is already here its post ID 40254089
https://www.experts-exchange.com/questions/28494276/Powershell-need-to-find-this-value.html?anchorAnswerId=40254089#a40254089
You said you got success? I dont understand when you did real test thru web and could not produce same result. On the file you said you got true.
No, it is not. Search in the HTML you posted for "frameset" and you won't find anything. The live code of the report result is completely different, at least for me. I got the report, and it immediately starts with a frameset, while the code you posted starts with some scripting code.
ASKER
You know I am looking for the Run By: string for confirmation that report has ran. May be we could look for something else that would help me make that same determination. For example 2 Framesets I didnt see that in error HTML. Even something Unique in the header that would give the indication that report has ran successfully.
Your thoughts for alternatives are welcome.
Your thoughts for alternatives are welcome.
That should be feasible and easier to achieve. You can check for the classname (or is it type?) of $ie.Document.body, which needs to be "frameset" for success.
But what to do after that? Calling the report without storing the results does not make sense to me.
But what to do after that? Calling the report without storing the results does not make sense to me.
ASKER
I dont what to see report results. That's not my objective.
We have 272 of these pages and every Saturday night Sunday Morning these servers have updates and reboots done. We need to test sites manually at this point. This process you see the code doing is being done Site by Site by a human 272 sites all the way down to the report. All the tester does is verify that they can run the report. If the report runs then the site is up and functional and they move on to next site to test. We need to know site is down before the client finds out and going thru 272 sites really delays finds bad sites.
That True/false number will be passed thru more code to display which site is up and what sites are down.
This is the objective of this code. Report result are irrelevant and done me anything to me.
Hope this help you understand the code and what I need to accomplish better.
We have 272 of these pages and every Saturday night Sunday Morning these servers have updates and reboots done. We need to test sites manually at this point. This process you see the code doing is being done Site by Site by a human 272 sites all the way down to the report. All the tester does is verify that they can run the report. If the report runs then the site is up and functional and they move on to next site to test. We need to know site is down before the client finds out and going thru 272 sites really delays finds bad sites.
That True/false number will be passed thru more code to display which site is up and what sites are down.
This is the objective of this code. Report result are irrelevant and done me anything to me.
Hope this help you understand the code and what I need to accomplish better.
Got it. For making the tests robust, it would be good to know if you only need to change the URL for each site, or there is more. It would be tedious to implement 272 ways to test each site individually ;-).
But since you provided three URLs, I will check myself with those.
BTW, in http:#a40252055 you import the HTML Agility Pack, but we are not using any feature of it. I will take the liberty and simplify the code, removing all the test stuff, and making it suitable for testing that lot of sites.
But since you provided three URLs, I will check myself with those.
BTW, in http:#a40252055 you import the HTML Agility Pack, but we are not using any feature of it. I will take the liberty and simplify the code, removing all the test stuff, and making it suitable for testing that lot of sites.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Changed:
Write-Host "$URL: $TestValue"
to
Write-Host "URL: $TestValue"
it was causing an error.
OK where do I save this function so i can call it from any ISE window or any command line at anytime.
This looks promising.
Write-Host "$URL: $TestValue"
to
Write-Host "URL: $TestValue"
it was causing an error.
OK where do I save this function so i can call it from any ISE window or any command line at anytime.
This looks promising.
Sorry for that. The colon has a special meaning ("drive" resp. "provider"). My intention was to use Write_host "$URL`: $TestValue", so you can see each URL with the result (instead of only results).
You can put that directly into ISE, storing it to your favourite location. If you do as I did, function and calling code are in the same script, and you do not need to consider anything.
However, if you want to have the function in an own script, and then be able to call it from comand line, you can store it into (again) an arbitrary location (script name does not matter either), together with the preceeding code. Then import the script via dot operator, e.g.
. C:\Scripts\FunctionForTest ing.ps1
Doing that once will keep anything defined available in the current shell; would you just call the script without the dot operator, no vars and other definitions should be available outside of the script.
You can put that directly into ISE, storing it to your favourite location. If you do as I did, function and calling code are in the same script, and you do not need to consider anything.
However, if you want to have the function in an own script, and then be able to call it from comand line, you can store it into (again) an arbitrary location (script name does not matter either), together with the preceeding code. Then import the script via dot operator, e.g.
. C:\Scripts\FunctionForTest
Doing that once will keep anything defined available in the current shell; would you just call the script without the dot operator, no vars and other definitions should be available outside of the script.
ASKER
This looks like it works but I cant see the process in IE. I need to see it to validate.
I opened new question here.
https://www.experts-exchange.com/questions/28499027/Powershell-click-button-on-page-and-watch-as-it-processes.html
I opened new question here.
https://www.experts-exchange.com/questions/28499027/Powershell-click-button-on-page-and-watch-as-it-processes.html
stackoverflow.com/question