Skip to content

Commit eed91fa

Browse files
authored
Create Invoke-WinSCPUpload.ps1
1 parent d8a0896 commit eed91fa

File tree

1 file changed

+363
-0
lines changed

1 file changed

+363
-0
lines changed

Invoke-WinSCPUpload.ps1

Lines changed: 363 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,363 @@
1+
#Requires -Version 3.0
2+
Function Invoke-WinSCPUpload {
3+
<#
4+
.SYNOPSIS
5+
This cmdlet is used to copy files to an FTP server using WinSCP
6+
7+
8+
.DESCRIPTION
9+
Use WinSCP to copy files to a destination FTP server
10+
11+
12+
.PARAMETER Protocol
13+
Define the protocol to use when connecting to the WinSCP FTP server
14+
15+
.PARAMETER Server
16+
Define the SFTP server hostname, FQDN, or IP Address
17+
18+
.PARAMETER Port
19+
Define the destination port to connect to on the WinSCP FTP server
20+
21+
.PARAMETER Path
22+
Define the files to copy to the FTP server
23+
24+
.PARAMETER Destination
25+
Define the file path on the FTP server to copy files too
26+
27+
.PARAMETER EnumerateDirectory
28+
Return the list of all files in the destination you specify on the SFTP server
29+
30+
.PARAMETER Credential
31+
Enter credentials to authenticate to the FTP server
32+
33+
.PARAMETER Username
34+
Enter the username to authenticate to the FTP server with
35+
36+
.PARAMETER Password
37+
Enter the password of the user to authenticate with
38+
39+
.PARAMETER KeyUsername
40+
Enter the username associated with the private key
41+
42+
.PARAMETER SshPrivateKeyPath
43+
Enter the file path to a PPK file containing the private key to authenticate with
44+
45+
.PARAMETER SshPrivateKeyPassPhrase
46+
Define the pass phrase used to protect the private key in the PPK file
47+
48+
.PARAMETER HostKeyPolicy
49+
Define the host key policy for previously unknown host keys
50+
51+
.PARAMETER FTPMode
52+
Define whether to use Active of Passive FTP mode
53+
54+
.PARAMETER FTPEncryption
55+
Define whether to not use encryption or use Implicit or Explicit encryption
56+
57+
.PARAMETER TrustCertificate
58+
Tells your device to trust the FTPS servers SSL certificate
59+
60+
.PARAMETER Timeout
61+
Define the connection timeout to the FTP server
62+
63+
.PARAMETER WinScpDllPath
64+
Define the location of the WinSCP NET Assembly DLL file containing the require .NET Assembly obects
65+
66+
67+
.EXAMPLE
68+
PS> Invoke-WinSCPUpload -Protocol Sftp -Server 127.0.0.1 -Credential (Get-Credential) -Path "C:\Users\Administrator\Documents\importantfile.txt","C:\Users\Administrator\Documents\otherfile2.txt" -Destination "C:\SFTP\Uploads"
69+
# This example copies the importantfile.txt and otherfile2.txt to the WinSCP destination C:\SFTP\Uploads using passive FTP over SSH (SFTP). There is a 15 second timeout to connect to the destination server and any new host keys are automatically accepted
70+
71+
.EXAMPLE
72+
PS> Invoke-WinSCPUpload -Protocol Sftp -Server 127.0.0.1 -Username admin -Password (ConvertTo-SecureString -String "Password123!" -AsPlainText -Force) -Path "C:\Users\Administrator\Documents\importantfile.txt","C:\Users\Administrator\Documents\otherfile2.txt" -Destination "C:\SFTP\Uploads" -EnumerateDirectory -FTPMode Passive -Timeout 15 -HostKeyPolicy AcceptNew -WinScpDllPath "C:\ProgramData\WinSCP\WinSCPnet.dll"
73+
# This example copies the importantfile.txt and otherfile2.txt to the WinSCP destination C:\SFTP\Uploads using passive FTP over SSH (SFTP) and lists the contents of the destination directory. There is a 15 second timeout to connect to the destination server and any new host keys are automatically accepted
74+
75+
.EXAMPLE
76+
PS> Invoke-WinSCPUpload -Protocol Ftp -FtpEncryption "Implicit" -Server 127.0.0.1 -KeyUserName admin -SshPrivateKeyPassPhrase "Keypassword123!" -SshPrivateKeyPath "C:\Users\admin\.ssh\id_rsa.ppk" -Path "C:\Users\Administrator\Documents\importantfile.txt","C:\Users\Administrator\Documents\otherfile2.txt" -Destination "C:\SFTP\Uploads" -HostKeyPolicy Check
77+
# This example copies the importantfile.txt and otherfile2.txt to the WinSCP destination C:\SFTP\Uploads using passive FTP over SSL (FTPS). There is a 15 second timeout to connect to the destination server and any new host keys will prompt for confirmation
78+
79+
.EXAMPLE
80+
PS> Invoke-WinSCPUpload -Protocol Ftp -FtpEncryption "Explicit" -Server 127.0.0.1 -Credential (Get-Credential) -Path "C:\Users\Administrator\Documents\importantfile.txt","C:\Users\Administrator\Documents\otherfile2.txt" -Destination "C:\SFTP\Uploads" -EnumerateDirectory -FTPMode Active -Timeout 15 -HostKeyPolicy GiveUpSecurityAndAcceptAny
81+
# This example copies the importantfile.txt and otherfile2.txt to the WinSCP destination C:\SFTP\Uploads using passive FTP over SSL (FTPS) and lists the contents of the destination directory. There is a 15 second timeout to connect to the destination server and any ignores host keys
82+
83+
84+
.NOTES
85+
Author: Robert H. Osborne
86+
Alias: tobor
87+
88+
89+
90+
.LINK
91+
https://github.com/tobor88
92+
https://github.com/osbornepro
93+
https://www.powershellgallery.com/profiles/tobor
94+
https://osbornepro.com
95+
https://writeups.osbornepro.com
96+
https://btpssecpack.osbornepro.com
97+
https://www.powershellgallery.com/profiles/tobor
98+
https://www.hackthebox.eu/profile/52286
99+
https://www.linkedin.com/in/roberthosborne/
100+
https://www.credly.com/users/roberthosborne/badges
101+
102+
103+
.INPUTS
104+
System.String[]
105+
106+
107+
.OUTPUTS
108+
System.String[]
109+
#>
110+
[OutputType([System.String[]])]
111+
[CmdletBinding(DefaultParameterSetName="Credential")]
112+
param(
113+
[Parameter(
114+
Mandatory=$False
115+
)] # End Parameter
116+
[ValidateSet('Sftp','Ftp')]
117+
[String]$Protocol = "Sftp",
118+
119+
[Parameter(
120+
Mandatory=$True,
121+
HelpMessage="[H] Enter the FQDN, IP address, or hostname of the WinSCP server`n [-] EXAMPLE: sftp.domain.com "
122+
)] # End Parameter
123+
[String]$Server,
124+
125+
[Parameter(
126+
Mandatory=$False,
127+
HelpMessage="[H] Enter the destination port for the WinSCP server`n [-] EXAMPLE: sftp.domain.com "
128+
)] # End Parameter
129+
[ValidateRange(0, 65535)]
130+
[Int]$Port = 0,
131+
132+
[Parameter(
133+
Mandatory=$True,
134+
ValueFromPipeline=$True,
135+
ValueFromPipelineByPropertyName=$False,
136+
HelpMessage="[H] Define all the files you to copy to the WinSCP server `n [-] EXAMPLE: 'C:\Temp\file1.txt', 'C:\file2.txt' "
137+
)] # End Parameter
138+
[String[]]$Path,
139+
140+
[Parameter(
141+
Mandatory=$True,
142+
HelpMessage="[H] Define the destination directory to copy files too on the WinSCP server `n [-] EXAMPLE: C:\Temp\ "
143+
)] # End Parameter
144+
[String]$Destination,
145+
146+
[Parameter(
147+
Mandatory=$False
148+
)] # End Parameter
149+
[Switch]$EnumerateDirectory,
150+
151+
[Parameter(
152+
Mandatory=$True,
153+
ParameterSetName="Credential"
154+
)] # End Parameter
155+
[ValidateNotNull()]
156+
[System.Management.Automation.PSCredential]
157+
[System.Management.Automation.Credential()]
158+
$Credential = [System.Management.Automation.PSCredential]::Empty,
159+
160+
[Parameter(
161+
ParameterSetName="Credentials",
162+
Mandatory=$True,
163+
HelpMessage="[H] Enter the username to authenticate to the WinSCP server with`n [-] EXAMPLE: sftpadmin "
164+
)] # End Parameter
165+
[String]$Username,
166+
167+
[Parameter(
168+
ParameterSetName="Credentials",
169+
Mandatory=$True,
170+
HelpMessage="[H] Enter the password to authenticate to the WinSCP server with for the user specified `n [-] EXAMPLE: (ConvertTo-SecureString -String 'Password123!' -AsPlainText -Force) `n [-] EXAMPLE: (Read-Host -Prompt 'Enter password' -AsSecureString) "
171+
)] # End Parameter
172+
[SecureString]$Password,
173+
174+
[Parameter(
175+
ParameterSetName="Key",
176+
Mandatory=$True,
177+
HelpMessage="[H] Enter the username to authenticate to the WinSCP server with`n [-] EXAMPLE: sftpadmin "
178+
)] # End Parameter
179+
[String]$KeyUsername,
180+
181+
[Parameter(
182+
ParameterSetName="Key",
183+
Mandatory=$True,
184+
HelpMessage="[H] Define the location of the .ppk certificate file to authenticate with `n [-] EXAMPLE: C:\Users\Administrator\.ssh\id_rsa.ppk "
185+
)] # End Parameter
186+
[ValidateScript({$_ -like "*.ppk"})]
187+
[String]$SshPrivateKeyPath,
188+
189+
[Parameter(
190+
ParameterSetName="Key",
191+
Mandatory=$True,
192+
HelpMessage="[H] Enter the SSH private key password to authenticate to the WinSCP server with `n [-] EXAMPLE: (ConvertTo-SecureString -String 'Password123!' -AsPlainText -Force) `n [-] EXAMPLE: (Read-Host -Prompt 'Enter password' -AsSecureString) "
193+
)] # End Parameter
194+
[SecureString]$SshPrivateKeyPassPhrase,
195+
196+
[Parameter(
197+
Mandatory=$False
198+
)] # End Parameter
199+
[ValidateSet('AcceptNew','GiveUpSecurityAndAcceptAny','Check')]
200+
[String]$HostKeyPolicy = "AcceptNew",
201+
202+
[Parameter(
203+
Mandatory=$False
204+
)] # End Parameter
205+
[ValidateSet('Active','Passive')]
206+
[String]$FTPMode = "Passive",
207+
208+
[Parameter(
209+
Mandatory=$False
210+
)] # End Parameter
211+
[ValidateSet('None','Implicit','Explicit')]
212+
[String]$FTPEncryption,
213+
214+
[Parameter(
215+
Mandatory=$False
216+
)] # End Parameter
217+
[Switch]$TrustCertificate,
218+
219+
[Parameter(
220+
Mandatory=$False
221+
)] # End Parameter
222+
[Int]$Timeout = 15, # Seconds
223+
224+
[ValidateNotNullOrEmpty()]
225+
[Parameter(
226+
Mandatory=$False
227+
)] # End Parameter
228+
[ValidateScript({$_.Name -eq "WinSCPnet.dll"})]
229+
[System.IO.FileInfo]$WinScpDllPath = "$env:ProgramData\WinSCP\WinSCPnet.dll"
230+
) # End param
231+
232+
BEGIN {
233+
234+
Write-Verbose -Message "[v] $(Get-Date -Format 'MM-dd-yyyy hh:mm:ss') Loading the WinSCP assembly from $WinScpDllPath"
235+
Add-Type -Path $WinScpDllPath -Verbose:$False
236+
237+
} PROCESS {
238+
239+
Write-Debug -Message "[d] $(Get-Date -Format 'MM-dd-yyyy hh:mm:ss') ParameterSetName value is $($PSCmdlet.ParameterSetName)"
240+
Switch ($PSCmdlet.ParameterSetName) {
241+
242+
'Credentials' {
243+
244+
$SessionOptions = New-Object -TypeName WinSCP.SessionOptions -Property @{
245+
Protocol = [WinSCP.Protocol]::$Protocol;
246+
PortNumber = $Port;
247+
HostName = $Server;
248+
UserName = $Username;
249+
SecurePassword = $Password;
250+
FtpMode = [WinSCP.FtpMode]::$FTPMode;
251+
Timeout = $Timeout;
252+
} # End $SessionOptions
253+
254+
} 'Key' {
255+
256+
$SessionOptions = New-Object -TypeName WinSCP.SessionOptions -Property @{
257+
Protocol = [WinSCP.Protocol]::$Protocol;
258+
PortNumber = $Port;
259+
HostName = $Server;
260+
UserName = $KeyUsername;
261+
SshPrivateKeyPath = $SshPrivateKeyPath;
262+
PrivateKeyPassphrase = $SshPrivateKeyPassPhrase;
263+
FtpMode = [WinSCP.FtpMode]::$FTPMode;
264+
Timeout = $Timeout;
265+
} # End $SessionOptions
266+
267+
} 'Credential' {
268+
269+
$SessionOptions = New-Object -TypeName WinSCP.SessionOptions -Property @{
270+
Protocol = [WinSCP.Protocol]::$Protocol;
271+
PortNumber = $Port;
272+
HostName = $Server;
273+
UserName = $Credential.Username;
274+
SecurePassword = $Credential.Password;
275+
FtpMode = [WinSCP.FtpMode]::$FTPMode;
276+
Timeout = $Timeout;
277+
} # End $SessionOptions
278+
279+
} Default {
280+
281+
Throw "[x] Unable to determine a required credential parameter set name"
282+
283+
} # End Switch Options
284+
285+
} # End Switch
286+
287+
Switch ($Protocol) {
288+
289+
'Ftp' {
290+
291+
$SessionOptions.FtpSecure = $FTPEncryption
292+
If ($TrustCertificate.IsPresent) {
293+
294+
$SessionOptions.GiveUpSecurityAndAcceptAnyTlsHostCertificate = 1
295+
296+
} # End If
297+
298+
If ($Port -eq 0 -and $SessionOptions.FtpSecure -like "Implicit") {
299+
300+
$WritePort = 990
301+
302+
} ElseIf ($Port -eq 0 -and $SessionOptions.FtpSecure -like "Explicit") {
303+
304+
$WritePort = 21
305+
306+
} Else {
307+
308+
$WritePort = $Port
309+
310+
} # End If ElseIf Else
311+
312+
} 'Sftp' {
313+
314+
$SessionOptions.SshHostKeyPolicy = [WinSCP.SshHostKeyPolicy]::$HostKeyPolicy
315+
$WritePort = 22
316+
317+
} # End Switch Options
318+
319+
} # End Switch
320+
321+
$Session = New-Object -TypeName WinSCP.Session
322+
Try {
323+
324+
Write-Verbose -Message "[v] $(Get-Date -Format 'MM-dd-yyyy hh:mm:ss') Establishing $Protocol session"
325+
$Session.Open($SessionOptions)
326+
327+
Write-Verbose -Message "[v] $(Get-Date -Format 'MM-dd-yyyy hh:mm:ss') Transferring $($Path.Count) files over SFTP connection to $Destination on $Server port $WritePort"
328+
ForEach ($File in $Path) {
329+
330+
$Session.PutFiles($File, $Destination).Check()
331+
332+
} # End ForEach
333+
334+
} Finally {
335+
336+
If ($EnumerateDirectory.IsPresent) {
337+
338+
$Directory = $Session.ListDirectory($Destination)
339+
$SubDirs = $Directory.Files.FullName
340+
341+
$Output = @()
342+
ForEach ($Sub in $SubDirs) {
343+
344+
$Output += $Sub
345+
346+
} # End ForEach
347+
348+
Write-Verbose -Message "[v] $(Get-Date -Format 'MM-dd-yyyy hh:mm:ss') $($Output.Count) items returned from $Destination"
349+
350+
} # End If
351+
352+
Write-Verbose -Message "[v] $(Get-Date -Format 'MM-dd-yyyy hh:mm:ss') Closing the $Protocol session"
353+
$Session.Dispose()
354+
355+
} # End Try Finally
356+
357+
} END {
358+
359+
Return $Output
360+
361+
} # End END
362+
363+
} # End Function Invoke-WinSCPUpload

0 commit comments

Comments
 (0)