PowerShell = не распознанная ошибка командлета

В дополнение к приведенному здесь ответу: Ошибка поиска пути входа в сеанс PowerShell, в моем сценарии я наткнулся на еще одну стену, которую я не могу обойти. Следующий скрипт возвращает ошибку:

Термин '=' не распознается как имя командлета, функции, файла сценария или работающей программы. Проверьте написание имени или, если был включен путь, убедитесь, что путь правильный, и повторите попытку.

$sb = [ScriptBlock]::Create(@"
$Acl = (Get-Item -path D:\Websites\$Sitename).GetAccessControl('Access')
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule('BUILTIN\IIS_IUSRS', 'Modify', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
$Acl.SetAccessRule($Ar)
Set-Acl -path $Path -AclObject $Acl
"@)

Invoke-Command -Session $Session -ScriptBlock $sb

Я могу создать переменную блока скрипта ($ sb), но когда я вызываю ее, я получаю сообщение об ошибке. Я сузил его до настройки переменной $Acl и безуспешно пытался переписать разными способами. Что мне не хватает?


person Karl    schedule 05.09.2017    source источник
comment
Измените @""@ на @''@ (здесь строки заключаются в одинарные кавычки, а не в двойные)   -  person Mathias R. Jessen    schedule 05.09.2017
comment
Это не сработает, поскольку переменная $ sitename передается в блок скрипта, поэтому ее нужно расширить? Мне нужно, чтобы переменные $ acl, $ ar $ acl и $ path обрабатывались как переменные, но чтобы переменная $ sitename была расширена   -  person Karl    schedule 05.09.2017
comment
Я обновил свой ответ, чтобы учесть это.   -  person Mathias R. Jessen    schedule 05.09.2017


Ответы (1)


Когда вы используете здесь-строку в двойных кавычках, она ведет себя так же, как обычная строка в двойных кавычках - синтаксический анализатор будет оценивать и расширять любую переменную или подвыражение между кавычками.

Поскольку переменные в определении блока сценария еще не существуют в определяющем контексте, вы получаете блок сценария со следующим определением:

 = (Get-Item -path D:\Websites\).GetAccessControl('Access')
 = New-Object System.Security.AccessControl.FileSystemAccessRule('BUILTIN\IIS_IUSRS', 'Modify', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
.SetAccessRule()
Set-Acl -path  -AclObject 

Как вы можете видеть, первые два оператора начинаются с простого = в качестве первого непробельного символа, и это является причиной ошибки, которую вы видите.

Вместо этого переключитесь на одинарные кавычки здесь:

$sb = [ScriptBlock]::Create(@'
$Acl = (Get-Item -path D:\Websites\$Sitename).GetAccessControl('Access')
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule('BUILTIN\IIS_IUSRS', 'Modify', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
$Acl.SetAccessRule($Ar)
Set-Acl -path $Path -AclObject $Acl
'@)

Если вам нужно передать значение переменной из определяющей области, я бы предложил либо определить блок param в блоке сценария:

$sb = [ScriptBlock]::Create(@'
param($Sitename)
$Acl = (Get-Item -path D:\Websites\$Sitename).GetAccessControl('Access')
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule('BUILTIN\IIS_IUSRS', 'Modify', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
$Acl.SetAccessRule($Ar)
Set-Acl -path $Path -AclObject $Acl
'@)
 Invoke-Command -Session $Session -ScriptBlock $sb -ArgumentList $Sitename

или используйте оператор формата строки -f, чтобы заменить его в строке перед созданием блока сценария:

$sb = [ScriptBlock]::Create(@'
$Acl = (Get-Item -path D:\Websites\{0}).GetAccessControl('Access')
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule('BUILTIN\IIS_IUSRS', 'Modify', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
$Acl.SetAccessRule($Ar)
Set-Acl -path $Path -AclObject $Acl
'@ -f $Sitename)

См. about_Quoting_Rules раздел справки для дополнительная информация о цитировании и расширении переменных

person Mathias R. Jessen    schedule 05.09.2017
comment
Это сработало отлично, большое вам спасибо. я не знал о переключателе -f - person Karl; 05.09.2017
comment
@Karl. Он называется оператором формата на случай, если вы в будущем погуглите его. - person Maximilian Burszley; 05.09.2017