get the name of the new file in powershell - powershell

#Config Variables
$SiteURL = "https://company.sharepoint.com/sites/Test-Reports"
$FolderURL= "/Shared Documents/" #Folder's Site Relative Path
$oldCount = 16
function fileOps {
Try {
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Interactive
#Get All Files from the Folder
$FolderItems = Get-PnPFolderItem -FolderSiteRelativeUrl $FolderURL -ItemType File
Write-host "Total Number of Files in the Folder:" $FolderItems.Count
if ($FolderItems.Count > $script:oldCount) {
Write-host "I am here"
}
$oldCount = $FolderItems.Count
ForEach($File in $FolderItems)
{
$File.Name
}
}
catch {
write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}
}
For (;;) {
fileOps
timeout 20
I am trying out powershell to get a list of files from my sharedpoint site. This lists number of the files there.I am struggling with the format though and am short on time. Once a new file is dropped, I want it to print out the name of the new file that is added and break out of this loop to call a python script. This function needs to run indefinetly.
While($TRUE)
fileOps

Continuing from my comments:
use script: scoping on your $oldCount variable inside the function, so it can update the value on that while it has been defined elsewhere
Force the $FolderItems variable to always be an array. Arrays have a .Count property, single items do not
#Config Variables
$SiteURL = "https://company.sharepoint.com/sites/Test-Reports"
$FolderURL= "/Shared Documents/" #Folder's Site Relative Path
$oldCount = 16
function fileOps {
Try {
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Interactive -ErrorAction Stop
#Get All Files from the Folder
# use the `#()` construct to ensure you receive an array of items
$FolderItems = #(Get-PnPFolderItem -FolderSiteRelativeUrl $FolderURL -ItemType File -ErrorAction Stop)
Write-host "Total Number of Files in the Folder:" $FolderItems.Count
# PowerShell uses `-gt` operator for Greater Than, not the `>`
if ($FolderItems.Count -gt $script:oldCount) {
Write-host "I am here"
}
# set the script-scoped variable to its new value
$script:oldCount = $FolderItems.Count
# output the file names
$FolderItems.Name
}
catch {
write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}
}

Related

Download files from set of folders on FTP/SFTP server with WinSCP .NET assembly in PowerShell and email results

I have this PowerShell script that I'm working on. CSV file is imported to get source and destination paths. The goal is to move files from a SFTP/FTP server into a destination and send an email report.
Task scheduler will run this code every hour. And if there's a new file, as email will be sent out.
It's almost done, but two things are missing:
Check if the file already exists and Body email seems empty: Getting the following error: Cannot validate argument on parameter 'Body'. The argument is null or empty. Provide an argument that is not
null or empty, and then try the command again.
I would like some assistance on how to check if the file exists and how to get this email if a new file was dropped and copied to the destination list
$SMTPBody = ""
$SMTPMessage = #{
"SMTPServer" = ""
"From" = ""
"To" = ""
"Subject" = "New File"
}
try {
# Load WinSCP .NET assembly
Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property #{
Protocol = [WinSCP.Protocol]::sftp
HostName = ""
UserName = ""
Password = ""
PortNumber = "22"
FTPMode = ""
GiveUpSecurityAndAcceptAnySshHostKey = $true
}
$session = New-Object WinSCP.Session
try
{
# Connect
$session.Open($sessionOptions)
# Download files
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
Import-Csv -Path "D:\FILESOURCE.csv" -ErrorAction Stop | foreach {
$synchronizationResult = $session.SynchronizeDirectories(
[WinSCP.SynchronizationMode]::Local, $_.Destination, $_.Source, $False)
$synchronizationResult.Check()
foreach ($download in $synchronizationResult.Downloads ) {
Write-Host "File $($download.FileName) downloaded" -ForegroundColor Green
$SMTPBody +=
"`n Files: $($download.FileName -join ', ') `n" +
"Current Location: $($_.Destination)`n"
Send-MailMessage #SMTPMessage -Body $SMTPBody
}
$transferResult =
$session.GetFiles($_.Source, $_.Destination, $False, $transferOptions)
#Find the latest downloaded file
$latestTransfer =
$transferResult.Transfers |
Sort-Object -Property #{ Expression = { (Get-Item $_.Destination).LastWriteTime }
} -Descending |Select-Object -First 1
}
if ($latestTransfer -eq $Null) {
Write-Host "No files found."
$SMTPBody += "There are no new files at the moment"
}
else
{
$lastTimestamp = (Get-Item $latestTransfer.Destination).LastWriteTime
Write-Host (
"Downloaded $($transferResult.Transfers.Count) files, " +
"latest being $($latestTransfer.FileName) with timestamp $lastTimestamp.")
$SMTPBody += "file : $($latestTransfer)"
}
Write-Host "Waiting..."
Start-Sleep -Seconds 5
}
finally
{
Send-MailMessage #SMTPMessage -Body $SMTPBody
# Disconnect, clean up
$session.Dispose()
}
}
catch
{
Write-Host "Error: $($_.Exception.Message)"
}
I believe your code has more problems than you think.
Your combination of SynchronizeDirectories and GetFiles is suspicious. You first download only the new files by SynchronizeDirectories and then you download all files by GetFiles. I do not think you want that.
On any error the .Check call will throw and you will not collect the error into your report.
You keep sending partial reports by Send-MailMessage in the foreach loop
This is my take on your problem, hoping I've understood correctly what you want to implement:
$SMTPBody = ""
Import-Csv -Path "FILESOURCE.csv" -ErrorAction Stop | foreach {
Write-Host "$($_.Source) => $($_.Destination)"
$SMTPBody += "$($_.Source) => $($_.Destination)`n"
$synchronizationResult =
$session.SynchronizeDirectories(
[WinSCP.SynchronizationMode]::Local, $_.Destination, $_.Source, $False)
$downloaded = #()
$failed = #()
$latestName = $Null
$latest = $Null
foreach ($download in $synchronizationResult.Downloads)
{
if ($download.Error -eq $Null)
{
Write-Host "File $($download.FileName) downloaded" -ForegroundColor Green
$downloaded += $download.FileName
$ts = (Get-Item $download.Destination).LastWriteTime
if ($ts -gt $latest)
{
$latestName = $download.FileName;
$latest = $ts
}
}
else
{
Write-Host "File $($download.FileName) download failed" -ForegroundColor Red
$failed += $download.FileName
}
}
if ($downloaded.Count -eq 0)
{
$SMTPBody += "No new files were downloaded`n"
}
else
{
$SMTPBody +=
"Downloaded $($downloaded.Count) files:`n" +
($downloaded -join ", ") + "`n" +
"latest being $($latestName) with timestamp $latest.`n"
}
if ($failed.Count -gt 0)
{
$SMTPBody +=
"Failed to download $($failed.Count) files:`n" +
($failed -join ", ") + "`n"
}
$SMTPBody += "`n"
}
It will give you a report like:
/source1 => C:\dest1`
Downloaded 3 files:
/source1/aaa.txt, /source1/bbb.txt, /source1/ccc.txt
latest being /source1/ccc.txt with timestamp 01/29/2020 07:49:07.
/source2 => C:\dest2
Downloaded 1 files:
/source2/aaa.txt
latest being /source2/aaa.txt with timestamp 01/29/2020 07:22:37.
Failed to download 1 files:
/source2/bbb.txt
To check and make sure the csv file exists before you process the entire thing, you can use the Test-Path,
...
if (!(Test-Path D:\FileSource.csv)) {
Write-Output "No File Found"
$SMTPBody += "There are no new files at the moment"
return; # Dont run. file not found. Exit out.
}
Import-Csv -Path "D:\FILESOURCE.csv" -ErrorAction Stop | foreach {
...
and for the Body error you are getting, it is coming from the finally loop because there are cases where $SMTPBody would be null. This will no longer be an issue because $SMTPBody will have some text when file is not found at the beginning.
Even though you are using return in the if statement to check if the file exists, finally will always get executed. Since we updated $smtpbody, your Send-MailMessage will no longer error out.
Update
If you want to check if the file you are downloading already exists, you can use the if statement like this,
foreach ($download in $synchronizationResult.Downloads ) {
if (!(Test-Path Join-Path D: $download.FileName) {
$SMTPBody += "File $($download.Filename) already exists, skipping."
continue # will go to the next download...
}
Write-Host "File $($download.FileName) downloaded" -ForegroundColor Green
...
If you do get the error regarding body, thats mostly because your script came across an exception and was sent straight over to finally statement. Finally statement sends the email with empty body because it was never set (due to exception). I would recommend using the debugger (step through) and see which step causes the exception and look into adding steps to make sure script doesnt fail.

The given path's format is not supported (but it looks ok to me)

I've tried a million combinations to fix and create the directory I need, and it works when I run the powershell IDE, and when I run the task that's scheduled, but it fails overnight in the scheduled run.
Right now, this is what I'm doing, which is extremely redundant, to try and catch the issue. I can't tell where it's failing specifically in my script, since it doesn't give a line number, but I think it's the initial dir creation (see #create sub-folder location). All I can think is that this is the first time the script is run in the sequence, and it hasn't finished creating the dated parent dir when it gets to the subdir. The parent dir is fine format-wise as well.
Error message:
"Alert: Disaster Backup failed on workstation DT2. Error Message: Error in Privilege script. Length error The given path's format is not supported.The given path's format is not supported.The given path's format is not supported.Exception: System.Management.Automation.ItemNotFoundException: Cannot find path 'E:\DisasterBackup\toLoc_2019-01-30\Privileges\Privileges_1_Bak.csv' because it does not exist.
at System.Management.Automation.LocationGlobber.ExpandMshGlobPath(String path, Boolean allowNonexistingPaths, PSDriveInfo drive, ContainerCmdletProvider provider, CmdletProviderContext context)
at System.Management.Automation.LocationGlobber.ResolveDriveQualifiedPath(String path, CmdletProviderContext context, Boolean allowNonexistingPaths, CmdletProvider& providerInstance)
at System.Management.Automation.LocationGlobber.GetGlobbedMonadPathsFromMonadPath(String path, Boolean allowNonexistingPaths, CmdletProviderContext context, CmdletProvider& providerInstance)
at System.Management.Automation.LocationGlobber.GetGlobbedProviderPathsFromMonadPath(String path, Boolean allowNonexistingPaths, CmdletProviderContext context, ProviderInfo& provider, CmdletProvider& providerInstance)
"
Script:
function SQLQueryWriteToFile([string]$SQLquery, [string]$extractFile, [string]$facility)
{
#one last check that the dir exists for destination
$to_loc_final = Split-Path $extractFile
if(-Not (Test-Path $to_loc_final ))
{
write-output " Creating folder $to_loc_final because it does not exist "
$global:ErrorStrings.Add("Creating folder $to_loc_final fourth time ")
New-Item -ItemType directory -Path $to_loc_final -force
if(-Not (Test-Path $to_loc_final )) ##############
{
write-output " Creating folder $to_loc_final because it does not exist second "
$global:ErrorStrings.Add("Creating folder $to_loc_final fifth time ")
New-Item -ItemType directory -Path $to_loc_final -force
if(-Not (Test-Path $to_loc_final ))
{
write-output " Creating folder $to_loc_final because it does not exist third "
$global:ErrorStrings.Add("Creating folder $to_loc_final sixth time ")
New-Item -ItemType directory -Path $to_loc_final -force
}
}
}
[System.Data.SqlClient.SqlConnection] $sqlConnection=$null
[System.Data.SqlClient.SqlCommand] $sqlCmd=$null
try
{
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection
$sqlConnection.ConnectionString = "Server=sqlm;Database=DB;User ID=user;Password=pw" #db
$sqlConnection.Open()
#Create a SqlCommand object to define the query
$sqlCmd = New-Object System.Data.SqlClient.SqlCommand
$sqlCmd.Connection = $sqlConnection
$sqlCmd.CommandText = $SQLquery
$sqlCmd.Parameters.Add('#facility',$facility)
if($sqlConnection.State -ne 'Open'){
$global:ErrorStrings.Add("Exception: $("Couldn't connect to DB with connection string given");; ")
} #if
elseif($sqlConnection.State -eq 'Open'){
#create a SqlAdapter that actually does the work and manages everything
$sqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$sqlAdapter.SelectCommand = $sqlCmd
$sqlAdapter.SelectCommand.CommandTimeout=300 #set timeout for query execution to 5 minutes (60x5=300)
#create an empty dataSet for the query to fill with its results
$dataSet = New-Object System.Data.DataSet
#execute the query and fill the dataSet (then disconnect)
$sqlAdapter.Fill($dataSet)
$sqlConnection.Close()
#dump the data to csv
$DataSet.Tables[0] | Export-Csv $extractFile ##this is where the path error is first thrown
if($DataSet.Tables[0].Rows.Count -eq 0)
{
$result = ($SQLquery -split '[\n]')[0] #first line of query gives enough identifying info
$global:ErrorStrings.Add("Exception: $("DataSet returned empty results for query $result") ")
} #if
} #elseif
}#try
catch
{ ##I found out this is where the error is caught about path in question title
$tempMsg = "caught an error in SQL Query method:" + $_.Exception.Message
$global:ErrorStrings.Add($tempMsg)
}
finally
{
if($sqlConnection -ne $null)
{
$sqlConnection.Close()
$sqlConnection.Dispose()
}
} #finally
}
#create dated folder to put backup files in
function CreateDatedFolder([string]$name){
$datedDir = ""
$datedDir = "$name" + "_" + "$((Get-Date).ToString('yyyy-MM-dd'))"
New-Item -ItemType Directory -Path $datedDir
return $datedDir
}
################################## start here #########################################################################
$SQLquery_Privilege = #"
SELECT *
FROM "TABLEName
WHERE
Status in ('Active')
and Facility = #facility
and Last not like ('%test%')
and Last not like ('%Test%')
--ORDER BY Last
"#
$parentDirBaseName = "E:\DisasterBackup\toLoc"
$toLocParent = CreateDatedFolder $parentDirBaseName
$to_loc_final = Join-Path -Path $toLocParent -ChildPath "Privileges"
#create sub-folder location
if(-Not (Test-Path $to_loc_final ))
{
write-output " Creating folder $to_loc_final because it does not exist "
$global:ErrorStrings.Add("Creating folder $to_loc_final first time ")
New-Item -ItemType directory -Path $to_loc_final -force
if(-Not (Test-Path $to_loc_final ))
{
write-output " Creating folder $to_loc_final because it does not exist second "
$global:ErrorStrings.Add("Creating folder $to_loc_final second time ")
New-Item -ItemType directory -Path $to_loc_final -force
if(-Not (Test-Path $to_loc_final ))
{
write-output " Creating folder $to_loc_final because it does not exist third "
$global:ErrorStrings.Add("Creating folder $to_loc_final third time ")
New-Item -ItemType directory -Path $to_loc_final -force
}
}
}
$global:IT = "\\DRIVE\IT\DisasterRecovery\Privileges\"
$global:ErrorStrings = New-Object System.Collections.Generic.List[System.String]
$extractFiles = #("Privileges_0_Bak.csv","Privileges_1_Bak.csv","Privileges_2_Bak.csv")
$facCode = #("H0","H1","H2")
#Loop through list of files and facilities for Practitioner Privileges
for($i=0; $i -lt ($facCode.Length); $i++) {
$tempToLoc = Join-Path -Path $to_loc_final -ChildPath $extractFiles[$i]
SQLQueryWriteToFile $SQLquery_Privilege $tempToLoc $facCode[$i]
}
[string] $errorCodeAsString = ""
foreach ($item in $global:ErrorStrings){
$errorCodeAsString += $item
}
if($errorCodeAsString -ne "")
{
$errorCodeAsString = [string]$errorCodeAsString
$errorCodeAsString = "Error in Privilege script. Length error $errorCodeAsString.length " + $errorCodeAsString
$ScriptPath = Split-Path $MyInvocation.InvocationName
$ScriptPathFilename = Join-Path -Path $ScriptPath -Child "\EmailAlertFailure.ps1"
& $ScriptPathFilename $errorCodeAsString
Exit 99
}
Exit 0
I've looked at path format not supported
but I don't have a : in my dir path other than c: or e:, which is normal.
For example, the toLoc dir last night was:
'E:\DisasterBackup\toLoc_2019-01-30\Privileges
When I look, the E:\DisasterBackup\toLoc_2019-01-30 is there, but Privileges dir is not. This is the only script I have that is failing to create it's subdir in that folder, and it's doing it the same way. Today I copied the code exactly (for dir creation) to make sure it was the same. It runs fine in IDE and run scheduled task, but I guarantee tonight I will have the same error messages for the Privilege backup script. I checked, and the script name is correct in the task manager as well, which I expected since it runs when I run it manually. The scheduled run at night has the error given above, with resulting SQL file write failing because the subdir isn't there. Any ideas?
Update
I found out where the path error is thrown and caught. See added ## comments in the SQLQueryWriteToFile function.
I figured it out. For some reason, it wasn't treating the filename correctly. When I looked at it in the debugger, it was showing me 2 filenames with the same path, so I thought it was just a display issue. I think for some reason it was putting two same name filename paths together into an array. To fix it, I did this (see "this fixed it" comments below):
$parentDirBaseName = "E:\DisasterBackup\toLoc"
$toLocParent = CreateDatedFolder $parentDirBaseName
#create sub-folder location
$to_loc_final = Join-Path -Path $toLocParent -ChildPath "Privileges"
New-Item -type directory -path $to_loc_final -force
$global:MSS_IT = "\\DRIVE\IT\DisasterRecovery\Privileges\"
$global:ErrorStrings = New-Object System.Collections.Generic.List[System.String]
$extractFiles = #("Privileges_0_Bak.csv","Privileges_1_Bak.csv","Privileges_2_Bak.csv")
$facCode = #("H1","H2","H3")
#Loop through list of files and facilities for Practitioner Privileges
for($i=0; $i -lt ($facCode.Length); $i++) {
$tempFile = $extractFiles[$i] ###this fixed it
$extractFilePath = Join-Path -Path $to_loc_final -childpath $tempFile ###this fixed it
New-Item -path $extractFilePath -itemType file -force ###this fixed it
$extractLoc = $extractFilePath[0] ###this fixed it
SQLQueryWriteToFile $SQLquery_Privilege $extractLoc $facCode[$i] ###this fixed it
}

User input - folder and subfolder creation

I am trying to create a script to create a specific folder and subfolders based on user input in SharePoint using Powershell.
I would like to be prompted for a name in a message box. (Message Box)
This would create a folder of that name in a specified path. (New-Item -Path c:(UserInput Variable) -ItemType Directory -Force)
Then create a specific set of subfolders in the newly created folder. For Loop (get-child item)
I would also like to prevent errors if the folder is already created. -Force Flag
I've been trying to look up how to do this, but i'm not sure how to put it all together.
Here's something that I would do, it's rough and simple. I've taken some functions that already existed here on StackOverflow. Hope this helps you.
Just a polite suggestion but next time, try to include as much of the script as you can even if it's nowhere near complete.
### VARS ###
$subdirs = "Subdir1","Subdir2","Subdir3","Subdir4"
### FUNCTIONS ###
# Stole this function from https://code.adonline.id.au/folder-file-browser-dialogues-powershell/
function Find-Folders {
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
[System.Windows.Forms.Application]::EnableVisualStyles()
$browse = New-Object System.Windows.Forms.FolderBrowserDialog
$browse.SelectedPath = "C:\"
$browse.ShowNewFolderButton = $false
$browse.Description = "Choose a parent directory"
$loop = $true
while($loop)
{
if ($browse.ShowDialog() -eq "OK")
{
$loop = $false
#Insert your script here
} else
{
$res = [System.Windows.Forms.MessageBox]::Show("You clicked Cancel. Would you like to try again or exit?", "Select a location", [System.Windows.Forms.MessageBoxButtons]::RetryCancel)
if($res -eq "Cancel")
{
#Ends script
return
}
}
}
$browse.SelectedPath
$browse.Dispose()
}
# Stole this function from https://stackoverflow.com/questions/30534273/simple-inputbox-function
Function Get-NewDirName (){
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
$title = 'New Directory'
$msg = 'New directory name:'
[Microsoft.VisualBasic.Interaction]::InputBox($msg, $title)
}
### MAIN ###
$parentDir = Find-Folders
if ($parentDir) {
#Get the new directory name
$NewDirName = Get-NewDirName
if ($NewDirName) {
#Creates the parent directory
New-Item -Path $parentDir\$NewDirName -ItemType Directory
#A parent directory was found
ForEach ($dir in $subdirs) {
New-Item -Path $parentDir\$NewDirName\$dir -ItemType Directory
}
} else {
Write-Error "No directory name was specified"
}
} else {
Write-Error "No parent directory was specified"
}

Copy files to FTP and archive with today's date

I need to create a script that does the following:
Copies all files in a folder to an FTP site.
If the copy was successful move the files to an archive.
The archive should be a freshly created folder with today's date (so we know when they were transmitted).
I've tried to cannibalise other scripts to get something to work but I'm not getting anywhere so I need some help I've been working on this for hours.
I'm using the WinSCP DLL only because my other (working) script uses SFTP which needs it. I know normal FTP doesn't but I couldn't find any easily transferrable code so trying to modify that instead.
So, here's the code I have, which doesn't even run, never mind run properly, can someone help me get it right? Sorry it's a bit of a mess.
param (
$localPath = "c:\test\source",
$remotePath = "/upload",
$folder = ($_.CreationTime | Get-Date -Format yyyyMMdd)
# not sure this works but don't see how to point the destination
# to the newly created folder
$backupPath = "c:\test\destination\$folder"
)
try
{
# Load WinSCP .NET assembly
Add-Type -Path "C:\Windows\System32\WindowsPowerShell\v1.0\WinSCPnet.dll"
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property #{
Protocol = [WinSCP.Protocol]::ftp
HostName = "xxxxxxxx"
UserName = "xxxxxxxx"
Password = "xxxxxxxx"
}
$session = New-Object WinSCP.Session
try
{
# Connect
$session.Open($sessionOptions)
# Upload files, collect results
$transferResult = $session.PutFiles($localPath, $remotePath)
# Iterate over every transfer
foreach ($transfer in $transferResult.Transfers)
{
# Success or error?
if ($transfer.Error -eq $Null)
{
# If today's folder doesn't exist, create it
if (!(Test-Path $BackupPath))
{
New-Item -ItemType Directory -Force -Path $BackupPath
}
Write-Host ("Upload of {0} succeeded, moving to Uploaded folder" -f
$transfer.FileName)
# Upload succeeded, move source file to backup
Move-Item $transfer.FileName $backupPath
}
else
{
Write-Host ("Upload of {0} failed: {1}" -f
$transfer.FileName, $transfer.Error.Message)
}
}
}
finally
{
# Disconnect, clean up
$session.Dispose()
}
exit 0
}
catch [Exception]
{
Write-Host ("Error: {0}" -f $_.Exception.Message)
exit 1
}
So there's the code. I'm happy to use built in PowerShell for the FTP side to simplify it, I just want it to work.
I'm not sure what's your concern with the code. It looks pretty much ok, except for a syntax error, when setting $folder:
Why are you even trying to use $_.CreationTime as folder timestamp? Just use current date:
$folder = (Get-Date -Format "yyyyMMdd")
See Formatting timestamps in PowerShell in WinSCP documentation.
Also I do not see a point of setting $folder and $backupPath in the params block. Move it after the params block. If you want this anyway, you are missing a comma after the $folder assignment.
Other than that, your code should work.
You cannot simplify it by using the built-in PowerShell (or rather .NET) FTP functionality, as it does not have as powerful commands as WinSCP .NET assembly.
I'd write the code as:
$localPath = "C:\source\local\path\*"
$remotePath = "/dest/remote/path/"
$folder = (Get-Date -Format "yyyyMMdd")
$backupPath = "C:\local\backup\path\$folder"
# If today's folder doesn't exist, create it
if (!(Test-Path $BackupPath))
{
New-Item -ItemType Directory -Force -Path $BackupPath | Out-Null
}
try
{
# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property #{
Protocol = [WinSCP.Protocol]::ftp
HostName = "ftp.example.com"
UserName = "username"
Password = "password"
}
$session = New-Object WinSCP.Session
try
{
# Connect
$session.Open($sessionOptions)
# Upload files, collect results
$transferResult = $session.PutFiles($localPath, $remotePath)
# Iterate over every transfer
foreach ($transfer in $transferResult.Transfers)
{
# Success or error?
if ($transfer.Error -eq $Null)
{
Write-Host ("Upload of $($transfer.FileName) succeeded, " +
"moving to backup")
# Upload succeeded, move source file to backup
Move-Item $transfer.FileName $backupPath
}
else
{
Write-Host ("Upload of $($transfer.FileName) failed: " +
"$($transfer.Error.Message)")
}
}
}
finally
{
# Disconnect, clean up
$session.Dispose()
}
exit 0
}
catch [Exception]
{
Write-Host "Error: $($_.Exception.Message)"
exit 1
}
Based on Moving local files to different location after successful upload.

adding file to document library

Here is my document library looks like. I have 2 content types with my document library. 1 content type is based on Document and the other content type is based on "Link to a document" type.
I am trying to upload some files using powershell script. I am using a csv file to read line by line and upload files to document library. I am getting error on $i.fileNameASPX. Powershell tells me that Missing expression after , . So what to do.
if($i.ContentType = "LegalLink2Document")
{
$itemType = $docLibrary.ContentTypes[$i.ContentType]
$newFile = $docLibrary.RootFolder.Files.Add($i.fileNameASPX, UTF8Encoding.UTF8.GetBytes(builder.ToString()), $true)
$theItem = $newFile.Item
$theItem["ContentTypeId"] = $itemType.Id
$itemUrl = ew-object Microsoft.SharePoint.SPFieldUrlValue()
$itemUrl.Url = $i.fileLinkUrl
$itemUrl.Descrition = $i.URLDESC
$theItem["URL"] = $itemUrl
}
Here is the Simple PowerShell script to upload files to a document library in SharePoint2013
http://soreddymanjunath.blogspot.in/2014/07/add-file-to-document-library-using.html
cls
asnp "*sh*"
$url=Read-Host "Enter Site Url"
$web=Get-SPWeb -Identity $url
if($web)
{
try
{
$list = $web.Lists.TryGetList("Documents")
$files = Get-ChildItem -Path "D:\M" -Force -Recurse
foreach ($file in $files)
{
$stream = $file.OpenRead()
$done= $list.RootFolder.Files.Add($file.Name, $stream, $true)
Write-Host $done.Name "Uploaded into the Site" -BackgroundColor Green
}
}
catch
{
$ErrorMessage = $_.Exception.Message
Write-Host $ErrorMessage
}
}
else
{
Write-Host "Site Doesn't exist"
}
$list.Update();