无法使用WinSCP和PowerShell删除名称中带方括号的目录

时间:2014-02-26 04:47:38

标签: powershell winscp winscp-net

我正在尝试编写一个自动删除FTP服务器上的空目录的PowerShell脚本。我没有任何直接访问目录所在的服务器 - 我只能通过FTP访问它们。出于这个原因,我编写了一个PowerShell脚本,它使用WinSCP .NET程序集(尝试)删除空目录。但是,我有一个问题,因为服务器上的许多目录在目录名中都有方括号。

例如,可能会调用目录名称:[a]153432

这些目录很多,因此我希望编写一个脚本来删除它们。发生这种情况是因为它们是由程序创建的,该程序使用数字来创建所需的目录。为了处理这个程序,我创建了一个空目录

/latest/[b]test

我的程序是这样的:

# program to test deletion of directories with square-brackets in the name.

$HOSTNAME="myftpservername"
$USERNAME="myftpusername"
$PASSWORD="myftppassword"
$DLL_LOCATION="C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
$LOCAL_DIRECTORY="C:\testdir\extended\baseroot"

# Load WinSCP .NET assembly
[Reflection.Assembly]::LoadFrom($DLL_LOCATION) | Out-Null

# Session.FileTransferred event handler

try
{
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.Protocol = [WinSCP.Protocol]::ftp
    $sessionOptions.HostName = $HOSTNAME
    $sessionOptions.UserName = $USERNAME
    $sessionOptions.Password = $PASSWORD

    $session = New-Object WinSCP.Session
    try
    {
        # Connect
        $session.Open($sessionOptions)

        $remoteFileWithUnixPath = "/latest/[b]test"

        $removalResult = $session.RemoveFiles($remoteFileWithUnixPath)
        if ($removalResult.IsSuccess)
        {
            Write-Host ("Removal of remote file {0} succeeded" -f $remoteFileWithUnixPath)
        }
        else
        {
            Write-Host ("Removal of remote file {0} failed" -f $remoteFileWithUnixPath)
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}

当我运行它时,它会显示以下消息:

PS C:\Users\dbuddrige\Documents\dps> .\delete-squarebracket-dir.ps1
Removal of remote file /latest/[b]test succeeded

但是,目录不会被删除。

我还尝试使用分隔符指定目录名称,例如:

$remoteFileWithUnixPath = "/latest/\[b\]test"

但这也失败了(但至少它是这样说的):

PS C:\Users\dbuddrige\Documents\dps> .\delete-squarebracket-dir.ps1
Removal of remote file /latest/\[b\]test failed

但是,如果我将目录名[和变量$remoteFileWithUnixPath]更改为

/latest/foo

然后重新运行程序,删除目录/latest/foo就好了。

有没有人有任何想法我需要做些什么才能让它发挥作用?


Martin Prikryl指出了这个问题的答案[谢谢!]

完整工作的代码如下:

# program to test deletion of directories with square-brackets in the name.

$HOSTNAME="myftpservername"
$USERNAME="myftpusername"
$PASSWORD="myftppassword"
$DLL_LOCATION="C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
$LOCAL_DIRECTORY="C:\testdir\extended\baseroot"

# Load WinSCP .NET assembly
[Reflection.Assembly]::LoadFrom($DLL_LOCATION) | Out-Null

# Session.FileTransferred event handler

try
{
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.Protocol = [WinSCP.Protocol]::ftp
    $sessionOptions.HostName = $HOSTNAME
    $sessionOptions.UserName = $USERNAME
    $sessionOptions.Password = $PASSWORD

    $session = New-Object WinSCP.Session
    try
    {
        # Connect
        $session.Open($sessionOptions)

        $remoteFileWithUnixPath = "/latest/[b]test"

        $removalResult = 
            $session.RemoveFiles($session.EscapeFileMask($remoteFileWithUnixPath))
        if ($removalResult.IsSuccess)
        {
            Write-Host ("Removal of remote file {0} succeeded" -f $remoteFileWithUnixPath)
        }
        else
        {
            Write-Host ("Removal of remote file {0} failed" -f $remoteFileWithUnixPath)
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}

2 个答案:

答案 0 :(得分:1)

WinSCP .NET程序集的某些方法(包括Session.RemoveFiles)接受文件掩码,而不是简单路径。

方括号在file mask中具有特殊含义。

在将它们传递给汇编方法之前,您应该始终在文件路径上使用RemotePath.EscapeFileMask method

答案 1 :(得分:0)

我在命令行中使用转义序列:

Remove-Item 'C:\Scripts\Test`[1`].txt'

或使用-LiteralPath参数。

Remove-Item -LiteralPath C:\scripts\test[1].txt

-LiteralPath参数不会尝试转换字符串。