Não é possível excluir um diretório com colchetes em nome usando o WinSCP e PowerShell

StackOverflow https://stackoverflow.com//questions/22032008

  •  21-12-2019
  •  | 
  •  

Pergunta

Eu estou tentando escrever um script PowerShell que automaticamente apaga diretórios vazios no nosso servidor FTP.Eu não tenho qualquer acesso direto ao servidor no qual a diretórios residem - eu só posso acessá-los via FTP.Por este motivo, escrevi um script PowerShell que utiliza o WinSCP .LÍQUIDO de montagem para (tentar) excluir os diretórios vazios.No entanto, eu tenho um problema, em que muitos dos diretórios no servidor ter colchetes no nome do diretório.

Por exemplo, o nome do diretório pode ser chamado de: [a]153432

Existem muitos destes diretórios, daí o meu desejo de escrever um script para eliminá-los.Isso ocorre porque eles foram criados por um programa que usa um número de criar os diretórios que ele requer.Para trabalhar com este programa, eu criei um diretório vazio

/latest/[b]test

Meu programa vai como esta:

# 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
}

Quando eu executá-lo, ele exibe a seguinte mensagem:

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

No entanto, a pasta não é apagada.

Eu também tentei especificar o nome do diretório com delimitadores, tais como:

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

Mas isso também falha (mas pelo menos ele diz isso):

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

MAS, se eu mudar o nome do diretório [e a variável $remoteFileWithUnixPath] para algo como

/latest/foo

E, em seguida, volte a executar o programa, ele exclui o diretório /latest/foo muito bem.

Alguém tem alguma idéia do que eu preciso fazer para chegar a este trabalho?


A resposta a esta pergunta foi apontado por Martin Prikryl [Obrigada!]

Totalmente de trabalho código a seguir:

# 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
}
Foi útil?

Solução

Alguns métodos do WinSCP .LÍQUIDO de montagem, incluindo o Session.RemoveFiles, aceita um arquivo de máscara, não é um caminho simples.

Colchetes têm um significado especial no máscara de ficheiro.

Você deve sempre usar o RemotePath.EscapeFileMask método em caminhos de arquivo, antes de passá-los para métodos de montagem.

Outras dicas

Eu gostaria de usar a seqüência de escape na linha de comandos:

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

Ou use o -LiteralPath o parâmetro.

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

O parâmetro LiteralPath não tenta converter a seqüência de caracteres.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top