我需要将PowerShell脚本放入一个带有双引号的变量中,就像这样。然而,我不知道正确的语法,因为我看到$script变量的语法错误,当我尝试这个。
$script = "Invoke-Command -ComputerName $hostname -Credential $cred -ScriptBlock {Import-Module sqlserver; invoke-sqlcmd -ServerInstance $Using:hostnameMSSQLServer; invoke-sqlcmd "create login [$Using:sqluser] from windows";invoke-sqlcmd "alter server role sysadmin add member [$Using:sqluser]"}"
$runscript = Invoke-VMScript -VM $vm -ScriptText $script -GuestUser $tmpl_user -GuestPassword $tmpl_pass -ToolsWaitSecs 300
Invoke-VMScript -ScriptText
只接受一个字符串包含PowerShell代码,和没有支持单独传递参数代码。
含义是:
-
为了包含来自调用者作用域的变量值,您确实需要使用字符串插值(通过可扩展字符串,
"..."
),如您所尝试的。- 注意,这种情况需要在调用者变量的引用周围嵌入引号,调用者变量的值可能包含空格或其他特殊字符;例:
"... -Foo '$foo' ..."
)
- 注意,这种情况需要在调用者变量的引用周围嵌入引号,调用者变量的值可能包含空格或其他特殊字符;例:
-
正如Mathias R. Jessen指出的那样,您希望在目标机器上计算的变量引用必须将其
$
符号转义为`$
以防止调用方过早插补;例:`$Using:sqluser
有一个catch然而:
-
使用字符串插值对可以嵌入到字符串中的数据类型施加了限制,因为不是所有的数据类型都有字符串字面值表示,可以被识别为原始类型。
-
在您的示例中,调用方
$cred
变量包含一个[PSCredential]
实例,该实例不有意义地对进行字符串化。(出于安全原因不能):它毫无意义地扩展为System.Management.Automation.PSCredential
的逐字字符串值,即实例的类型名称。
换句话说:您不能以这种方式传递凭证. -
一个潜在的解决方案需要在目标机器上预先工作:您可以尝试将凭证以加密形式保存到文件中,然后在调用时通过
Import-Clixml
对该文件进行反序列化。- 查看此答案的演示,并查看此方法的安全含义。
-