Upload files to an FTP Server using powershell - powershell

I have the following code to upload a file to an FTP Server via powershell but it's giving me this error:
Code:
$Directory=”C:\test”
#FTP server configuration
$ftpserver = “ftp://ftpserver/”
$username = “user”
$password = “pw”
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object System.Net.NetworkCredential($username,$password)
#Copy each file which type is *.tx*
foreach($file in (dir $Directory “*.txt*”)){
“Uploading $file…”
$uri = New-Object System.Uri($ftpserver+$file.Name)
$webclient.UploadFile($uri, $file.FullName)
}
Error:
Exception calling "UploadFile" with "2" argument(s): "Excepção durante um pedido WebClient."
At C:\Users\home\Desktop\test6.ps1:16 char:1
+ $webclient.UploadFile($uri, $file.FullName)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException

Try it like so:
$Directory = "C:\test"
#FTP server configuration
$ftpserver = "ftp://ftpserver/"
$username = "user"
$password = "pw"
$ftpserverURI = New-Object -TypeName System.Uri -ArgumentList $ftpserver, [System.UriKind]::Absolute
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object -TypeName System.Net.NetworkCredential -ArgumentList $username, $password
#Copy each file which type is *.tx*
Get-ChildItem $Directory -Filter *.txt* | ForEach-Object {
Write-Host "Uploading $($_.FullName)..."
$uri = New-Object -TypeName System.Uri -ArgumentList $ftpserverURI, $_.Name
$webclient.UploadFile($uri, [System.Net.WebRequestMethods+Ftp]::UploadFile, $_.FullName)
}
The differences are that I'm making System.Uri combine the path instead of relying on string concatenation, and I'm telling WebClient.UploadFile() the method to use when uploading the file.
If this doesn't work, then I agree with the comments that you should examine the server logs. If you can't, then try it against a server that you can see the logs for. Alternately, you may want to try to use WinSCP, which is also scriptable with PowerShell or with a custom script file. WinSCP has the advantage of supporting FTP, FTPS, and SFTP, as well. The .Net WebClient only natively supports plain FTP, as far as I'm aware.
As far as smart quotes, they work just fine on Windows PowerShell (<= v5.x), but they don't work at all on PowerShell Core (v6+). I would avoid using them to make your code more portable and more future proof.

Related

Powershell Import-Clixml from a shared network folder using full UNC - The system cannot find the file specified

I am trying to run a powershell script inside a SQL Agent job. I keep getting the error: Import-Clixml : The system cannot find the file specified. At \Data\Powershell\Collibra\Dev\test.ps1:95 char:21 + ... redential = Import-Clixml -Path Filesystem::\Data\Powershell... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Import-Clixml], Cryptographic Exception + FullyQualifiedErrorId : System.Security.Cryptography.CryptographicExcept ion,Microsoft.PowerShell.Commands.ImportClixmlCommand
$Credential = Import-Clixml -Path
Filesystem::\\energy\data\apps\BISharedServices\Powershell\Collibra\Dev\credentials.xml
$username = $Credential.GetNetworkCredential().UserName
$password = $Credential.GetNetworkCredential().Password
$credPair = "$($username):$($password)"
$encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credPair))
$H = #{ Authorization = "Basic $encodedCredentials" }
I have tried mapping a new drive and doing a set-location. Same results. This is driving me nuts!
Thanks for the help.
In basic Powershell without SSIS at least, it's only one slash at the beginning:
Import-Clixml -Path FileSystem::\path\to\file.txt

PowerShell Usage - File Upload Directory

I am hoping to get some assistance on PowerShell usage for HTTPS file upload. My current task to automate the copying of a directory of PDF file from a local network path to a HTTPS:// website. Whilst I have a local account on the web server, I have an issue with file upload and recursing the list all PDF's.
I tried Invoke-RestMethod -URI
$sourceFilePath = Get-ChildItem "\\DFS-Netwrok\PDF" -Recurse -Include *.pdf
$siteAddress = "https://contoso.com/PDF";
$urlDest = "{0}/{1}" -f ($siteAddress, "*.pdf");
$UserName = "UserName"
$Password = "Password"
function uploadFile() {
Param ([string] $sourceFilePath,
[string] $siteAddress ,
[string] $urlDest,
[string] $UserName,
[string] $Password)
$webClient = New-Object System.Net.WebClient;
$webClient.Credentials = New-Object System.Net.NetworkCredential($UserName,$Password);
("*** Uploading {0} file to {1} ***" -f ($sourceFilePath, $siteAddress) ) | write-host -ForegroundColor Green
$webClient.UploadFile($urlDest, "PUT", $sourceFilePath);
$httpresponse = $httprequest.GetResponse()
}
Upload-File -File $SourceFilePath -URI $SiteAddress -Dest $URLDest -Username $MyUsername -Password $MyPassword
Currently I get error on Upload-File.
I am happy to convert to any code which can provide the above task, list PDF from internal path connect to website with User/Pass and upload all PDF from local Directory. I can confirm the account can connect and has correct permissions on the destination website URL.
I am also looking at this example with error "Forbidden":
$Dir="\\Netwrok\Path"
$Url = "https://Website/PDF"
$user = "User"
$pass = "Password"
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass)
foreach($item in (dir $Dir "*.pdf"))
{
"Uploading $item..."
$uri = New-Object System.Uri($Url+$item.Name)
$webclient.UploadFile($uri, $item.FullName)
}
Returns error:
Exception calling "UploadFile" with "2" argument(s): "The remote server
returned an error: (403) Forbidden."
At line:16 char:22
+ $webclient.UploadFile($uri, $item.FullName)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException

Using special characters (slash) in FTP credentials with WebClient

EDIT: I have discovered it's definitely the password that is causing issues. I have a forward slash in my password and cannot figure out how to get this to accept it. I've already tried replacing it with %5B. Changing the password is not a possibility.
cd v:
$username = "*********"
$password = "*********"
$usrpass = $username + ":" + $password
$webclient = New-Object -TypeName System.Net.WebClient
function ftp-test
{
if (Test-Path v:\*.204)
{
$files = Get-ChildItem v:\ -name -Include *.204 | where { ! $_.PSIsContainer } #gets list of only the .204 files
foreach ($file in $files)
{
$ftp = "ftp://$usrpass#ftp.example.com/IN/$file"
Write-Host $ftp
$uri = New-Object -TypeName System.Uri -ArgumentList $ftp
$webclient.UploadFile($uri, $file)
}
}
}
ftp-test
When I run the above code I get
Exception calling "UploadFile" with "2" argument(s): "An exception occurred during a WebClient request."
At line:13 char:34
+ $webclient.UploadFile <<<< ($uri, $file)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
I'm not sure what the issue is. Searching has brought issue with proxies, but I have no proxy that I need to get through.
I can manually upload the file with ftp.exe, but I'd rather do all this in PowerShell if possible instead of generating a script to use ftp.exe with.
You have to URL-encode the special characters. Note that encoded slash (/) is %2F, not %5B (that's [).
Instead of hard-coding encoded characters, use Uri.EscapeDataString:
$usrpass = $username + ":" + [System.Uri]::EscapeDataString($password)
Or use the WebClient.Credentials property, and you do not need to escape anything:
$webclient.Credentials =
New-Object System.Net.NetworkCredential($username, $password)
...
$ftp = "ftp://ftp.example.com/IN/$file"
Similarly for (Ftp)WebRequest: Escape the # character in my PowerShell FTP script

powershell doesn't install AzurePowerShell

I found script on internet, which install WindowsAzurePowerShell, but it doesn't work:
[reflection.assembly]::LoadWithPartialName("Microsoft.Web.PlatformInstaller") | Out-Null
$ProductManager = New-Object Microsoft.Web.PlatformInstaller.ProductManager
$ProductManager.Load()
$product = $ProductManager.Products | Where { $_.ProductId -eq "WindowsAzurePowerShell" }
$InstallManager = New-Object Microsoft.Web.PlatformInstaller.InstallManager
$Language = $ProductManager.GetLanguage("en")
$installertouse = $product.GetInstaller($Language)
$installer = New-Object 'System.Collections.Generic.List[Microsoft.Web.PlatformInstaller.Installer]'
$installer.Add($installertouse)
$InstallManager.Load($installer)
$failureReason=$null
foreach ($installerContext in $InstallManager.InstallerContexts) {
$InstallManager.DownloadInstallerFile($installerContext, [ref]$failureReason)
}
$InstallManager.StartInstallation()
I see exception:
Exception calling "DownloadInstallerFile" with "2" argument(s): "The InstallerContext passed to this method requires a non-Null InstallerFile."
At C:\Users\test.ps1:18 char:5
+ $InstallManager.DownloadInstallerFile($installerContext, [ref]$failureReason ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : InvalidOperationException
So. How it's fixed?
This example I have put together below doesn't go about installing that package the way you where attempting but instead downloads the WebPi CLI, extracts the zip and runs it in an elevated prompt then returns an exit code. I think this will get the job done and can be reproduced on all boxes that may not have the WebPI installed as you can place the file on a share and run this across many computers.
$SourcePath = "http://www.iis.net/community/files/webpi/webpicmd_x86.zip"
$DestinationPath = "c:\Temp\webpicmd_x86.zip"
$ExtractionPath = "c:\Temp\WebPICmd"
$CWebPiCmdLineTool = "$ExtractionPath\WebpiCmdLine.exe"
Import-Module BitsTransfer
Start-BitsTransfer -Source $SourcePath -Destination $DestinationPath
New-Item -Path C:\Temp -Name WebPICmd -ItemType directory | Out-Null
$shell = new-object -com shell.application
$zip = $shell.NameSpace($DestinationPath)
foreach($item in $zip.items())
{
$shell.Namespace($ExtractionPath).copyhere($item)
}
$InstallWebPiPackages = Start-Process -FilePath $CWebPiCmdLineTool -ArgumentList "/Products:WindowsAzurePowerShell" -Verb "RunAs" -Wait -PassThru
$InstallWebPiPackages.ExitCode

Powershell CMDLET Cross Domain Managment

I'm logged in at domain "domain1" with my account. I wish via powershell to be able to update users in domain "domain2" via my supe ruser account "suaccount" with password "password1". Trust is established between the two.
Running PowerShell 2.0 and .NET 3.5 SP1
I have gotten this far:
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ctype = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$context = New-Object -TypeName
System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, "domain2", "OU=TestOU,DC=domain2", "suaccount", "password1"
$usr = New-Object -TypeName System.DirectoryServices.AccountManagement.UserPrincipal -ArgumentList $context
$usr.Name = "AM Test1"
$usr.DisplayName = "AM Test1"
$usr.GivenName = "AM"
$usr.SurName = "Test1"
$usr.SamAccountName = "AMTest1"
$usr.UserPrincipalName = "amtest1#mtest.test"
$usr.PasswordNotRequired = $false
$usr.SetPassword("errr")
$usr.Enabled = $true
$usr.Save()
Pretty new to PowerShell, any pointers? I want to edit/create users on the "other" domain so to speak.
I get the error:
"Exception calling "Save" with "0" argument(s): "General access denied error
"
At C:\Script\Sandbox\Morris PowerShell Application\includes\mo\mo.ps1:104 char:14
+ $usr.Save <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException"
Any pointers?
From comments: Try using for username this format domain2\username, and always use the FQDN for the domain. – Christian yesterday