PsInfo from remote computer in python

I need to get output from PsInfo.exe on remote computer. I am located on vhabosapp4gen but need to get information about vhabosdev25 From command line I execute:

PsInfo.exe  -d  -nobanner \\vhabosdev25

It returns me information about remote computer I have to run it using python3. Hence I execute the following:

from subprocess import check_output
 x = check_output("PsInfo.exe  -d  -nobanner \\vhabosdev25", shell=True)

It return me information about local vhabosapp4gen Question: how could I get information about remote computer using python?

This is almost certainly a string issue. You wrote:

"PsInfo.exe  -d  -nobanner \\vhabosdev25"

In Python, strings accept various slosh escapes such as \n to mean a
newline character and so forth, and in keep with that the sequence \\
means a slosh/backslash. This means that the resulting command string

PsInfo.exe  -d  -nobanner \vhabosdev25

which only has one backslash, unlike your intended command.

The simplest approach is a “raw string”:

r"PsInfo.exe  -d  -nobanner \\vhabosdev25"

That leading r indicates this this is a “raw string” and that the
backslash is not specially handled. That would pass it through directly.

The other piece of advice I have is that you should, almost always,
strive to avoid using shell=True. That passes a single command string
to your system’s shell. That string itself is subject to the shell’s own
syntax parsing. Yet another layer of opportunity for something to mangle
the arguments to the command you intend.

Instead, avoid shell=True and pass the actual command line arguments
you intend as a list:

x = check_output([r"PsInfo.exe", r"-d", r"-nobanner", r"\vhabosdev25"])

On a UNIX system that is invoked directly; on Windows something equivalent
happens - I believe. The documentation at subprocess — Subprocess management — Python 3.9.6 documentation says:

On Windows, if args is a sequence, it will be converted to a string 
in a manner described in Converting an argument sequence to a string 
on Windows. This is because the underlying CreateProcess() operates 
on strings.

which is detailed here: subprocess — Subprocess management — Python 3.9.6 documentation

Nonetheless, it is better to avoid shell=True and try always to use a
list - even on Windows it is better to have this handled in a consistent
and well define way.

Cameron Simpson

Using an argument list with shell=False is usually right in Windows. subprocess.Popen concatenates the arguments into a command-line string according to the rules that WinAPI CommandLineToArgvW uses. Unfortunately, nothing requires a process to parse its command line according to these rules (e.g. backslash escaping), and the CMD shell itself is a notable example of a program that uses incompatible rules. IIRC, Cygwin and MSYS2 programs also use different rules.

Thanks a lot
I will try your suggestions

Using x = check_output([r"PsInfo.exe", r"-d", r"-nobanner", r"\vhabosdev25"]) did not work and still pointed to ‘local’ server
Using x = check_output(r"PsInfo.exe -d -nobanner \vhabosdev25") did work fine and returned information about remote server.
I think that I should be all set now.
Thanks a lot for help

Cameron suggested:


I am amused :slight_smile:

Did you have trouble escaping the backslashes in those three strings?

(Note for any beginners reading: what Cameron wrote with the raw strings
is perfectly legal Python code. It’s just unusual, and unnecessary, to
use raw strings for strings that don’t have backslashes in them.)

They’re the same command line:

>>> args = ["PsInfo.exe", "-d", "-nobanner", r"\vhabosdev25"]
>>> cmd1 = subprocess.list2cmdline(args)
>>> cmd2 = r"PsInfo.exe -d -nobanner \vhabosdev25"
>>> cmd1 == cmd2

Also, in both cases you haven’t used the correct UNC path r"\\vhabosdev25". Two initial backslashes are required.

It was just for consistency. - Cameron

That was my fault. Like your working command line example, two
backslashes are required. The r"" strings are not magic, they just make
it easy to type two backslashes instyead of four to get two backslashes
at the command end.

Cameron Simpson