June 1, 2017 at 9:06 am
I'm newish to Powershell and got bits of this code off the internet. I thought that using a Foreach-Object and Get-ChildItem together would automatically terminate my loop after the last file was sent, but unfortunately it appears the script is still trying to grab additional items. There are more items in the folder than just the group of files I'm grabbing, but again, I thought I defined specifically which items I want to grab. Can someone point out where I went wrong and how to stop my error?
Error is:
Foreach-Object : Cannot bind argument to parameter 'Path' because it is null.
AT \\Myfolderpath\folder1\folder2\MyPwrshllScript.ps1:20 char:5
+ Foreach-Object {
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: ( : ) [Foreach-Object], ParameterBindingValidationException
+ FullyQualifiedErrorID : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ForEachObjectCommand
A note on my file names. They are basically MyFileName_ACB_FileX_YYYYMMDD.txt with the X part of the file name being a file number. I run this script from an SSIS package which determines the number of files to create at runtime, so I could pass in that variable if I need to, but I'd rather leave it to grab all files, if I could.
My code is:
$erroractionpreference = "Stop"
# Load WinSCP .NET assembly
[Reflection.Assembly]::LoadFrom("\\ServerName\D$\Program Files\WinSCP\WinSCPnet.dll")
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions
$sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
$sessionOptions.HostName = "Myhost.com"
$sessionOptions.UserName = "MyLogin"
$sessionOptions.Password = "MyPwd"
$sessionOptions.GiveUpSecurityAndAcceptAnySshHostKey = "true"
# $sessionOptions.SshHostKeyFingerprint = "*"
$remotePath = "/LandingZone/Folder1"
$localPath = "\\Myfolderpath\folder1\folder2"
# Set up Loop for SFTP
Get-ChildItem "\\Myfolderpath\folder1\folder2" -Filter MyFileName_ACB_*
Foreach-Object {
$content = Get-Content $_.FullName
$localFile = "$($localPath) + $($content)"
$remoteFile = "$($remotePath) + $($content)"
# Create Session
$session = New-Object WinSCP.Session
# Connect
$session.Open($sessionOptions)
# Upload files
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.TransferMode = [WinSCP.TransferMode]::Ascii
$transferOptions.PreserveTimestamp = $FALSE
$transferResult = $session.PutFiles("$localFile", "$remoteFile", $FALSE, $transferOptions)
# Throw on any error
$transferResult.Check()
# Get date for log
$LogTime = Get-Date -Format "MM-dd-yyyy_hh:mm:ss"
}
# Print results
foreach ($transfer in $transferResult.Transfers)
{
Write-Output ($LogTime + " Upload of {0} succeeded" -f $transfer.FileName) | Out-File -FilePath \\Myfolderpath\folder1\folder2\SFTP_Log.txt -Append
}
# Disconnect, clean up
if (!($session))
{
$session.Dispose()
}
What am I missing here?
June 1, 2017 at 11:30 am
I think you might need to pipe the output of the get-childitem into the foreach-object:Get-ChildItem "\\Myfolderpath\folder1\folder2" -Filter MyFileName_ACB_*| Foreach-Object {
The other method (I believe) would be to put the results of the get-childitem into a variable and then have the foreach-object work on that.
Not sure on that though.
June 2, 2017 at 4:36 am
jasona.work - Thursday, June 1, 2017 11:30 AMI think you might need to pipe the output of the get-childitem into the foreach-object:Get-ChildItem "\\Myfolderpath\folder1\folder2" -Filter MyFileName_ACB_*| Foreach-Object {
The other method (I believe) would be to put the results of the get-childitem into a variable and then have the foreach-object work on that.
Not sure on that though.
I was going to say "Is that not what my code is doing?" and then I realized I don't have a pipe in there.
Trying this now. And since it's taking more than a few seconds to work on the first file this time around (they are large files), you may have resolved my issue... But I'll let you know later, after my code has finished running.
June 2, 2017 at 4:46 am
GAH. Spoke too soon. New error.
Foreach-Object : Exception calling "PutFiles" with "4" argument(s): "Exception of type 'System.OutOfMemoryException' was thrown."
At \\Myfolderpath\folder1\folder2\MyPwrshllScript.ps1:19\\Myfolderpath\folder1\folder2\MyPwrshllScript.ps1:19 char:114
+ ... " -Filter MyFileName_ACB_* | Foreach-Object {
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ForEach-Object], MethodInvocationException
+ FullyQualifiedErrorId : OutOfMemoryException,Microsoft.PowerShell.Commands.ForEachObjectCommand
This is after changing this section of codeGet-ChildItem "\\Myfolderpath\folder1\folder2" -Filter MyFileName_ACB_*
Foreach-Object {
To this section of codeGet-ChildItem "\\Myfolderpath\folder1\folder2" -Filter MyFileName_ACB_* | Foreach-Object {
Everything else is the same. Thoughts?
June 2, 2017 at 8:36 am
Well, we've moved the error further down.
I don't have WinSCP loaded anywhere, I'll look at spinning up a VM later today and loading it there to give some testing. How big are these files you're moving around? I'm wondering if possibly either creating the WinSCP session inside the foreach-object loop is causing you to run out of RAM, or if the files are just too big and need to be split into smaller files.
Which also raises the question, for me to test, how much RAM in the box you're doing this on?
And, what is the OS?
June 2, 2017 at 11:01 am
Well my boss finally got out of his eternal meeting schedule so I asked him to take a look and he's altered it to do a FOR loop. That eliminated the error messages, unfortunately the code doesn't actually send anything so we're poking around to figure out why no errors but no workie either. If we get the newer version functional, I'll post that.
Viewing 6 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic. Login to reply
This website stores cookies on your computer.
These cookies are used to improve your website experience and provide more personalized services to you, both on this website and through other media.
To find out more about the cookies we use, see our Privacy Policy