Home > OS >  How to capture variable in Script Block?
How to capture variable in Script Block?

Time:02-18

Is it possible to return variable ($logstring) from the ScriptCommand to feed into the LogWriter function?

$ScriptCommand = "`$Cert  = Get-ChildItem Cert:\LocalMachine\My | where {`$_.thumbprint -eq `"$TP`"}
if(`$Cert.FriendlyName -eq `"$FriendlyName`")
{
`$logString = `"Friendly Name already $FriendlyName on $Node.`"
}
else 
{
`$Cert.FriendlyName = `"$FriendlyName`"
}"
$CommandScriptBlock = [Scriptblock]::Create($ScriptCommand)
Invoke-Command -ComputerName $Node -ScriptBlock $CommandScriptBlock

LogWriter -LogFile $Lfile -LogString $logString

CodePudding user response:

To build on the helpful comments: It sounds like you want two things:

  • Execute a script block remotely that contains references to local variable values.

    • For that, define your script block - as usual - as script-block literal, i.e. enclosed in { ... }; as Sage Pourpre notes, not only does this avoid quoting and escaping headaches, it allows your IDE to syntax-highlight and -check the code inside the block.

    • The simplest way to incorporate local variable values is via the $using: scope; e.g., $using:FriendlyName - see the relevant section of the conceptual about_Scopes help topic. This obviates the need to construct the text of your script block as a string that relies on string interpolation.

  • Output a value from that script block and capture it in local variable $logString. (You categorically cannot set a local variable directly in a remotely executing script block).

To put it all together:

# Define the script block for remote execution as a literal.
# Reference local variable values via $using:
$commandScriptBlock = {

  $Cert  = Get-ChildItem Cert:\LocalMachine\My | 
             Where-Object { $_.thumbprint -eq $using:TP }
  if ($Cert.FriendlyName -eq $using:FriendlyName) {
    # Output text for logging.
    "Friendly Name already $using:FriendlyName on $using:Node."
  }
  else {
    # Note: No text is being output here.
    $Cert.FriendlyName = $using:FriendlyName
  } 

}

# Invoke the script block remotely and capture its output in $logString
$logString = Invoke-Command -ComputerName $Node -ScriptBlock $commandScriptBlock

LogWriter -LogFile $Lfile -LogString $logString
  • Related