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 -ScriptTextaccepts 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."... -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; e.g.`$Using:sqluserThere'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
$credvariable contains a[PSCredential]instance, which does not stringify meaningfully (and cannot, for security reasons): it meaninglessly expands to a verbatim string value ofSystem.Management.Automation.PSCredential, i.e. 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.