1

除了此处给出的响应:PowerShell Enter Session find path bug 之外,我在脚本中遇到了另一堵墙,我无法解决。以下脚本返回错误:

术语“=”未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。检查名称的拼写,或者如果包含路径,请验证路径是否正确并重试。

$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变量的设置,并尝试以各种方式重写但没有运气。我错过了什么?

4

1 回答 1

2

当您使用双引号 here-string 时,它的行为就像常规双引号字符串一样 - 解析器将评估和扩展引号之间的任何变量或子表达式。

由于脚本块定义中的变量在定义上下文中并不存在,因此您最终会得到一个具有以下定义的脚本块:

 = (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帮助主题

于 2017-09-05T14:01:59.550 回答