A co-worker asked the other day about a communication between different powershell scripts. First solution was using Mutex but it showed pretty fast that Mutex and Semaphore does only work in Powershell if you start with the –STA switch. By default Powershell uses a Multithreaded Apartment with each command running in its own thread. So when the simples method failed I looked for other means

Named Pipes to the Rescue

Named Pipes are not supported natively by Powershell (as far as I know). But as you can use any .Net Classes in Powershell thats not a Problem. You only need to load the System.Core Assembly (from .Net 3.5) via either

add-Type -assembly "System.Core" (in PS V2)

or old fashioned via

[reflection.Assembly]::LoadWithPartialName("system.core")

Some are telling you to load with explicit version but IMHO this only
ties you to a certain combination of Powershell and .Net. Usualy newer versions of .Net ensures backwards compability anyway.

Server Side

$pipe=new-object System.IO.Pipes.NamedPipeServerStream("\\.\pipe\Wulf");
'Created server side of "\\.\pipe\Wulf"'
$pipe.WaitForConnection(); 

$sr = new-object System.IO.StreamReader($pipe); 
while (($cmd= $sr.ReadLine()) -ne 'exit') 
{
 $cmd 
}; 

$sr.Dispose();
$pipe.Dispose();

In this case the server only emits the given command but feel free to parse it and even extract parameters or just ignore the cmd and always do the same.

Client Side

$pipe = new-object System.IO.Pipes.NamedPipeClientStream("\\.\pipe\Wulf");
 $pipe.Connect(); 

$sw = new-object System.IO.StreamWriter($pipe);
$sw.WriteLine("Go"); 
$sw.WriteLine("start abc 123"); 
$sw.WriteLine('exit'); 

$sw.Dispose(); 
$pipe.Dispose():

On the client side you are writing to the pipe. As long as you don’t send the exit command you can connect from different clientscripts.

Naming the Pipe

Named Pipes must have uniq names per System so you better use something like \\.\pipe\company.tld.app. While the server side is bound to use localhost ‘.’ the client can use a remote connection with the \\servername\pipe\… syntax. (If the policies and firewall settings permit it).

 

I might revisit it and bring it to a proper module form but for the moment it is enough. Stay alert as this is not tested in production qualitiy scripts there might be a lot of caveats. Don’t say I didn’t told you.