Creating a directory on remote FTP using powershell - powershell

I"m able to put a file up to a remote FTP with a modified version of...
$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)
I'm running into the problem that I"m trying to upload a file to a directory that doesn't exist, the put fails. So I need to create the target directory first. GET-MEMBER doesn't seem to show any methods I can invoke to create a directory, only file operations.

I use function Create-FtpDirectory
function Create-FtpDirectory {
param(
[Parameter(Mandatory=$true)]
[string]
$sourceuri,
[Parameter(Mandatory=$true)]
[string]
$username,
[Parameter(Mandatory=$true)]
[string]
$password
)
if ($sourceUri -match '\\$|\\\w+$') { throw 'sourceuri should end with a file name' }
$ftprequest = [System.Net.FtpWebRequest]::Create($sourceuri);
$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::MakeDirectory
$ftprequest.UseBinary = $true
$ftprequest.Credentials = New-Object System.Net.NetworkCredential($username,$password)
$response = $ftprequest.GetResponse();
Write-Host Upload File Complete, status $response.StatusDescription
$response.Close();
}
Taken from Ftp.psm1 where you can find also other functions for FTP.
To others: sorry for not following well known verb-noun pattern. ;)

Related

Format date download issue in PowerShell

I have a files in my SharePoint site that look something like this
ShardReportsFull/ShardData-Full-2022-03-28-03.00.12AM.csv
ShardReportsFull/ShardData-Full-2022-03-27-53.00.12AM.csv
ShardReportsFull/ShardData-Full-2022-03-25-34.00.12AM.csv
I'm just wondering how can I download the latest file. I have tried passing a date like this but the problem is the uploaded file name format. it has a time where is not consistent so I can't just pass a date like this so I need to find a way to download the latest file instead.
$Date = Get-Date
$ShardDate = $Date.ToString("yyyy-MM-dd")
$Global:ShardListURL = "/sites/msteams_88c7ed/ShardReportsFull/ShardData-Full-"+$ShardDate+".csv"
$Global:shardListCSV = "C:\scripts\Re-LitHold-OneDrive\Download-Files\ShardData-Full-"+$ShardDate+".csv"
$Global:SiteURL = "https://company.sharepoint.com/sites/"
$Global:ShardListURL = "/sites/msteams_88c7ed/ShardReportsFull/ShardData-Full-2022-03-27-03.00.11AM.csv"
$Global:shardListCSV = "C:\scripts\OneDrive\Download-Files\ShardData-Full-2022-03-27-03.00.11AM.csv"
Function Download-FileFromLibrary() {
param
(
[Parameter(Mandatory = $true)] [string] $SiteURL,
[Parameter(Mandatory = $true)] [string] $SourceFile,
[Parameter(Mandatory = $true)] [string] $TargetFile
)
Try {
#Setup Credentials to connect
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Global:adminUPN, $Global:adminPwd)
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = $Credentials
#sharepoint online powershell download file from library
$FileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Ctx, $SourceFile)
$WriteStream = [System.IO.File]::Open($TargetFile, [System.IO.FileMode]::Create)
$FileInfo.Stream.CopyTo($WriteStream)
$WriteStream.Close()
Write-host -f Green "File '$SourceFile' Downloaded to '$TargetFile' Successfully!" $_.Exception.Message
}
Catch {
write-host -f Red "Error Downloading File!" $_.Exception.Message
}
}
Download-FileFromLibrary -SiteURL $Global:SiteURL -SourceFile $Global:ShardListURL -TargetFile $Global:shardListCSV

PowerShell System.Net.WebClient never closes ftp connection

I'm trying to use PowerShell to upload a (long) list of queued files, using System.Net.WebClient and the UploadFile function. This works fine, but after a file us uploaded, the ftp-connection never closes, either when the WebClient object instance goes out of scope or even after the script has finished. The function looks as follows:
function Upload-File() {
Param (
[string] $user,
[string] $password,
[string] $srceFileName,
[string] $destFileName
)
# Set up FTP-client
$client = New-Object System.Net.WebClient
$client.Credentials = New-Object System.Net.NetworkCredential($user, $password)
$client.UploadFile($destFileName, ".\$srceFileName")
$client.Dispose()
}
All the information I can find states that the connection should close automatically when $client goes out of scope but this is clearly not happening.
Any idea on how to force the connection to close?
(This is part of a legacy system and for now I am stuck with ftp, so switching to another protocol is not an option.)
For anyone else running into this problem, the solution is to use FtpWebRequest instead of WebClient and to set KeepAlive = $false. The function below will upload and then terminate the connection immediately afterwards.
function Upload-File() {
Param (
[string] $user,
[string] $password,
[string] $srceFileName,
[string] $destFileName
)
$request = [Net.WebRequest]::Create($destFileName)
$request.KeepAlive = $false
$request.Credentials =
New-Object System.Net.NetworkCredential($user, $password)
$request.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile
$fileStream = [System.IO.File]::OpenRead(".\$srceFileName")
$ftpStream = $request.GetRequestStream()
$fileStream.CopyTo($ftpStream)
$ftpStream.Dispose()
$fileStream.Dispose()
}
This post pointed me in the right direction.

Azure Automation - Copy Files from one Sharepoint site to another

I would like to create a workflow that automatically copies files which were uploaded to a Sharepoint-Site onto another SharePoint-Site (for file exchange with customers). Therefore I created a Logic App that triggers a Runbook with following content:
param(
[Parameter (Mandatory = $true)][string]$FilePath,
[Parameter (Mandatory = $true)][string]$FileName
)
$Client = "C:\Modules\User\Microsoft.SharePoint.Client\Microsoft.SharePoint.Client.dll"
$ClientRT = "C:\Modules\User\Microsoft.SharePoint.Client\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path $Client
Add-Type -Path $ClientRT
Creds = Get-AutomationPSCredential -Name "SharepointCreds"
#Set parameter values
$TargetSiteURL="https://domain.SharePoint.com/sites/site1"
$SourceSiteURL="https://domain.Sharepoint.com/sites/site2"
#Set Source and Destination File URL
$SourceFileURL="/sites/Sitename1/$Filepath/$FileName"
$TargetFileURL="/sites/Sitename2/$Filepath/$FileName"
#Setup Credentials to connect
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Creds.UserName, $Creds.Password)
#Setup the contexts
$SourceCtx = New-Object Microsoft.SharePoint.Client.ClientContext($SourceSiteURL)
$SourceCtx.Credentials = $Credentials
$TargetCtx = New-Object Microsoft.SharePoint.Client.ClientContext($TargetSiteURL)
$TargetCtx.Credentials = $Credentials
#Get the Source File
$FileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($SourceCtx, $SourceFileURL)
#Copy File to the Target location
[Microsoft.SharePoint.Client.File]::SaveBinaryDirect($TargetCtx, $TargetFileURL, $FileInfo.Stream,$True)
Anyways I keep receiving following error: Cannot send a content-body with this verb-type
How can I resolve this issue? Is there a better approach?
In sharepoint, we could use the MoveCopyUtil Class to copy file between sites
For example:
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SourceSiteURL)
$Ctx.Credentials = $Credentials
#Copy the File
$MoveCopyOpt = New-Object Microsoft.SharePoint.Client.MoveCopyOptions
$Overwrite = $True
[Microsoft.SharePoint.Client.MoveCopyUtil]::CopyFile($Ctx, $SourceFileURL, $TargetFileURL, $Overwrite, $MoveCopyOpt)
$Ctx.ExecuteQuery()
Reference: https://www.sharepointdiary.com/2017/02/sharepoint-online-copy-file-between-document-libraries-using-powershell.html#ixzz7CSvEyjEc

Using PowerShell to FTP to label printer - mimic command-line FTP command

I'm trying to print files to an Intermec printer. I can do it with ftp command like:
put C:\myfile.prn pr1
Now I'm trying to do the same thing with PowerShell and I've been able to upload files but I'm not sure how execute the last part, which is the port of the printer pr1.
This is what I got so far.
$Dir = "C:\files"
$ftp = "ftp://printerip/pr1/"
$user = "admin"
$pass = "pass"
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object System.Net.NetworkCredential($user, $pass)
#list every sql server trace file
foreach($item in (dir $Dir "*.prn")) {
"Uploading $item..."
$uri = New-Object System.Uri($ftp+$item.Name)
$webclient.UploadFile($uri, $item.FullName)
}
You are uploading the local file myfile.prn to the remote "file" pr1.
So do the same in PowerShell:
$ftp = "ftp://printerip/pr1"
$webclient.UploadFile($ftp, $item.FullName)

How to create directories from powershell on FTP server?

I want to run a PS script when I want to publish to FTP server. I took this script as structure : structure script.
I have very simple folder :
C:\Uploadftp\Files\doc.txt
C:\Uploadftp\Files\Files2
C:\Uploadftp\Files\Files2\doc2.txt
nothing fancy there.
Here is my script :
cd C:\Uploadftp
$location = Get-Location
"We are here: $location"
$user = "test" # Change
$pass = "test" # Change
## Get files
$files = Get-ChildItem -recurse
## Get ftp object
$ftp_client = New-Object System.Net.WebClient
$ftp_client.Credentials = New-Object System.Net.NetworkCredential($user,$pass)
$ftp_address = "ftp://test/TestFolder"
## Make uploads
foreach($file in $files)
{
$directory = "";
$source = $($file.DirectoryName + "/" + $file);
if ($file.DirectoryName.Length -gt 0)
{
$directory = $file.DirectoryName.Replace($location,"")
}
$directory = $directory.Replace("\","/")
$source = $source.Replace("\","/")
$directory += "/";
$ftp_command = $($ftp_address + $directory + $file)
# Write-Host $source
$uri = New-Object System.Uri($ftp_command)
"Command is " + $uri + " file is $source"
$ftp_client.UploadFile($uri, $source)
}
I keep getting this error :
Exception calling "UploadFile" with "2" argument(s): "An exception occurred during a WebClient request."
If I hardcode specific folder for $uri and tell source to be some specific folder on my computer, this script doesn't create directory, it creates a file. What am I doing wrong?
P.S. dont hit me too hard, its my fist time ever doing something in power shell.
Try the "Create-FtpDirectory" function from https://github.com/stej/PoshSupport/blob/master/Ftp.psm1
function Create-FtpDirectory {
param(
[Parameter(Mandatory=$true)]
[string]
$sourceuri,
[Parameter(Mandatory=$true)]
[string]
$username,
[Parameter(Mandatory=$true)]
[string]
$password
)
if ($sourceUri -match '\\$|\\\w+$') { throw 'sourceuri should end with a file name' }
$ftprequest = [System.Net.FtpWebRequest]::Create($sourceuri);
$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::MakeDirectory
$ftprequest.UseBinary = $true
$ftprequest.Credentials = New-Object System.Net.NetworkCredential($username,$password)
$response = $ftprequest.GetResponse();
Write-Host Upload File Complete, status $response.StatusDescription
$response.Close();
}