Não é possível excluir um diretório com colchetes em nome usando o WinSCP e PowerShell
-
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
}
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.