Powershell - вызов icacls с скобками, включенными в параметры

Я новичок в Powershell, но у меня много опыта в VBScript и Python. Я пытаюсь быть хорошим администратором Windows и больше в PowerShell. Итак, вот что я пытаюсь сделать: Родительская папка содержит десятки подпапок, которые называются именами пользователей AD (например, пользователи \username1, Users\username2, где пользователи являются родительской папкой). Я хочу перебрать каждое имя папки, проанализировать имя подпапки и передать ее в icacls для применения разрешений на основе имени пользователя. Я сделал многострочный лайнер, потому что у меня возникали проблемы с конвейерами. Это то, что я получил после нескольких разных подходов:

$root_folder = "c:\temp\test"
$cmd1 = "icacls "
$cmd2 = " /grant cm\"
$cmd3 = ":`(OI`)`(CI`)F"
$paths_collection = get-childitem $root_folder | foreach-object -process {$_.FullName}
foreach ($path in $paths_collection)
{$string = $path.split("\");$last = $string[-1];$command = $cmd1 + $path +$cmd2 +$last +$cmd3;invoke-expression $command}

Первоначально это не было грубо, но я начал разламывать его, когда у меня возникали проблемы.

ПРОБЛЕМА - в $cmd3, (OI) (CI) не идет чисто в выражение invoke. Если я изменю $cmd3 на просто ": F", это сработает, но я должен установить наследование с использованием параметров-нарушителей. ПОЖАЛУЙСТА ПОМОГИ. Я весь день ломаю голову над этим. Не мог найти ничего, что касалось этой проблемы (проверенные обратные ссылки, ссылаясь на команду $как команду $и т.д.)

Ошибка: Термин "OI" не распознается как имя командлета, функции, файла script или исполняемой программы. Проверьте правописание  имени, или если путь был включен, убедитесь, что путь верен и повторите попытку. На линии: 1 char: 56 + icacls C:\temp\test\garthwaitm/grant domain\user1: (OI < lt;) (IO) F   + CategoryInfo: ObjectNotFound: (OI: String) [], CommandNotFoundException   + FullyQualifiedErrorId: CommandNotFoundException

Ответ 1

Я думаю, что вы излишне усложняете это.

Получите echoargs.exe из Расширения сообщества Powershell.

Посмотрите, нравится ли что-то вроде ниже:

PS >.\EchoArgs.exe /grant $path "cm\$last" ":(OI)(CI)F"
Arg 0 is </grant>
Arg 1 is <c:\test>
Arg 2 is <cm\user>
Arg 3 is <:(OI)(CI)F>

Затем вызовите его с помощью команды, которую вы хотите:

&icacls /grant $path "cm\$last" ":(OI)(CI)F"

Кстати, вы можете использовать Split-Path для получения $last. И используйте select -expand fullname вместо foreach-object -process {$_.FullName}

Ответ 2

Чтобы добавить к этому старому вопросу, в PowerShell 3.0 вы теперь можете использовать -%, чтобы сообщить PowerShell прекратить обработку чего-либо еще в строке, поэтому вы можете использовать что-то вроде этого:

icacls.exe $path -%/grant "Все: (OI) (CI) (F)"

Ответ 3

Пробовали ли вы использовать кавычки вокруг $command, например. Invoke-Expression "$command"? Здесь обсуждаются другие методы предотвращения обработки круглых скобок: http://msdn.microsoft.com/en-us/library/cc281841.aspx