Recently I needed a script to upload log files from one server to another server. The servers were in separate networks so I could not use a simple copy command like xcopy or robocopy. For this I had to use FTP. I had already a simple old batch file that uses the built-in ftp command. But I wanted to use PowerShell so that I could make it more advanced. After some searching on PowerShell websites I found some examples. I used these as a start for my function.
function Send-FileToFtp {
[CmdletBinding()]
[OutputType([System.Int32])]
param(
[Parameter(Position=0, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.Object]$SourceFile,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.String]$Destination,
[Parameter(Position=2, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.String]$UserName,
[Parameter(Position=3, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.String]$Password
)
Process {
try {
# Get the object used to communicate with the server.
$Request = [System.Net.FtpWebRequest]::Create("ftp://$Destination/$($SourceFile.Name)")
$Request.Method = $Request.Method = [System.Net.WebRequestMethods+ftp]::UploadFile
# This example assumes the FTP site uses anonymous logon.
$Request.Credentials = New-Object System.Net.NetworkCredential $UserName,$Password
# Copy the contents of the file to the request stream.
$FileContents = [System.IO.File]::ReadAllBytes($SourceFile.FullName)
$Request.ContentLength = $fileContents.Length
$RequestStream = $request.GetRequestStream()
$RequestStream.Write($FileContents, 0, $FileContents.Length)
$RequestStream.Close()
$Response = $Request.GetResponse()
$Response.StatusDescription
}
catch {
throw "ERROR: Unable to upload file $($SourceFile.name), status {0}"
}
$Response.StatusDescription
}
}
The function takes 4 parameters as you can see in the script. Most of them will be self explaining. But the parameter $SourceFile will need some explanation. Instead of using a string I decided to use an object. I did this so I can use the object to construct the filename of the source and also use it to construct the ftp request. To use the function you can write something like this.
$files = Get-ChildItem -Path "c:\windows\system32\logfiles\" -Filter "*.log"
if ($files -ne $null) {
Foreach ($file in $files) {
$result = Send-FileToFtp -SourceFile $file -Destination "ftp.domain.com/folder" -UserName "user" -Password "password"
if ($Result -match "226*"){
"Upload completed, now deleting source file: $($File.Name)"
} else {
"Upload failed!"
}
}
}
It gets all the log files from the c:\windows\system32logfiles directory and places them in the variable $files. For every file object in the variable $files it runs the function Send-FileToFtp. If the upload succeeds, the function returns a StatusDescription with the code 226, you can delete the original file or do something else. When the upload fails you can output a message or do somethings else.
For what I wanted to do this works perfect. But for other things it possibly needs to get changed a bit.