简体   繁体   English

将 powershell 脚本放入带双引号的变量中的正确语法

[英]correct syntax for putting a powershell script into a variable with double quotes

I have a need to put a PowerShell script into a variable with double quotes like so.我需要像这样将 PowerShell 脚本放入带有双引号的变量中。 However I am not aware of the correct syntax for this as I see syntax errors with $script variable when I try this.但是我不知道正确的语法,因为我在尝试此操作时看到 $script 变量的语法错误。

$script = "Invoke-Command -ComputerName $hostname -Credential $cred -ScriptBlock {Import-Module sqlserver; invoke-sqlcmd -ServerInstance $Using:hostname\MSSQLServer; 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 accepts only a string containing PowerShell code, and has no support for separately passing arguments to that code. Invoke-VMScript -ScriptText仅接受包含 PowerShell 代码的字符串,并且支持单独将arguments传递给该代码。

The implications are:其含义是:

  • In order to include variable values from the caller 's scope you indeed need to use string interpolation (via an expandable string , "..." ), as you have attempted.为了包含来自调用者的 scope 的变量值,您确实需要使用字符串插值(通过可扩展字符串"..." ),正如您所尝试的那样。

    • Note that this situationally requires embedded quoting around reference to caller variables whose values may contain spaces or other special characters;请注意,这在某些情况下需要在对值可能包含空格或其他特殊字符的调用者变量的引用周围嵌入引号 eg例如
      "... -Foo '$foo'..." ) "... -Foo '$foo'..."
  • As Mathias R. Jessen points out, variable references you want to be evaluated on the target machine must have their $ sigil escaped as `$ so as to prevent premature interpolation on the caller's side;正如Mathias R. Jessen指出的那样,您想要在目标机器上评估的变量引用必须将其$ sigil 转义为`$以防止调用方过早插值; eg `$Using:sqluser例如`$Using:sqluser

There's a catch , however:但是,有一个问题

  • Use of string interpolation imposes limits on what data types may be embedded in the string , as not all data types have string -literal representations that are recognized as the original type.字符串插值的使用对可以嵌入到字符串中的数据类型施加了限制,因为并非所有数据类型都具有被识别为原始类型的字符串文字表示。

    • In your case, the caller-side $cred variable contains a [PSCredential] instance, which does not stringify meaningfully (and cannot, for security reasons): it meaninglessly expands to a verbatim string value of System.Management.Automation.PSCredential , ie the instance's type name .在您的情况下,调用方$cred变量包含一个[PSCredential]实例,它没有有意义地进行字符串化(并且出于安全原因不能):它毫无意义地扩展为System.Management.Automation.PSCredential的逐字字符串值,即实例的类型名称
      In other words: you cannot pass credentials this way .换句话说:您不能以这种方式传递凭据

    • A potential workaround requires up-front work on the target machine : You can try to save the credentials in encrypted form to a file and then deserialize that file at invocation time via Import-Clixml .一个潜在的解决方法需要在目标机器上进行前期工作:您可以尝试将凭据以加密形式保存到文件中,然后在调用时通过Import-Clixml反序列化该文件。

      • See this answer for a demonstration, and this answer for the security implications of this approach.请参阅此答案以获取演示,并查看此答案以了解此方法的安全隐患。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM