Contents of this directory is archived and no longer updated.

Мне вчера на почту пришёл комментарий на пост: Смена владельца папки или файла в PowerShell (часть 2), в котором сообщалось об ошибке, которую генерирует скрипт, если в пути есть служебные мета-символы, как апостроф (одиночкая кавычка). А дело было в том, что этот мета-символ нужно дополнительно эскейпить (помимо обратных слешей в пути). То же касается и квадратных скобок. Одиночные кавычки эскейпятся очень просто – одним обратным слешем:

PS C:\> $path = "C:\Users\vPodans\text'text.txt"
PS C:\> $path = $path -replace "\\|'", '\$0'
PS C:\> $path
C:\\Users\\vPodans\\text\'text.txt
PS C:\> gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'"


__GENUS          : 2
__CLASS          : Win32_LogicalFileSecuritySetting
__SUPERCLASS     : Win32_SecuritySetting
__DYNASTY        : CIM_Setting
__RELPATH        : Win32_LogicalFileSecuritySetting.Path="C:\\Users\\vPodans\\text'text.txt"
<...> 

Но с квадратными скобками такой фокус не прошёл:

PS C:\> $path = "C:\Users\vPodans\text[text.txt"
PS C:\> $path = $path -replace "\\|\[", '\$0'
PS C:\> $path
C:\\Users\\vPodans\\text\[text.txt
PS C:\> gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'"
Get-WmiObject : Invalid query
At line:1 char:5
+ gwmi <<<<  Win32_LogicalFileSecuritySetting -filter "path='$path'"
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], ManagementException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

PS C:\>

попытка заэскейпить квадратные скобки при помощи бэктика (`) успехом не увенчалась:

PS C:\> $path = "C:\Users\vPodans\text[text.txt"
PS C:\> $path = $path -replace "\\", '\$0'
PS C:\> $path = $path -replace "\[", '`$0'
PS C:\> gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'"
PS C:\>

он вообще файл не нашёл так. На удачу решил опробовать хитрый вариант – не эскейпить символ, а вписать его char номер из таблицы ASCII. И вот что у меня вышло:

PS C:\> $path = "C:\Users\vPodans\text[text.txt"
PS C:\> $path = $path -replace "\\", '\$0'
PS C:\> [int][char]"["
91
PS C:\> $path = $path -replace "\[", "$([char]91)"
PS C:\> $path
C:\\Users\\vPodans\\text[text.txt
PS C:\> gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'"


__GENUS          : 2
__CLASS          : Win32_LogicalFileSecuritySetting
__SUPERCLASS     : Win32_SecuritySetting
__DYNASTY        : CIM_Setting
__RELPATH        : Win32_LogicalFileSecuritySetting.Path="C:\\Users\\vPodans\\text[text.txt"
<...>

И этот финт сработал! Тот же самый манёвр делается и для второй квадратной скобки:

PS C:\> $path = "C:\Users\vPodans\text[text].txt"
PS C:\> $path = $path -replace "\\", '\$0'
PS C:\> $path = $path -replace "\[", "$([char]91)"
PS C:\> [int][char]"]"
93
PS C:\> $path = $path -replace "\]", "$([char]93)"
PS C:\> $path
C:\\Users\\vPodans\\text[text].txt
PS C:\> gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'"


__GENUS          : 2
__CLASS          : Win32_LogicalFileSecuritySetting
__SUPERCLASS     : Win32_SecuritySetting
__DYNASTY        : CIM_Setting
__RELPATH        : Win32_LogicalFileSecuritySetting.Path="C:\\Users\\vPodans\\text[text].txt"
<...>

Но в именах файлов и папок может содержаться один коварный символ – backtick (`). Его заэскейпить не представляется возможным, поэтому единственный выход с ним – прописывать путь в одинарных кавычках, чтобы этот мета-символ использовался в качестве литерала. В связи с чем я немного подрихтовал пост, ссылка на который приведена в начале этого поста.


Share this article:

Comments:

Comments are closed.