Sending email message with attachment by powershell with a batch file - powershell

Hi i'm trying to send email from batch file.bat but I'm getting a list of red errors and rolling really fast and the window close also fast I tried to keep it open by the command
cmd /k
and it's still open but it won't show any error list.
not that: I'm using Gmail account as smtp and i opened smtp settings and enabled the less secure login option.
finally what to run the bat is that command. cmd execute command :
file.bat "mygmail#gmail.com" "mypassword" "D:\test\myFile.txt"
file.bat contains :
#ECHO OFF
SET GmailAccount=%~1
SET GmailPassword=%~2
SET Attachment=%~3
CALL :PowerShell
CD /D "%PowerShellDir%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%' '%GmailAccount%' '%GmailPassword%' '%Attachment%'"
EXIT
:PowerShell
SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
SET PSScript=%temp%\~tmpSendeMail.ps1
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
ECHO $Username = $args[0]>> "%PSScript%"
ECHO $EmailPassword = $args[1]>> "%PSScript%"
ECHO $Attachment = $args[2]>> "%PSScript%"
ECHO >> "%PSScript%"
ECHO $Username = $Username >> "%PSScript%"
ECHO $EmailTo = "target#mail.com" >> "%PSScript%"
ECHO $EmailFrom = "mygmail#gmail.com" >> "%PSScript%"
ECHO $Subject = "test" >> "%PSScript%"
ECHO $Body = "test" >> "%PSScript%"
ECHO $SMTPServer = "smtp.gmail.com" >> "%PSScript%"
ECHO $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body) >> "%PSScript%"
ECHO $Attachment = New-Object System.Net.Mail.Attachment($Attachment) >> "%PSScript%"
ECHO $SMTPMessage.Attachments.Add($Attachment) >> "%PSScript%"
ECHO $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) >> "%PSScript%"
ECHO $SMTPClient.EnableSsl = $true >> "%PSScript%"
ECHO $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($Username, $EmailPassword) >> "%PSScript%"
ECHO $SMTPClient.Send($SMTPMessage)
please Help me what is the problem here. Thanks.

First of all : This is a reminder for how to use less secure applications with google accounts
PS-Gmail-Sender.bat
#ECHO OFF
REM https://stackoverflow.com/questions/28605803/can-not-send-mail-using-smtp-gmail-com-port-587-from-vbs-script/28606754#28606754
Title Sending E-Mail with Gmail Less Secure Applications using Powershell and Batch
SET GmailAccount="%~1"
SET GmailPassword="%~2"
SET Attachment="%~3"
REM We write our Powershell script
CALL :WritePS
REM We execute our Powershell script .PS1 by passing arguments from the command line or a batch file
Powershell -ExecutionPolicy bypass -noprofile -file "%PSScript%" "%GmailAccount%" "%GmailPassword%" "%Attachment%"
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
pause
EXIT
REM -----------------------------------------------------------------------------------------------------
:WritePS
SET PSScript=%temp%\temp_SendeMail.ps1
> "%PSScript%" (
ECHO $Username = $args[0]
ECHO $EmailPassword = $args[1]
ECHO $Attachment= $args[2]
ECHO $EmailTo = $Username
ECHO $EmailFrom = $Username
ECHO $Subject = "This email was sent from Powershell script into a batch file with Less Secure Application Enabled"
ECHO $Body= "Test Email Sending with a script"
ECHO $SMTPServer = "smtp.gmail.com"
ECHO $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body^)
ECHO $Attachment = New-Object System.Net.Mail.Attachment($Attachment^)
ECHO $SMTPMessage.Attachments.Add($Attachment^)
ECHO $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587^)
ECHO $SMTPClient.EnableSsl = $true
ECHO $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($Username, $EmailPassword^)
ECHO $SMTPClient.Send($SMTPMessage^)
)
Exit /B
REM -----------------------------------------------------------------------------------------------------
So with the command line or a batch file we can call it as below :
PS-Gmail-Sender.bat "Mygmail_Account#gmail.com" "MyGmail_Password" "D:\test\myFile.txt"

Related

Automating batch files and powershell script execution

The goal is to automate the execution of 3 files:
A batch file that runs a selenium webdriver automated test suite.
Another batch file that generates a reports for the tests run in step 1.
A PowerShell script that attaches the reports and sends an email.
How can I automate the execution of these 3 files so that upon running a command or executing a file, all 3 are executed?
This is how my PowerShell looks like:
$Username = "";
$Password = "";
function Send-ToEmail([string]$email, [string]$attachmentpath) {
$message = New-Object Net.Mail.MailMessage;
$message.From = "c#c.com";
$message.To.Add($email);
$message.Subject = "abc";
$message.Body = "abc";
$attachment1 = New-Object Net.Mail.Attachment($attachmentpath);
$message.Attachments.Add($attachment1);
$smtp = New-Object Net.Mail.SmtpClient("build3", "25");
$smtp.EnableSSL = $false;
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.Send($message);
Write-Host $smtp.EnableSSL;
Write-Host "Mail Sent";
}
Send-ToEmail -email "a#a.com" -attachmentpath "C:\file1";
Send-ToEmail -email "b#b.com" -attachmentpath "C:\file1";
This is what the first batch file looks like:
FOR /F "TOKENS=2 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET dd=%%A
FOR /F "TOKENS=2,3 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET mm=%%B
FOR /F "TOKENS=2,3,4 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET yyyy=%%C
SET todaysdate=%yyyy%%mm%%dd%
start /d "nunitPATH" nunit3-console.exe "seleniumtestsuite dll PATH" --where:cat==SignUp --result="xmlreportPATH"
This is what the second batch file looks like:
start /d "exeFilePATH" ReportUnit.exe "folderPATH"
Simply write a batch script that runs
call script1.bat
call script2.bat
D:\path\to\powershell.exe -File script3.ps1
If you need async:
start script1.bat
start script2.bat
start "" "D:\path\to\powershell.exe" "-File" "script3.ps1"
Note the pair of double quotes before powershell.exe path.
Note that this assumes your device has at least powershell v2
However, this question is a duplicate of here

How do you add code with quotes to a file using batch?

I am trying to create a batch file that will create a file that will send an email through powershell. It does many things, but email is just a snippet of it. Here is what I have so far:
REM Creates batch file with contents of the powershell script
echo "I need to add the below powershell script" > email.bat
echo "into email.bat with all the quotes included">> email.bat
echo "like what I'm doing now with appending text">> email.bat
REM powershell script to send email.
$smtp = new-object Net.Mail.SmtpClient("smtp.gmail.com")
if( $Env:SmtpUseCredentials -eq "true" ) {
$credentials = new-object Net.NetworkCredential("username","password")
$smtp.Credentials = $credentials
}
$objMailMessage = New-Object System.Net.Mail.MailMessage
$objMailMessage.From = "myemail#gmail.com"
$objMailMessage.To.Add("whereImsendingto#gmail.com")
$objMailMessage.Subject = "Logs for today"
$objMailMessage.Body = "(the logs)"
$smtp.send($objMailMessage)
In batch, I have the way to append text to another file down if what I'm adding does not have quotes, but I need to add text that includes quotes to the file.
Why don't you simply echo whithout quotes and escape possible chars <>|& with a caret ^ and double percent signs?
In a (code block) you've to also escape closing parentheses ^)
#Echo off
( Echo:$smtp = new-object Net.Mail.SmtpClient("smtp.gmail.com"^)
Echo:
Echo:if( $Env:SmtpUseCredentials -eq "true" ^) {
Echo: $credentials = new-object Net.NetworkCredential("username","password"^)
Echo: $smtp.Credentials = $credentials
Echo:}
Echo:$objMailMessage = New-Object System.Net.Mail.MailMessage
Echo:$objMailMessage.From = "myemail#gmail.com"
Echo:$objMailMessage.To.Add("whereImsendingto#gmail.com"^)
Echo:$objMailMessage.Subject = "Logs for today"
Echo:$objMailMessage.Body = "(the logs^)"
Echo:
Echo:$smtp.send($objMailMessage^)
) > "SomeFile.ps1"

How to send Email from a Batch file?

I want the Email and Message in the Code to be sent to my Email "example#gmail.com'. I'm new to coding. Please help me to do this.
#echo off
color a
title Message Me
echo Instructions:
echo 1) Type the message and hit ENTER/RETURN
cd "C:\MessageMe"
set /p user=Email ID:
set /p message=Message:
echo Username="%user%" Message="%message%">Sent_Items.txt
echo Press any key to continue
pause >n
echo Loading.....
echo Enter E-Mail Again
set /p user=Email ID:
echo Username="%user%">Confirmed.txt
echo.
echo Press any key to Send
echo.
echo.
pause >
echo.
echo Processing...
echo.
echo.
echo.
echo.
echo.
pause >n
To send Emails from the Windows command-line, you can
...forget using raw telnet.exe as it cannot accept input from a file
...use a telnet.exe replacement like Albert Yale's telnet scripting tool
...use an actual command-line Email client like blat
...use PowerShell, like e.g. this1:
$EmailFrom = “yourgmailadress#gmail.com”
$EmailTo = “destination#somedomain.com”
$Subject = “The subject of your email”
$Body = “What do you want your email to say”
$SMTPServer = “smtp.gmail.com”
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential(“usr”, “pass”);
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)

Using the Filenames method of System.Windows.Forms.OpenFileDialog returns System.String[]

I'm new to Powershell and I am struggling with creating a script that'll return the file(s) chosen to the batch script I'm writing.
It's suppose to, when launched, open up a file browser where you can select multiple files and when the user confirms the selection, returns the file paths to the batch script.
This is what's in the batch file.
call :createPSscript
powershell -noprofile -noninteractive -executionpolicy unrestricted -Command "%~dp0FileSelector.ps1" >status
del FileSelector.ps1 >nul 2>&1
set /p status=<status
set /p queue=<queue
del status >nul 2>&1
echo %queue%
echo %status%
pause
:createPSscript
echo Add-Type -AssemblyName System.Windows.Forms>FileSelector.ps1
echo $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog>>FileSelector.ps1
echo $openFileDialog.Title = "Select APK(s) to work with.">>FileSelector.ps1
echo $openFileDialog.InitialDirectory = [Environment]::GetFolderPath("Desktop")>>FileSelector.ps1
echo $openFileDialog.Filter = "Android App Package (*.apk)|*.apk|All files (*.*)|*.*">>FileSelector.ps1
echo $openFileDialog.MultiSelect = $true>>FileSelector.ps1
echo $openFileDialog.ShowHelp = $true>>FileSelector.ps1
echo $openFileDialog.AutoUpgradeEnabled = $true>>FileSelector.ps1
echo $openFileDialog.ShowDialog() > $null>>FileSelector.ps1
echo $stream = [System.IO.StreamWriter] "%~dp0queue">>FileSelector.ps1
echo 1 ^| %% $stream.WriteLine^($openFileDialog.Filenames^)>>FileSelector.ps1
echo $stream.close^(^)>>FileSelector.ps1
exit /b
And in the powershell script that the batch outputs to.
Add-Type -AssemblyName System.Windows.Forms
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.Title = "Select APK(s) to work with."
$openFileDialog.InitialDirectory = [Environment]::GetFolderPath("Desktop")
$openFileDialog.Filter = "Android App Package (*.apk)|*.apk|All files (*.*)|*.*"
$openFileDialog.MultiSelect = $true
$openFileDialog.ShowHelp = $true
$openFileDialog.AutoUpgradeEnabled = $true
$openFileDialog.ShowDialog()
$stream = [System.IO.StreamWriter] "C:\Users\<redacted>\<redacted>\queue"
1 | % $stream.WriteLine($openFileDialog.Filenames)
$stream.close()
It works perfectly fine when I use $openFileDialog.Filename instead of $openFileDialog.Filename
%Status% returns if the user canceled or not and %queue% should return the list of files.
Did I do the syntax correctly?
Annnnnnd I'm an idiot. Turns out just by invoking $openFileDialog.Filenames, it'll return the selected files to the output.

How to script FTP upload and download

I'm attempting to make a batch file to upload a file to an FTP server.
If I type it in manually it works fine, but when I run the batch file it halts after it's connected... It says:
connected to domain.com.
220 microsoft ftp server
User(domain.com:(none)):
And then nothing else. What is going on here?
Below is my batch file:
ftp www.domainhere.com
user useridhere
passwordhere
put test.txt
bye
pause
It's a reasonable idea to want to script an FTP session the way the original poster imagined, and that is the kind of thing Expect would help with. Batch files on Windows cannot do this.
But rather than doing cURL or Expect, you may find it easier to script the FTP interaction with PowerShell. It's a different model, in that you are not directly scripting the text to send to the FTP server. Instead you will use PowerShell to manipulate objects that generate the FTP dialogue for you.
Upload:
$File = "D:\Dev\somefilename.zip"
$ftp = "ftp://username:password#example.com/pub/incoming/somefilename.zip"
"ftp url: $ftp"
$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)
"Uploading $File..."
$webclient.UploadFile($uri, $File)
Download:
$File = "c:\store\somefilename.zip"
$ftp = "ftp://username:password#example.com/pub/outbound/somefilename.zip"
"ftp url: $ftp"
$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)
"Downloading $File..."
$webclient.DownloadFile($uri, $File)
You need PowerShell to do this. If you are not aware, PowerShell is a shell like cmd.exe which runs your .bat files. But PowerShell runs .ps1 files, and is quite a bit more powerful. PowerShell is a free add-on to Windows and will be built-in to future versions of Windows. Get it here.
Source: http://poshcode.org/1134
Create a command file with your commands.
I.e., file commands.txt:
open www.domainhere.com
user useridhere
passwordhere
put test.txt
bye
Then run the FTP client from the command line:
ftp -s:commands.txt
Note: This will work for the Windows FTP client.
Batch files don't work that way. They don't just "type" everything - they run system commands, in this case ftp, wait for them to return, and run the next command... so in this case, the interpreter is simply waiting for ftp to exit.
If you must use the ftp command, then prepare a script file (for example, commands.txt and run ftp -s:commands.txt.
But using cURL, or a PHP/Perl/Python/whatever script may be a better idea.
I've done this with PowerShell:
function DownloadFromFtp($destination, $ftp_uri, $user, $pass){
$dirs = GetDirecoryTree $ftp_uri $user $pass
foreach($dir in $dirs){
$path = [io.path]::Combine($destination,$dir)
if ((Test-Path $path) -eq $false) {
"Creating $path ..."
New-Item -Path $path -ItemType Directory | Out-Null
}else{
"Exists $path ..."
}
}
$files = GetFilesTree $ftp_uri $user $pass
foreach($file in $files){
$source = [io.path]::Combine($ftp_uri,$file)
$dest = [io.path]::Combine($destination,$file)
"Downloading $source ..."
Get-FTPFile $source $dest $user $pass
}
}
function UploadToFtp($artifacts, $ftp_uri, $user, $pass){
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass)
foreach($item in Get-ChildItem -recurse $artifacts){
$relpath = [system.io.path]::GetFullPath($item.FullName).SubString([system.io.path]::GetFullPath($artifacts).Length + 1)
if ($item.Attributes -eq "Directory"){
try{
Write-Host Creating $item.Name
$makeDirectory = [System.Net.WebRequest]::Create($ftp_uri+$relpath);
$makeDirectory.Credentials = New-Object System.Net.NetworkCredential($user,$pass)
$makeDirectory.Method = [System.Net.WebRequestMethods+FTP]::MakeDirectory;
$makeDirectory.GetResponse();
}catch [Net.WebException] {
Write-Host $item.Name probably exists ...
}
continue;
}
"Uploading $item..."
$uri = New-Object System.Uri($ftp_uri+$relpath)
$webclient.UploadFile($uri, $item.FullName)
}
}
function Get-FTPFile ($Source,$Target,$UserName,$Password)
{
$ftprequest = [System.Net.FtpWebRequest]::create($Source)
$ftprequest.Credentials = New-Object System.Net.NetworkCredential($username,$password)
$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
$ftprequest.UseBinary = $true
$ftprequest.KeepAlive = $false
$ftpresponse = $ftprequest.GetResponse()
$responsestream = $ftpresponse.GetResponseStream()
$targetfile = New-Object IO.FileStream ($Target,[IO.FileMode]::Create)
[byte[]]$readbuffer = New-Object byte[] 1024
do{
$readlength = $responsestream.Read($readbuffer,0,1024)
$targetfile.Write($readbuffer,0,$readlength)
}
while ($readlength -ne 0)
$targetfile.close()
}
#task ListFiles {
#
# $files = GetFilesTree 'ftp://127.0.0.1/' "web" "web"
# $files | ForEach-Object {Write-Host $_ -foregroundcolor cyan}
#}
function GetDirecoryTree($ftp, $user, $pass){
$creds = New-Object System.Net.NetworkCredential($user,$pass)
$files = New-Object "system.collections.generic.list[string]"
$folders = New-Object "system.collections.generic.queue[string]"
$folders.Enqueue($ftp)
while($folders.Count -gt 0){
$fld = $folders.Dequeue()
$newFiles = GetAllFiles $creds $fld
$dirs = GetDirectories $creds $fld
foreach ($line in $dirs){
$dir = #($newFiles | Where { $line.EndsWith($_) })[0]
[void]$newFiles.Remove($dir)
$folders.Enqueue($fld + $dir + "/")
[void]$files.Add($fld.Replace($ftp, "") + $dir + "/")
}
}
return ,$files
}
function GetFilesTree($ftp, $user, $pass){
$creds = New-Object System.Net.NetworkCredential($user,$pass)
$files = New-Object "system.collections.generic.list[string]"
$folders = New-Object "system.collections.generic.queue[string]"
$folders.Enqueue($ftp)
while($folders.Count -gt 0){
$fld = $folders.Dequeue()
$newFiles = GetAllFiles $creds $fld
$dirs = GetDirectories $creds $fld
foreach ($line in $dirs){
$dir = #($newFiles | Where { $line.EndsWith($_) })[0]
[void]$newFiles.Remove($dir)
$folders.Enqueue($fld + $dir + "/")
}
$newFiles | ForEach-Object {
$files.Add($fld.Replace($ftp, "") + $_)
}
}
return ,$files
}
function GetDirectories($creds, $fld){
$dirs = New-Object "system.collections.generic.list[string]"
$operation = [System.Net.WebRequestMethods+Ftp]::ListDirectoryDetails
$reader = GetStream $creds $fld $operation
while (($line = $reader.ReadLine()) -ne $null) {
if ($line.Trim().ToLower().StartsWith("d") -or $line.Contains(" <DIR> ")) {
[void]$dirs.Add($line)
}
}
$reader.Dispose();
return ,$dirs
}
function GetAllFiles($creds, $fld){
$newFiles = New-Object "system.collections.generic.list[string]"
$operation = [System.Net.WebRequestMethods+Ftp]::ListDirectory
$reader = GetStream $creds $fld $operation
while (($line = $reader.ReadLine()) -ne $null) {
[void]$newFiles.Add($line.Trim())
}
$reader.Dispose();
return ,$newFiles
}
function GetStream($creds, $url, $meth){
$ftp = [System.Net.WebRequest]::Create($url)
$ftp.Credentials = $creds
$ftp.Method = $meth
$response = $ftp.GetResponse()
return New-Object IO.StreamReader $response.GetResponseStream()
}
Export-ModuleMember UploadToFtp, DownLoadFromFtp
You can script the ftp command with the -s:filename option. The syntax is just a list of commands to pass to the ftp shell, each terminated by a newline. This page has a nice reference to the commands that can be performed with ftp.
Upload/Download Entire Directory Structure
Using the normal ftp doesn't work very well when you need to have an entire directory tree copied to or from a FTP site. So you could use something like these to handle those situations.
These scripts work with the Windows ftp command and allows for uploading and downloading of entire directories from a single command. This makes it pretty self-reliant when using on different systems.
Basically, they map out the directory structure to be up/downloaded, dump corresponding ftp commands to a file, and then execute those commands when the mapping has finished.
ftpupload.bat
#echo off
SET FTPADDRESS=%1
SET FTPUSERNAME=%2
SET FTPPASSWORD=%3
SET LOCALDIR=%~f4
SET REMOTEDIR=%5
if "%FTPADDRESS%" == "" goto FTP_UPLOAD_USAGE
if "%FTPUSERNAME%" == "" goto FTP_UPLOAD_USAGE
if "%FTPPASSWORD%" == "" goto FTP_UPLOAD_USAGE
if "%LOCALDIR%" == "" goto FTP_UPLOAD_USAGE
if "%REMOTEDIR%" == "" goto FTP_UPLOAD_USAGE
:TEMP_NAME
set TMPFILE=%TMP%\%RANDOM%_ftpupload.tmp
if exist "%TMPFILE%" goto TEMP_NAME
SET INITIALDIR=%CD%
echo user %FTPUSERNAME% %FTPPASSWORD% > %TMPFILE%
echo bin >> %TMPFILE%
echo lcd %LOCALDIR% >> %TMPFILE%
cd %LOCALDIR%
setlocal EnableDelayedExpansion
echo mkdir !REMOTEDIR! >> !TMPFILE!
echo cd %REMOTEDIR% >> !TMPFILE!
echo mput * >> !TMPFILE!
for /d /r %%d in (*) do (
set CURRENT_DIRECTORY=%%d
set RELATIVE_DIRECTORY=!CURRENT_DIRECTORY:%LOCALDIR%=!
echo mkdir "!REMOTEDIR!/!RELATIVE_DIRECTORY:~1!" >> !TMPFILE!
echo cd "!REMOTEDIR!/!RELATIVE_DIRECTORY:~1!" >> !TMPFILE!
echo mput "!RELATIVE_DIRECTORY:~1!\*" >> !TMPFILE!
)
echo quit >> !TMPFILE!
endlocal EnableDelayedExpansion
ftp -n -i "-s:%TMPFILE%" %FTPADDRESS%
del %TMPFILE%
cd %INITIALDIR%
goto FTP_UPLOAD_EXIT
:FTP_UPLOAD_USAGE
echo Usage: ftpupload [address] [username] [password] [local directory] [remote directory]
echo.
:FTP_UPLOAD_EXIT
set INITIALDIR=
set FTPADDRESS=
set FTPUSERNAME=
set FTPPASSWORD=
set LOCALDIR=
set REMOTEDIR=
set TMPFILE=
set CURRENT_DIRECTORY=
set RELATIVE_DIRECTORY=
#echo on
ftpget.bat
#echo off
SET FTPADDRESS=%1
SET FTPUSERNAME=%2
SET FTPPASSWORD=%3
SET LOCALDIR=%~f4
SET REMOTEDIR=%5
SET REMOTEFILE=%6
if "%FTPADDRESS%" == "" goto FTP_UPLOAD_USAGE
if "%FTPUSERNAME%" == "" goto FTP_UPLOAD_USAGE
if "%FTPPASSWORD%" == "" goto FTP_UPLOAD_USAGE
if "%LOCALDIR%" == "" goto FTP_UPLOAD_USAGE
if not defined REMOTEDIR goto FTP_UPLOAD_USAGE
if not defined REMOTEFILE goto FTP_UPLOAD_USAGE
:TEMP_NAME
set TMPFILE=%TMP%\%RANDOM%_ftpupload.tmp
if exist "%TMPFILE%" goto TEMP_NAME
echo user %FTPUSERNAME% %FTPPASSWORD% > %TMPFILE%
echo bin >> %TMPFILE%
echo lcd %LOCALDIR% >> %TMPFILE%
echo cd "%REMOTEDIR%" >> %TMPFILE%
echo mget "%REMOTEFILE%" >> %TMPFILE%
echo quit >> %TMPFILE%
ftp -n -i "-s:%TMPFILE%" %FTPADDRESS%
del %TMPFILE%
goto FTP_UPLOAD_EXIT
:FTP_UPLOAD_USAGE
echo Usage: ftpget [address] [username] [password] [local directory] [remote directory] [remote file pattern]
echo.
:FTP_UPLOAD_EXIT
set FTPADDRESS=
set FTPUSERNAME=
set FTPPASSWORD=
set LOCALDIR=
set REMOTEFILE=
set REMOTEDIR=
set TMPFILE=
set CURRENT_DIRECTORY=
set RELATIVE_DIRECTORY=
#echo on
This script generates the command file then pipes the command file to the ftp program, creating a log along the way. Finally print the original bat file, the command files and the log of this session.
#echo on
#echo off > %0.ftp
::== GETmy!dir.bat
>> %0.ftp echo a00002t
>> %0.ftp echo iasdad$2
>> %0.ftp echo help
>> %0.ftp echo prompt
>> %0.ftp echo ascii
>> %0.ftp echo !dir REPORT.CP1C.ROLLEDUP.TXT
>> %0.ftp echo get REPORT.CP1C.ROLLEDUP.TXT
>> %0.ftp echo !dir REPORT.CP1C.ROLLEDUP.TXT
>> %0.ftp echo *************************************************
>> %0.ftp echo !dir CONTENT.CP1C.ROLLEDUP.TXT
>> %0.ftp echo get CONTENT.CP1C.ROLLEDUP.TXT
>> %0.ftp echo !dir CONTENT.CP1C.ROLLEDUP.TXT
>> %0.ftp echo *************************************************
>> %0.ftp echo !dir WORKLOAD.CP1c.ROLLEDUP.TXT
>> %0.ftp echo get WORKLOAD.CP1C.ROLLEDUP.TXT
>> %0.ftp echo !dir WORKLOAD.CP1C.ROLLEDUP.TXT
>> %0.ftp echo *************************************************
>> %0.ftp echo !dir REPORT.TMMC.ROLLEDUP.TXT
>> %0.ftp echo get REPORT.TMMC.ROLLEDUP.TXT
>> %0.ftp echo !dir REPORT.TMMC.ROLLEDUP.TXT
>> %0.ftp echo *************************************************
>> %0.ftp echo !dir CONTENT.TMMC.ROLLEDUP.TXT
>> %0.ftp echo get CONTENT.TMMC.ROLLEDUP.TXT
>> %0.ftp echo !dir CONTENT.TMMC.ROLLEDUP.TXT
>> %0.ftp echo **************************************************
>> %0.ftp echo !dir WORKLOAD.TMMC.ROLLEDUP.TXT
>> %0.ftp echo get WORKLOAD.TMMC.ROLLEDUP.TXT
>> %0.ftp echo !dir WORKLOAD.TMMC.ROLLEDUP.TXT
>> %0.ftp echo quit
ftp -d -v -s:%0.ftp 150.45.12.18 > %0.log
type %0.bat
type %0.ftp
type %0.log
I was having a similar issue - like the original poster, I wanted to automate a file upload, but I couldn't figure out how. Because this is on a register terminal at my family's store, I didn't want to install PowerShell (although that looks like an easy option) and I just wanted a simple .bat file to do this.
This is pretty much what grawity and another user said; I'm new to this stuff, so here's a more detailed example and explanation (thanks also to How to Automate FTP Uploads from the Windows Command Line who explains how to do it with just one .bat file).
Essentially you need two files - one .bat and one .txt. The .bat tells ftp.exe what switches to use. The .txt gives a list of commands to ftp.exe. In the text file put this:
username
password
cd whereverYouWantToPutTheFile
lcd whereverTheFileComesFrom
put C:\InventoryExport\inventory.test (or your file path)
bye
Save that wherever you want. In the BAT file put:
ftp.exe -s:C:\Windows\System32\test.txt destinationIP
pause
Obviously change the path after the -s: to wherever your text file is. Take out the pause when you're actually running it - it's just so you can see any errors. Of course, you can use "get" or any other ftp command in the .txt file to do whatever you need to do.
I'm not positive that you need the lcd command in the text file. Like I said, I'm new to using command line for this type of thing, but this is working for me.
I had this same issue, and solved it with a solution similar to what Cheeso provided.
"doesn't work, says password is srequire, tried it a couple different ways "
Yep, that's because FTP sessions via a command file don't require the username to be prefaced with the string "user". Drop that, and try it.
Or, you could be seeing this because your FTP command file is not properly encoded (that bit me, too). That's the crappy part about generating a FTP command file at runtime. PowerShell's out-file cmdlet does not have an encoding option that Windows FTP will accept (at least not one that I could find).
Regardless, as doing a WebClient.DownloadFile is the way to go.
Try manually:
$ ftp www.domainhere.com
> useridhere
> passwordhere
> put test.txt
> bye
> pause