Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # This method will finish an IE download by forcing the 'ALT+S' key several times to ensure that the "Save" button gets
- # hit. It then waits a specified amount of time before returning so that the user can allow the file download to be
- # expected to have finished.
- Function Finish-Download([__ComObject]$ie, [int]$iterations, [int]$sleep) {
- Write-Verbose "Finish-Download: Entered 'Finish-Download ie iterations'"
- Write-Debug "Finish-Download: 'iterations': $iterations"
- Write-Debug ("Finish-Download: 'ie.HWND': " + $ie.HWND)
- Write-Warning "Please do not make any mouse or keyboard interactions for this next step."
- Write-Verbose "Finish-Download: Locating 'ie' process"
- $ieProc = Get-Process | Where-Object { $_.Name -eq "iexplore" -and $_.MainWindowHandle -eq $ie.HWND }
- Write-Verbose "Finish-Download: Attaching 'WScript.Shell' to 'ieProc'"
- Write-Debug ("Finish-Download: 'ieProc.Id': " + $ieProc.Id)
- $wScript = New-Object -ComObject WScript.Shell
- if (-not $wScript.AppActivate($ieProc.Id)) {
- Write-Error "Failed to attach WScript.Shell to appropriate process."
- Return $false
- }
- # For SOME reason, WScript takes a moment to activate the process. So we need to sleep. During this part it's
- # important that you don't make any mouse/keyboard movements.
- # Another hiccup: IE isn't a great browser, as a result sometimes the ALT+S command doesn't work properly, so
- # we're sending it multiple times to make sure that it get's received by Internet Explorer.
- Sleep 1
- Write-Verbose "Finish-Download: Sending 'ALT' then 'ALT+S' $iterations times"
- do {
- Write-Debug "Finish-Download: 'iterations': $iterations"
- $wScript.SendKeys("%")
- $wScript.SendKeys("%S")
- $iterations = $iterations - 1
- } while ($iterations -gt 0)
- # Note: this will save it to the default location. You can mess with WScript if you wish to use the "Save As"
- Sleep 1
- Write-Warning "You may use your mouse and keyboard again."
- Write-Verbose "Finish-Download: Sleep for $sleep seconds to wait for download to complete"
- Sleep $sleep
- }
- # You'll have to mess with a lot of this for your specific web-page layout, but it should be fairly self-explanatory
- Function Download-File([string]$url, [string]$user, [string]$pass) {
- try {
- Write-Verbose "Download-File: Entered 'Download-File url user pass'"
- Write-Debug "Download-File: 'url': $url"
- Write-Debug "Download-File: 'user': $user"
- Write-Debug ("Download-File: 'pass': " + $pass.Length.ToString() + " chars")
- # This is the ID for the login text-box and the password text-box
- $usernameElement = "login_field"
- $passwordElement = "password"
- Write-Verbose "Download-File: Creating 'Wait-NavigationCompleted[__ComObject]'"
- # Define a function to wait for navigation to finishe
- Function Wait-NavigationCompleted([__ComObject]$ie) {
- Write-Verbose "Wait-NavigationCompleted: Waiting for navigation to complete..."
- do {
- Write-Debug ("Wait-NavigationCompleted: 'ie.Busy': " + $ie.Busy)
- sleep 1
- }
- until (-not ($ie.Busy))
- }
- Write-Verbose "Download-File: Creating 'ie' object"
- # Define our IE object
- $ie = New-Object -ComObject InternetExplorer.Application
- # We NEED IE to be visible to download stuff appropriate, since we can't follow a specific URL to get to it. (If it's
- # possible to do so, let me know and I can work up an example of parsing a URL out of the page to get it to be
- # navigateable.)
- $ie.Visible = $true
- Write-Debug ("Download-File: 'ie.Visible': " + $ie.Visible.ToString())
- Write-Verbose "Download-File: Navigate to '$url'"
- # Navigate to the root login page
- $ie.Navigate($url)
- Wait-NavigationCompleted($ie)
- Write-Verbose "Download-File: Creating 'doc' object"
- # Thanks to how programming works, we only need to set $doc once
- $doc = $ie.Document
- try {
- Write-Verbose "Download-File: Attempting to log in."
- Write-Debug "Download-File: 'usernameElement': $usernameElement"
- Write-Debug "Download-File: 'passwordElement': $passwordElement"
- $doc.getElementById($usernameElement).value = $user
- $doc.getElementById($passwordElement).value = $pass
- # Here you can either use:
- # $doc.getElementById("button-id").click()
- # IF it has a valid ID.
- # In the case of the test website I used it doesn't, so we'll iterate all buttons on the page to find one that
- # looks right
- $doc.getElementsByName("commit") | % {
- if ($_.value -eq "Sign in") {
- $_.click()
- }
- }
- Wait-NavigationCompleted($ie)
- } catch {
- Write-Information "Login failed, user likely already logged in."
- }
- Write-Verbose "Download-File: Looking for button to click"
- # This next part can get tricky, I'm not sure how EAM is set up, but you *may* be able to do this without using
- # virtual mouse clicks. You would have to find what the element information is for the button you want to click
- # (type, anything unique to it like the name). In my example, going to the GitHub repo is just a simple link:
- # Basically, you need to perform each step in this area. Make sure to `Wait-NavigationCompleted($ie)` between each
- # one to ensure that you don't accidentally try to do something else when a page is loading. To check a check-box,
- # you just have to:
- $doc.getElementsByTagName("a") | % {
- if ($_.innerText -ne $null -and $_.innerText.Contains("StackExchange")) {
- $_.click()
- }
- }
- Wait-NavigationCompleted($ie)
- Write-Verbose "Download-File: Clicking 'Download' button"
- # To download a file:
- $doc.getElementsByTagName("a") | % {
- if ($_.innerText -ne $null -and $_.innerText.Contains("Download ZIP")) {
- $_.click()
- }
- }
- Wait-NavigationCompleted($ie)
- # Once you have hit the "download" button, we'll use WScript to send a few commands to finish that process off.
- # Sleep long enough that the file will download. If it's remote, and the net can be slow, I would consider
- # increasing this value a bit. (The second number is sleep time, the first is iterations.)
- Finish-Download $ie 5 5
- Write-Verbose "Download-File: Clicking 'Sign out' button"
- # You should logout so that you don't leave a hanging session next time you run the script (though I did design
- # it to look for a hanging session and ignore it).
- $doc.getElementsByTagName("button") | % {
- if ($_.innerText -ne $null -and $_.innerText.Contains("Sign out")) {
- $_.click()
- }
- }
- Wait-NavigationCompleted($ie)
- Write-Verbose "Download-File: Killing 'ie' process"
- # Kill the IE process
- $ie.Quit()
- Return $true
- } catch {
- $Error.ForEach({ Write-Error $_ })
- Return $false
- }
- }
- # Alter these to log what you want, valid values are "Continue" and "SilentlyContinue" for each
- $VerbosePreference = "Continue"
- $DebugPreference = "Continue"
- $ProgressPreferece = "Continue"
- Write-Verbose "Root: Script started"
- # Leave this one as it is
- $InformationPreference = "Continue"
- # Define your web service to connect to and the login page, include `http://` or `https://`
- $webService = "https://github.com/login"
- # Define your username and password
- $username = "USERNAME"
- $password = "PASSWORD"
- Write-Information "Beginning file download"
- if (Download-File $webService $username $password) {
- Write-Information "File downloaded successfully."
- } else {
- Write-Error "File could not be downloaded."
- }
- Exit
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement