What else I learned about powershell this week

Remoting.  Windows Remoting.  Powershell.  And variables.  With functions….

When you use powershell to connect to remote machines, you have to worry about where and how variables gets defined.

$s = New-PSSession -Computer localhost
Invoke-Command -Session $s -ArgList 1 -ScriptBlock { param($number) $number }

Yep. That’s what it takes to define a local variable in a script block

Today, I found that the powershell session has it’s own scope that lasts as long as the powershell scope.

 Invoke-Command -Session $s -ArgList "my_value" "value" -ScriptBlock { 
           param($name, $value)
           Set-Item Variable:$name = $value
      }
      Invoke-Command -Session $s -ScriptBlock { $my_value }

This will set a variable on a session in one remote invocation, and retrieve it on another. Crazy!  Or rather, just like an SSH session.

So I now want to make use of this to push local variables from my script over to a remote machine. Something like:

$wibble = "hi"
OnRemote -server "localhost" -locals "wibble" -action {
   Write-Host "Hi I'm on remote machine with $wibble == hi"
}

What the devil should OnRemote look like? Here’s the signature…

function OnRemote() {
    param($server, $locals=@(), [scriptblock]$action)
}

…and the body…

      $s = New-PSSession -Computer $server
      @($locals) | % { Invoke-Command -Session $s -ArgList $_ Variable:$_ -ScriptBlock {
           param($name, $value)
           New-Item -name Variable:$name -value $value
      }
      Invoke-Command -Session $s -ScriptBlock $action
      End-Session $s

At the moment I’ve haven’t gone any further with this, and I’m sure there’s a way of binding variables into the remote context more consisely. As it is, you have to remember to keep your locals declaration in sync with the values being pushed.

If I were to go to the next step, I’d probably try to remove that need to keep local names in sync. I guess it would look something like this:

function MyFunction(){
   $remote:wibble = 5 # or [remote]$wibble=5
   OnRemote {
       Write-Host "The value $wibble comes from the host"
   }
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: