4

SS64 says it means

Don’t wait for the application to terminate. Only use for non-interactive applications.

But I don't understand this. I'm trying to run some non-interactive system calls but, if I don't pass -d, my powershell job never returns and, if I do, pass -d, I don't get anything back when it does return. Can anyone tell me what exactly -d does?

Or for bonus points, you could tell me how to make this return something useful:

C:\PSExec.exe \\$hostname /accepteula -u user -p pass -d cmd /C "type $file" 2> $null
sirdank
  • 202

2 Answers2

3

The -d switch, as alluded to in the description quoted in your question, makes PsExec not wait for the new process to exit. You can't get any exit code or output because the remote PsExec service just starts the process, tells the new process ID to the original PsExec program, and stops caring about what the new process does. Without -d, all the process's output will be sent back to the PsExec program that started the whole thing, and PsExec will have to wait for the new process to exit so it can know when to exit itself.

PsExec doesn't play nicely with redirection or PowerShell. I did manage to get partial output by launching the starting PowerShell instance with the -inputformat none parameter, but PsExec weirdly chops off some of the command's output and I couldn't get around it.

You could try PowerShell remoting instead:

Invoke-Command {type $file} -ComputerName $hostname -Credential (New-Object PSCredential -ArgumentList 'username', (ConvertTo-SecureString 'password' -AsPlainText -Force))
Ben N
  • 42,308
2

About non-interactive -d, it just runs the command, without returning output and then terminates remote prompt. Actually, it does, by only returning the error code of remote process. In your case, it shows the output of $file on a non-existent, hidden cmd window on remote machine and terminates. That's why you don't see anything. Try to create a file on remote machine using -d switch and then you see it works.

Update:

If $file is a variable in remote machine, the problem is you're using a variable that expands in your local powershell environment (as you mentioned) so use a cmd variable instead (considering you're sending the command to cmd) that doesn't expand in powershell. PSExec.exe \\$hostname -u user -p pass -d cmd /c "type %file%" 2> $null

However, that's not the REAL solution! because what if you want to send a command to powershell remotely? You need something preventing the expansion, like %%varibale%% in cmd. I've found using " will expand, but ' prevents expanding in powershell:

PS> "This is $file" against PS> 'This is $file'

But that doesn't help in your case, another way though, is to create an script in local machine, and send to destination with PSEXEC:

PSExec.exe \\$hostname -u user -p pass -c powershell script.ps1 2> $null

Or... use Invoke-Command as mentioned here:

PS C:\> invoke-command -filepath c:\scripts\test.ps1 -computerName $hostname