2011-12-20 2 views
1

Я довольно новичок в Powershell, но у меня много опыта в VBScript и Python. Я пытаюсь быть хорошим администратором Windows и больше в PowerShell. Итак, вот что я пытаюсь сделать: Родительская папка содержит десятки подпапок, которые называются именами пользователей AD (например, пользователи \ username1, Users \ username2, где пользователи являются родительской папкой). Я хочу перебрать каждое имя папки, проанализировать имя подпапки и передать ее в icacls для применения разрешений на основе имени пользователя. Я сделал многострочный лайнер, потому что у меня возникали проблемы с конвейерами. Это то, что я после попытки несколько различных подходов:Powershell - вызов 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», это сработает, но я должен установить наследование с использованием параметров-нарушителей. ПОЖАЛУЙСТА ПОМОГИ. Я весь день ломаю голову над этим. Не удалось найти действительно ничего, что занимался этим вопросом специально (пытавшихся кавычку, ссылаясь на команду $ как «$» команды и т.д.)

ОШИБКА: Термин «О.» не признается в качестве имени командлет, функция, файл сценария или исполняемая программа. Проверьте орфографию имени, или если был указан путь, проверьте правильность пути и повторите попытку. В строке: 1 знак: 56 + Icacls C: \ Temp \ Test \ garthwaitm/грант домена \ user1: (О.И. < < < <) (ИО) F + CategoryInfo: ObjectNotFound: (О.И.: String) [ ], CommandNotFoundException + FullyQualifiedErrorId: CommandNotFoundException

+0

Для чего стоит, конкатенация строк намного проще, чем вы делаете это здесь. Вы также можете сделать: '$ command =" $ cmd1 $ path $ cmd2 $ last $ cmd3', а затем распечатать его, чтобы увидеть, что он работает. Каков результат, если вы просто выписываете эту переменную? – JNK

+0

Я сделал это и распечатал строка правильно.Однако, когда вызывается Invoke-Expression, он не корректно анализирует (я считаю). Я думаю, что bobbymcr получил это ниже. Спасибо хоть! –

ответ

2

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

Получить echoargs.exe от Powershell Community Extensions.

Смотрите, если что-то, как показано ниже, что вы хотели:

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}

+0

Вау, это отличная информация. Спасибо manojlds! Как я уже сказал, действительно пытался познакомиться с Powershell. Никогда не слышал об EchoArgs.exe, отлично выглядит! –

+0

@MattG. если вы не хотите загружать внешнее приложение, вы можете просто написать консольное приложение, которое печатает элементы «args». – mjsr

2

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

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

Смежные вопросы