debugging powershell login webpage script - powershell

I have this poweshell script - which opens up the webpage - however the idea is that it would log into the page. It pulls up the page ok, but does not put anything in the login/password box. I got the getelementbyid'd from google chrome tools.
Do you have any idea on how to troubleshoot this script. Like in perl or bash I can put in echo statements. i can use set -x to check the output. I want to see it the script is entering in the login and password.
param
(
[parameter(Mandatory=$true)]
[ValidateNotNull()]
$ID
)
$username = "casper"
$password = "passworD"
$ie = New-Object -com InternetExplorer.Application
$ie.visible=$false
$ie.navigate("http://casperweb.stm.swissbank.com:8080/cds/marketAccessAcctLimits.jsp?Term=$ID")
while($ie.ReadyState -ne 4) {start-sleep -m 1}
$ie.Document.getElementById("userName").value= "$username"
$ie.Document.getElementById("password").value = "$password"
$ie.Document.getElementById("submitButton").Click()
start-sleep 20
$ie.Document.body | Out-File -FilePath c:\UBS\DEV\web.txt

Are you getting a specific error message? Without being able to access your page it's difficult to determine if the element id is correct. Your code and post prompted me to try something similar and I only saw the issue you described when I wasn't entering the correct element id of the fields I was trying to populate.
I found the below articles helpful for inspecting the element and getting the correct ID.
http://kb.oboxthemes.com/articles/how-to-get-css-styles-for-elements/
https://stackoverflow.com/a/9435732/5587481
I'm not an expert at this in any way so hopefully I understand the issue at hand correctly here :)

Related

Powershell to click on 'ok' to delete an SP site

I am trying to create a script to delete old MOSS 2007 personal sites. I have most of the script working, but where I am having trouble is once a box pops up, to have it click 'Ok'. The script locates the URL, and clicks on 'delete', but then a box pops to confirm deletion and the options are 'Ok' and 'cancel'. I want the script to click on 'ok'. I've done some research on the sendkey methods, but since I'm not well versed in PS, I'm unable to get it to work. Also, please don't suggest using the SP cmds. We have MOSS 2007 running on 2003 servers, so any SP cmds or trying to run the script from the server is a moot point.
Please take a look at my script below.
[void]
[System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[void]
[System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
$user = "username"
$mysiteURL = "http://SharePointSite/personal/$user/_layouts/deleteweb.aspx"
Invoke-WebRequest -UseDefaultCredentials -uri $mysiteURL | Select-Object statusdescription
#Creates an Internet Explorer object
$ie = New-Object -ComObject 'internetExplorer.Application'
$ie.Visible= $true
$ie.Navigate($mysiteURL)
while ($ie.Busy -eq $true){Start-Sleep 4;}
$ie.Document.getElementByID('ctl00_PlaceHolderMain_ctl08_RptControls_BtnDelete').click()
#give the focus to ie
[Microsoft.VisualBasic.Interaction]::AppActivate("Message from webpage")
#send keys
start-sleep 1
[System.Windows.Forms.SendKeys]::Sendwait("{ENTER}");
Any help would be appreciated. Thank you!

PowerShell script to log in to Linkedin

Fairly new to PowerShell and exploring its capabilities. I have created the following script to automatically log in to LinkedIn, but it opens the web page and does nothing else, can some please assist? I wish to use the script to log in to a web status page and search for issues for alerting purposes, thank you.
PowerShell Script
$username = "Username"
$password = "Password"
$ie = New-Object -com InternetExplorer.Application
$ie.visible=$true
$ie.navigate("https://www.linkedin.com")
while($ie.ReadyState -ne 4) {start-sleep -m 100}
$usernameElement = $ie.document.getElementById("login-email").value= "$username"
$ie.document.getElementById("login-password").value = "$password"
$ie.document.getElementById("login-submit").submit()
start-sleep 20
OK, took me a while, but I figured out the issue. On LinkedIn specifically, the login-submit button has two notable properties: isDisabled and disabled. Those need to be both changed to $true before it can be clicked. Also, change the function called on it from .submit() to .click(). Also, a quick tip: After the script is done (I'm not sure if this is still true, because you seem to manually close it afterwards), $ie is kept under your script's management. To release it, call this command (after you manually close it, so it might be hard to get in there):
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie) #>
Not really sure why, I just know it keeps it out of the way and is apparently equivalent to killing it from the task manager.

Using IE automation in powershell to login to a website that has input validation

I am trying to use PowerShell to login to a website. In the example below I am trying to login to live.com.
I am able to update the username field but the webpage runs some sort of input validation that does not accept my value. If I manually go in and edit the username field, like hitting space and then backspace, the input is then valid.
I found some documentation about changing the focus or using fireevent, but neither seems to work.
While sendkeys would resolve my issue, I have had numerous problems with sendkeys before and would really like to avoid going down that path.
$Site = 'https://login.live.com'
$UserName = 'FakeUserName#outlook.com'
$ie = New-Object -ComObject 'internetExplorer.Application'
$ie.Visible= $true
$ie.Navigate($Site)
while ($IE.busy)
{
Start-Sleep -Milliseconds 100
}
$Inputs = $IE.document.getElementsByTagName("input")
foreach ($Input in $Inputs)
{
if ($Input.type -eq "email")
{
$UserIDField = $Input
}
if ($Input.type -eq "submit")
{
$LoginButton = $Input
}
}
$UserIDField.focus()
$UserIDField.value = $UserName
$UserIDField.FireEvent('onchange')
$LoginButton.focus()
$LoginButton.click()
#Ranadip Dutta is certainly true, you should not, do that this way, but if you want to automate web browser Selenium is a good tool, here it tooks five minutes to automate Chrome on your web site. You can chooe an IE driver,Mozilla or Opera. for that have a look to Selenium.
# Selenium directory is the place where I expand Selenium Client & WebDriver Language Bindings for C#
$seleniumDir = 'D:\Developpements\Pgdvlp_PowerShell\selenium-dotnet-3.0.0'
# Selenium Webdriver
Add-Type -Path "$seleniumDir\net40\WebDriver.dll"
Add-Type -Path "$seleniumDir\net40\WebDriver.Support.dll"
Add-Type -Path "$seleniumDir\net40\ThoughtWorks.Selenium.Core.dll"
Add-Type -Path "$seleniumDir\net40\Selenium.WebDriverBackedSelenium.dll"
# With Chrome
# I Download Chrome driver here : https://chromedriver.storage.googleapis.com/index.html?path=2.25/
# It stands in "$seleniumDir" drive
$chrome = New-Object OpenQA.Selenium.Chrome.ChromeDriver "$seleniumDir"
#$chrome.Navigate().GoToUrl("https://fr.hightail.com/loginSpaces?redirect_url=https%3A%2F%2Fspaces.hightail.com%2Foauth%2Fhightail");
$chrome.Navigate().GoToUrl("https://login.live.com");
$Browser = $chrome
$email = $Browser.FindElements([OpenQA.Selenium.By]::Name('loginfmt'))
$email[0].SendKeys("adress#hotmail.com")
$button = $Browser.FindElements([OpenQA.Selenium.By]::Id('idSIButton9'))
$button.Click()
Start-Sleep 2
$passwd = $Browser.FindElements([OpenQA.Selenium.By]::Name('passwd'))
$passwd[0].SendKeys("toto")
$button = $Browser.FindElements([OpenQA.Selenium.By]::Id('idSIButton9'))
$button.Click()
If your website is checking for automated login then how can you expect it to be automated in this way. Sendkeys actually send like user input which is similar to what user does and thereby sorts your problem in that case.
I would like you to see if there is any API available for the web service to get logged in.
Other than that, I do not see anything which can help you. This concern is not about powershell or any scripting language. It is pretty much generic for your website.
You may also want to consider passing stored credentials more securely instead of putting your creds in full view plain text within your script(s).
TechNet - PowerShell Tip - Storing and Using Password Credentials

Prevent PowerShell script from being read

I have the below PowerShell script (myscript.ps1) in which I ask for username and password. Depending on the username and password it copies a file to a certain destination.
$credentials = Get-Credential
if ($credentials.Username -eq "user1" -And $credentials.GetNetworkCredential().password -eq "pass1")
{ Copy-Item "test1.pdf" "\test\test1.pdf"; }
else
{ Copy-Item "test2.pdf" "\test\test2.pdf"; }
Requirement: I want to make this file protected so no one can edit it and see the username and password.
PS2EXE
I found a solution found here which converts the PowerShell script to an .exe file. When I originally run the script using PowerShell a dialog box appears allowing me to enter the username and password:
After the .exe is generated and when I run it the credentials dialog box no longer appears. Instead, the console appears saying "Credential:"
I don't know why? I want the credentials form to still appear when running the exe. Any thoughts please?
Q: Why does the EXE prompt with "Credential"?
This isn't an answer to the real question, and is based on guessing/supposition about PS2EXE, but I hope it is useful to clear up some confusion.
Having looked briefly at the PS2EXE page linked above, it seems that this utility encodes the script in Base64 and bundles it with a lightweight (?) custom PowerShell host. When run, I suppose the EXE starts the host, decodes the script and runs it.
The problem is that the Get-Credential cmdlet is running within a PS host that probably can't interact with the desktop. That is, it can't put up the GUI prompt for credentials. It therefore needs to prompt for the Credential property on the command line, explaining why you see that behaviour.
Workaround with Read-Host?
Instead of trying to use Get-Credential to prompt for username and password, you could embrace what PS2EXE seems to be doing and just use Read-Host:
$UserName = Read-Host "Enter username"
$Password = Read-Host "Enter password" -AsSecureString
$Credentials = New-Object System.Management.Automation.PSCredential $UserName,$Password
if ($credentials.Username -eq "user1" -And $credentials.GetNetworkCredential().password -eq "pass1")
{ ... }
Using -AsSecureString will hide the password on the screen. The $Password variable will be of type System.Security.SecureString, which can be used to create a PSCredential object as shown.
You'd need to test this, but it seems that you're able to read from the shell but not from a GUI prompt.
And just to be clear: none of this is anywhere near best-practice security. If you need authentication/authorization for these activities, step back and look at the problem again.
Workaround with two scripts?
It seems that PS2EXE doesn't support -AsSecureString in the same way that normal PowerShell does, i.e. it doesn't hide the characters. A possible workaround for this would be to collect the username and password from the user in one script and then pass them to a PS2EXE-converted script for processing.
Launch-MyScript.ps1:
$Credentials = Get-Credential
& MyScript.exe $Credentials.Username $Credentials.Password
MyScript.exe (coverted with PS2EXE):
param($Username,$Password)
$Credentials = New-Object System.Management.Automation.PSCredential $Username,$Password
if ($Credentials.Username -eq "user1" -and
$Credentials.GetNetworkCredential().password -eq "pass1")
{
...
}
The user runs Launch-MyScript.ps1 and completes the password prompt. Then the EXE is run automatically with the username and password passed in as arguments. Note that, as shown above, the password is a Secure String. Test this; I'm not using PS2EXE so it's a theoretical solution at the moment.
If you can't pass $Password along the pipeline as a Secure String object, you can convert it to text with ConvertFrom-SecureString in the first script, then conver it back with ConvertTo-SecureString in the second one.
According to this article http://windowsitpro.com/powershell/protect-your-powershell-scripts you should first set ur execution policy to AllSigned by Set-ExecutionPolicy AllSigned, then create a certificate using makecert cmdlet.
Then u can sign single script using Set-AuthenticodeSignature cmdlet or use .pfx File to Sign a Script which appears even safer.
Hope it helps a bit.

Powershell Web Page Automation works on Internet, not Intranet

I'm trying to do some simple automation with Powershell, pulling link URLs from one of our company's local intranet pages, and then doing some work with those URLs. Eventually I'll use the script to open each link and click a button on the page. I'm using Internet Explorer 9 in Windows 7 x64.
Here's an example of a simple working powershell script that displays all the links on a page:
$ie = new-object -com "InternetExplorer.Application"
$ie.Visible = $true
$ie.Navigate( "http://www.reddit.com" )
While ($ie.Busy) {
Sleep 1
}
$links = $ie.Document.getElementsByTagName("a")
$links | foreach {
write-host $_.href
}
This script works fine until I replace the URL with a local intranet site. It follows the normal URL scheme ( http://internaldomain.com/etc ), but it's recognized as an intranet site. Once I'm trying to scrape a page in the intranet zone, the $ie.Document value suddenly becomes NULL and the script fails.
I'm guessing it's related to some obscure setting for that zone... I'm not sure. I found some suggestions online such as adding it to your trusted sites, but that has not worked. This is my first time using Powershell for web automation, so any help or insight would be appreciated.
Maybe the solution is here: http://blogs.msdn.com/b/ieinternals/archive/2011/08/03/internet-explorer-automation-protected-mode-lcie-default-integrity-level-medium.aspx
It explained the different levels of tabs, in ie. You have to use the "medium tab" to navigate in local zone.
Basically, the best way to keep your ie settings and use your script is to create a registry key, as explained in the link above.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\InternetExplorer.ApplicationMedium]
[HKEY_CLASSES_ROOT\InternetExplorer.ApplicationMedium\CLSID]
#="{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}"
And in your script, use this new com object:
$ie = new-object -Com InternetExplorer.ApplicationMedium
...
Due to policy restrictions on my computer, I was not able to access the registry to create the key mentioned in another answer. However, I did find a way to do it indirectly using PowerShell in case this is helpful to anyone else:
$type = [Type]::GetTypeFromCLSID('D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E')
$ie = [System.Activator]::CreateInstance($Type)
$ie.Visible = $true
$URL = "http://my.intranet.com"
$ie.Navigate($URL)
Write-Host "`$ie.Busy:" $ie.Busy
Write-Host "`$ie.ReadyState:" $ie.ReadyState
while($ie.Busy -or ($ie.ReadyState -ne 4) ) {
Start-Sleep -s 1
}
Write-Host "IE is ready"
Use
$ie.Document.documentElement.getElementsByClassName("underline")
and enjoy .....