Post a reply

Options
Add an Attachment

If you do not want to add an Attachment to your Post, please leave the Fields blank.

(maximum 10 MB; please compress large files; only common media, archive, text and programming file formats are allowed)

Options

Topic review

Stumped23

Very true. Thank you for your help!
martin

Stumped23 wrote:

Does it still return the correct path if you let the watcher process build the $localfilepath variable instead of manually specifying?

How's that relevant? You claim the problem happens even with manually specified path.
Stumped23

Does it still return the correct path if you let the watcher process build the $localfilepath variable instead of manually specifying?

According to System > About this is what I am currently running.
Edition: Windows Server 2019 Standard
Version: 1809
OS Build: 17763.4010

Not sure if build versions are playing a factor here.
martin

Ok, I've made the script working in PowerShell on Windows Server 2019.
With your exact script from the last post (I've just commented out the TlsHostCertificateFingerprint line, as that won't work), I get:
Windows PowerShell

Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Users\Administrator> cd C:\foo
PS C:\foo> powershell -file test.ps1

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
1      FileCreated                     NotStarted    False                                 ...
Local path: D:\EDI-Upload\Files\Source\test2.xlsx
Remote Path: /XXX/Co-Packer/Orders/Source/test2.xlsx

So I cannot reproduce the problem with your script.
Stumped23

Thank you for working with me on this. I'm not the best with scripting.

I'm not sure regarding the assembly in ISE. I did not have to do anything special to get it to work on my side. Just installed WinSCP in default directory and referenced the assembly file located in C:\Program Files (x86)\WinSCP in my script.

This minimal script returns the correct remote path for me...
Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
$localFilePath = "D:\EDI-Upload\Files\Source\test2.xlsx"
$remotePath = "/XXX/Co-Packer/Orders/Source/"
$localPath = "D:\EDI-Upload\Files\Source"
$remoteFilePath =
    [WinSCP.RemotePath]::TranslateLocalPathToRemote(
        $localFilePath, $localPath, $remotePath)
Write-Host $remoteFilePath

This script, where I manually specified the $remotepath, $localpath, AND $localfilepath variables, still returns the incorrect remote file path. I've removed the upload aspect of the script to test and just requested it write-host $remotefilepath. I'm not sure how to simplify further without entirely removing the watcher aspect.
$remotePath = "/XXX/Co-Packer/Orders/Source/"
$localPath = "D:\EDI-Upload\Files\Source"
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $localPath
$watcher.Filter  = "*.xlsx"
$watcher.IncludeSubdirectories = $False
$watcher.EnableRaisingEvents = $True
 
### LISTEN FOR CREATE
Register-ObjectEvent $watcher Created -SourceIdentifier FileCreated -Action {
    try
    {
        $localFilePath = "D:\EDI-Upload\Files\Source\test2.xlsx"
        # $localFilePath = $event.SourceEventArgs.FullPath
        Write-Host "Local path: $localFilePath"
 
        $assemblyPath = "C:\Program Files (x86)\WinSCP"
        Add-Type -Path (Join-Path $assemblyPath "WinSCPnet.dll")
 
        # Setup session options
        $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
            Protocol = [WinSCP.Protocol]::ftp
        FtpSecure = [WinSCP.FtpSecure]::Implicit
            HostName = ""
            UserName = ""
            Password = ""
            TlsHostCertificateFingerprint = ""
        }
 
        $session = New-Object WinSCP.Session
 
        try
        {
           $remoteFilePath = [WinSCP.RemotePath]::TranslateLocalPathToRemote(
           $localFilePath, $localPath, $remotePath)
           Write-Host Remote Path: $remoteFilePath
        }
        finally
        {
            # Disconnect, clean up
            $session.Dispose()
        }
 
    } #end of first try
    catch
    {
        Write-Host "Error: $($_.Exception.Message)"
    }
} #end of action
while ($True) {sleep 5}
martin

So can you post minimal example that still has the problem?
Or help me making the script run on Windows Server. What do I need to do to allow loading the WinSCP .NET assembly on PowerShell ISE on Windows Server?
Guest

I tested your minimal example on Server 2019. It returns the correct remote path:
/XXX/Co-Packer/Orders/Source/test2.xlsx

Given that result, I commented out the portion of my original script that automates the $localfilepath variable and manually specified instead.
$localFilePath = "D:\EDI-Upload\Files\Source\test2.xlsx"
# $localFilePath = $event.SourceEventArgs.FullPath
Write-Host "Local path: $localFilePath"

Even with the local file path manually specified, the remote path is still returned incorrectly.
Local path: D:\EDI-Upload\Files\Source\test2.xlsx

Remote Path: D:/EDI-Upload/Files/Source/test2.xlsx

Is there anything else you would like me to test? This has me stumped.
martin

Re: Script translates local path to remote differently. Depending on how the script is initiated.

I wanted to test it, but I was not able to even load the WinSCPnet.dll in PowerShell ISE on Windows Server. I've getting "Could not load file or assembly ... Operation is not supported". I know the error, but I do not have the "Unblock" button on Windows Server.

Anyway, can you post minimal example? Or what do you get with this simple example?
Add-Type -Path ".\WinSCPnet.dll"
$localFilePath = "D:\EDI-Upload\Files\Source\test2.xlsx"
$remotePath = "/XXX/Co-Packer/Orders/Source/"
$localPath = "D:\EDI-Upload\Files\Source"
$remoteFilePath =
    [WinSCP.RemotePath]::TranslateLocalPathToRemote(
        $localFilePath, $localPath, $remotePath)
Write-Host $remoteFilePath

So far I cannot imagine that the RemotePath.TranslateLocalPathToRemote code could be returning different results on different systems. It's purely a string computation code. It does not use any system functions.
Stumped23

Script translates local path to remote differently. Depending on how the script is initiated.

I'm running into an issue adapting the script located below to my environment. I suspect the issue lies in the TranslateLocalPathToRemote portion of the script. The RemoteFilePath is translated differently depending on how the PowerShell script is ran.

  • Running locally on my machine, Windows 11, it returns what I expect and works fine.
  • Running it via PowerShell ISE on Server 2019, it returns what I expect and works fine.
  • Running it via PowerShell, on Server 2019 returns a different path and fails.

I've attached screenshots showing the different returned remote paths.

Is this a bug? If not, what is the best way to handle this situation?

Thanks!

# Watches a directory for new files and
# fires off the batch file to push to connection
 
$processedfiles = "D:\EDI-Upload\Files\ProcessedFiles"
$remotePath = "/XXX/Co-Packer/Orders/Source/"
$localPath = "D:\EDI-Upload\Files\Source"
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $localPath
$watcher.Filter  = "*.xlsx"
$watcher.IncludeSubdirectories = $False
$watcher.EnableRaisingEvents = $True
 
### LISTEN FOR CREATE
Register-ObjectEvent $watcher Created -SourceIdentifier FileCreated -Action {
    try
    {
        $localFilePath = $event.SourceEventArgs.FullPath
        Write-Host "Local path: $localFilePath"
 
        $assemblyPath = "C:\Program Files (x86)\WinSCP"
        Add-Type -Path (Join-Path $assemblyPath "WinSCPnet.dll")
 
        # Setup session options
        $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
            Protocol = [WinSCP.Protocol]::ftp
            FtpSecure = [WinSCP.FtpSecure]::Implicit
            HostName = ""
            UserName = ""
            Password = ""
            TlsHostCertificateFingerprint = ""
        }
 
        $session = New-Object WinSCP.Session
 
        try
        {
            $remoteFilePath = [WinSCP.RemotePath]::TranslateLocalPathToRemote(
                    $localFilePath, $localPath, $remotePath)
 
            Write-Host "Remote path: $remoteFilePath"
 
            # Connect
            $session.Open($sessionOptions)
 
            $session.PutFiles($localFilePath, $remoteFilePath).Check()
 
            Write-Host "Upload of $localFilePath succeeded"
 
            move-item "$localfilepath" "$ProcessedFiles"
        }
        finally
        {
            # Disconnect, clean up
            $session.Dispose()
        }
 
    } #end of first try
    catch
    {
        Write-Host "Error: $($_.Exception.Message)"
    }
} #end of action
while ($True) {sleep 5}