Мне вчера на почту пришёл комментарий на пост: Смена владельца папки или файла в 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 (`). Его заэскейпить не представляется возможным, поэтому единственный выход с ним – прописывать путь в одинарных кавычках, чтобы этот мета-символ использовался в качестве литерала. В связи с чем я немного подрихтовал пост, ссылка на который приведена в начале этого поста.
Comments: