How to create and delete NamedPipeServerStream in Powershell?

559 Views Asked by At

I was struggling with a scenario where I had one process running as admin and another process running as non-admin user. The first admin-process should open a pipeStream to allow the other process sending some message information.

Here I had multiple problems:

  1. I had to set the permission for the pipeStream allowing the client to write some data into this pipe even if the user is not the same and even no admin
  2. The admin process should wait for the connection via 'WaitForConnectionAsync'
  3. The pipeStream should be properly closed to allow running the same code again.

See below my solution.

1

There are 1 best solutions below

2
On BEST ANSWER

Here is my server-side code that creates the pipeStream:

# server process running as admin and waiting for client response:

cls
$ps  = [System.IO.Pipes.PipeSecurity]::new()
$all = [System.Security.Principal.WellKnownSidType]::WorldSid
$sid = [System.Security.Principal.SecurityIdentifier]::new($all,$null)
$ar  = [System.IO.Pipes.PipeAccessRule]::new($sid, 'ReadWrite', 'Allow')
$ps.SetAccessRule($ar)

$async = [System.IO.Pipes.PipeOptions]::Asynchronous
$pipe  = [System.IO.Pipes.NamedPipeServerStream]::new('test123','In',1,0,$async,512,512,$ps)

$timeout = [timespan]::FromSeconds(10)
$source = [System.Threading.CancellationTokenSource]::new($timeout)
$conn = $pipe.WaitForConnectionAsync($source.token)
do {
    # some other stuff here while waiting for connection
    sleep -Seconds 1
} until ($conn.IsCompleted)

$data = $null
if ($pipe.IsConnected) {
    $sr = [System.IO.StreamReader]::new($pipe)
    $data = $sr.ReadLine()
    $sr.Dispose()
}
$pipe.Dispose()
write-host "response: $data"
'end.'

and here the client-side code to send a message to the other process:

 # client process running as non-admin user sending a response:

cls
$pipe = [System.IO.Pipes.NamedPipeClientStream]::new('.','test123','Out')
try {$pipe.Connect(10000)} catch {}
if ($pipe.IsConnected) {
    $sw = [System.IO.StreamWriter]::new($pipe)
    $sw.WriteLine('hello world!')
    $sw.Flush()
    $sw.Dispose()
}
'end.'

I hope this code-snippets will help others with a similar use case and also explains a little bit some details working with a NamedPipeServerStream.