1

My big picture goal is to automate an FTP transfer to run daily. I have a PowerShell script that I have would like to use to login to the FTP site in question. I know the script works, because I've tested it with other sites/logins and it works perfectly every time. The problem is that when the site loads, the login screen loads in a pop up window (image below), and I cannot right click-inspect element or F12 to search the HTML for object names, element IDs, etc. I've tried just about everything I can think of to guess the names for the login windows, but I think that my script isn't even communicating with the pop up window. Any suggestions on how to tackle this particular issue? I've included the error message I'm getting at the end as well.

Here is my script:

$username = "myuser";
$password = "mypass";

#Create an instance of IE
$ie = New-Object -ComObject 'internetExplorer.Application'
$ie.Visible= $true # Make it visible

#Navigate to the site
$ie.Navigate("website.com")

While ($ie.Busy -eq $true) {Start-Sleep -Seconds 1;} #wait for browser idle

($ie.document.getElementById('User') | select -first 1).value = $username #enters username
Start-Sleep -Seconds 1 

($ie.document.getElementById('Pass') | select -first 1).value = $password #enters password
Start-Sleep -Seconds 1 

($ie.document.getElementById('Log on') | select -first 1).click() #clicks login button
Start-Sleep -Seconds 1

Screenshot of FTP Site

Screenshot of error messages

DarcFox
  • 13
  • 4
  • Consider using a dedicated FTP program, like `ftp.exe` that comes with Windows. It's `-s` switch can be used to give it a set of commands to run. There's little reason to use Internet Explorer to access a FTP site when scripting. – chwarr Dec 02 '19 at 19:42
  • PowerShell/.NET framework has native implementation of FTP protocol. See for example [PowerShell FTP download files and subfolders](https://stackoverflow.com/q/37080506/850848). – Martin Prikryl Dec 02 '19 at 20:18

1 Answers1

0

Consider using the PSFTP Powershell Module instead of the Internet Explorer COM object. Install it with the following command:

Install-Module PSFTP

Basically, use Set-FTPConnection to open a session to the FTP server, New-FTPItem for creating new FTP directories, and Add-FTPItem to upload new files. Get-FTPItem would be used to retrieve a remote file.


Here are some samples from the TechNet Gallery site:

Import-Module PSFTP 

Set-FTPConnection -Credentials mgajda -Server ftp://ftp.server.org -Session MyTestSession -UsePassive 
$Session = Get-FTPConnection -Session MyTestSession 

New-FTPItem -Session $Session -Name TestRootDir 
New-FTPItem -Session $Session -Name TestDir1 -Path /TestRootDir 
New-FTPItem -Session $Session -Name TestDir2 -Path /TestRootDir 
New-FTPItem -Session $Session -Name TestDir11 -Path /TestRootDir/TestDir1 

Get-FTPChildItem -Session $Session -Path /TestRootDir -Recurse -Depth 2 

"Test File" | Out-File TestFile.txt 
Get-ChildItem TestFile.txt | Add-FTPItem -Session $Session -Path /TestRootDir 
Get-ChildItem TestFile.txt | Add-FTPItem -Session $Session -Path /TestRootDir -Overwrite 
Get-ChildItem TestFile.txt | Add-FTPItem -Session $Session -Path /TestRootDir/TestDir1  
Get-ChildItem TestFile.txt | Add-FTPItem -Session $Session -Path /TestRootDir/TestDir2 -BufferSize 5 
Add-FTPItem -Session $Session -Path /TestRootDir/TestDir1/TestDir11 -LocalPath TestFile.txt 

Get-FTPChildItem -Session $Session -Path /TestRootDir -Recurse -Depth 2 
Get-FTPChildItem -Session $Session -Path /TestRootDir -Recurse 

Get-FTPItemSize -Session $Session -Path /TestRootDir/TestDir1/TestFile.txt 

Rename-FTPItem -Session $Session -Path /TestRootDir/TestDir1/TestFile.txt -NewName TestFile2.txt 
Rename-FTPItem -Session $Session -Path /TestRootDir/TestDir1/TestFile2.txt -NewName ../TestFile2.txt 

Get-FTPChildItem -Session $Session -Path /TestRootDir | Get-FTPItem -Session $Session -LocalPath C:\test 
Get-FTPChildItem -Session $Session -Path /TestRootDir -Recurse | Get-FTPItem -Session $Session -LocalPath C:\test -RecreateFolders 

Get-FTPChildItem -Session $Session -Path /TestRootDir -Filter TestF* | Remove-FTPItem -Session $Session 
Remove-FTPItem -Session $Session -Path /TestRootDir -Recurse 

Building the credential

There are a few ways of securely building a credential object. The (usually) best way is to use Get-Credential:

$cred = Get-Credential $user

However, Get-Credential will always prompt you for the password. As long as you generate the above credential on the same machine with the same user who needs to decrypt the credential, you can store the credential object on the filesystem and read it in later (as the same user on the same machine) to use the credential in other sessions.

Assuming you created $cred as I've shown above:

# Export the credential object to a file on disk
$cred | Export-CliXml C:\path\to\secretAD.xml

# Import the credential object later on
$cred = Import-CliXml C:\path\to\secretAD.xml

Export-CliXml and Import-CliXml are two handy cmdlets that let you serialize any Powershell object to disk and read it back into another Powershell session later on. There are some limitations to this (don't try using a COM object read in this way for example) but it works fine for the case of storing and reading credential objects.

If you want a more portable method of encrypting the password in a credential, see the second example here.

codewario
  • 19,553
  • 20
  • 90
  • 159
  • Thanks everyone, these are all very helpful! I'm going to work my way through these solutions to see what works best. I was very stuck, and this gives me a lot to go on for this project – DarcFox Dec 03 '19 at 16:51
  • Okay, dumb question (sorry, I'm a PowerShell novice): I've used the code block above as a template, and am going through and changing the generic placeholders to what I need them to say. I don't know how to put the login info I need in here. I'm assuming it is with the -Credentials area, but I don't know the syntax. Any help here would be great! – DarcFox Dec 03 '19 at 18:03
  • Use `Get-Credential` to securely build a PSCrenential object. I believe that's what `Set-FtpConnection` is expecting. – codewario Dec 03 '19 at 19:42
  • I added a bit about how to securely build your credential object – codewario Dec 03 '19 at 20:22