简体   繁体   中英

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. However I am not aware of the correct syntax for this as I see syntax errors with $script variable when I try this.

$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.

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.

    • Note that this situationally requires embedded quoting around reference to caller variables whose values may contain spaces or other special characters; eg
      "... -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; eg `$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 .
      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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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