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