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:
See below my solution.
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.