Python Forum

Full Version: PsInfo from remote computer in python
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
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?
You need to address the Hosts by their name. IP does not work and in front of the name, you need the double backslashes.
Remote hosts require a username and a password, otherwise it won't work.
Working example code with automatic download of this tool.

import platform
import subprocess
import sys
from io import BytesIO
from pathlib import Path
from urllib.request import urlopen
from zipfile import ZipFile

HOME = Path.home()
PSTOOLS = HOME / "pstools"
PSINFO = PSTOOLS / "PsInfo.exe"


def download_extract():
    url = "https://download.sysinternals.com/files/PSTools.zip"
    response = urlopen(url)
    file = BytesIO(response.read())
    with ZipFile(file) as fd:
        fd.extractall(PSTOOLS)


def get_psinfo(host, username=None, password=""):
    if platform.architecture()[0] == "64bit":
        cmd = [PSTOOLS / "PsInfo64.exe"]
    else:
        cmd = [PSTOOLS / "PsInfo.exe"]

    host = "\\\\" + host

    # username and password is mandatory for remote access
    if username:
        cmd += ["-d", "-nobanner", "-accepteula", host, "-u", username, "-p", password]
    else:
        cmd += ["-d", "-nobanner", "-accepteula", host]

    # suppress window
    startup_info = subprocess.STARTUPINFO()
    startup_info.dwFlags |= subprocess.STARTF_USESHOWWINDOW

    
    proc = subprocess.run(
        cmd, capture_output=True, encoding="utf8", startupinfo=startup_info
    )
    return proc.stdout


def main():
    if not PSINFO.exists():
        print(f"Downloading PsTools to {PSTOOLS}")
        download_extract()
    info_local = get_psinfo("DESKTOP-S5MOQUE")
    info_remote = get_psinfo("DESKTOP-S5MOQUE", "Andre")
    # empty password may not work remotely, but locally it works
    print("Local info")
    print(info_local)
    print()
    print("Fake - RemoteInfo")
    print(info_remote)
    


if __name__ == "__main__":
    main()
(Aug-10-2021, 08:02 AM)DeaD_EyE Wrote: [ -> ]You need to address the Hosts by their name. IP does not work and in front of the name, you need the double backslashes.
Remote hosts require a username and a password, otherwise it won't work.
Working example code with automatic download of this tool.

import platform
import subprocess
import sys
from io import BytesIO
from pathlib import Path
from urllib.request import urlopen
from zipfile import ZipFile

HOME = Path.home()
PSTOOLS = HOME / "pstools"
PSINFO = PSTOOLS / "PsInfo.exe"


def download_extract():
    url = "https://download.sysinternals.com/files/PSTools.zip"
    response = urlopen(url)
    file = BytesIO(response.read())
    with ZipFile(file) as fd:
        fd.extractall(PSTOOLS)


def get_psinfo(host, username=None, password=""):
    if platform.architecture()[0] == "64bit":
        cmd = [PSTOOLS / "PsInfo64.exe"]
    else:
        cmd = [PSTOOLS / "PsInfo.exe"]

    host = "\\\\" + host

    # username and password is mandatory for remote access
    if username:
        cmd += ["-d", "-nobanner", "-accepteula", host, "-u", username, "-p", password]
    else:
        cmd += ["-d", "-nobanner", "-accepteula", host]

    # suppress window
    startup_info = subprocess.STARTUPINFO()
    startup_info.dwFlags |= subprocess.STARTF_USESHOWWINDOW

    
    proc = subprocess.run(
        cmd, capture_output=True, encoding="utf8", startupinfo=startup_info
    )
    return proc.stdout


def main():
    if not PSINFO.exists():
        print(f"Downloading PsTools to {PSTOOLS}")
        download_extract()
    info_local = get_psinfo("DESKTOP-S5MOQUE")
    info_remote = get_psinfo("DESKTOP-S5MOQUE", "Andre")
    # empty password may not work remotely, but locally it works
    print("Local info")
    print(info_local)
    print()
    print("Fake - RemoteInfo")
    print(info_remote)
    


if __name__ == "__main__":
    main()

Thanks for replying to my question.
I would like to try your example and see how it works.
Hence what should I replace in your script to adopt to my needs?
1. replace username and password with real ones - line 32
2. replace DESKTOP-S5MOQUE for my local machine - line 51
3. replace "DESKTOP-S5MOQUE", "Andre" with remote machine - line 52
4. create a script from your example, make changes 1.-3. and execute?
Did I miss something?

Thanks
Quote:Did I miss something?
Yes. I think you need to learn more about truthiness in Python and about function definitions.
The username is supplied in the function definition as the second argument and if you don't call the function with a username, then None is assigned to the username. This is used for the different extension of cmd.

Quote:1. replace username and password with real ones - line 32
The name username comes from the function-call. Look at the function definition:
def get_psinfo(host, username=None, password=""):
If username is not supplied as argument or keyword-argument, then username is assigned to None.
A bool(None) returns False, which is important in this case, because I use it where you think you have to replace it, but it's not right.

Then the list for the command is extended. If the user has called the function with username, then bool(username) is True and the first branch is executed. If username is None, then the second branch (else) is executed.
    # username and password is mandatory for remote access
    if username:
        cmd += ["-d", "-nobanner", "-accepteula", host, "-u", username, "-p", password]
    else:
        cmd += ["-d", "-nobanner", "-accepteula", host]
Afterwards, cmd is used and the elements of cmd depends on the function-call. If no username was supplied, the cmd without "-u", username is used.

Quote:2. replace DESKTOP-S5MOQUE for my local machine - line 51
3. replace "DESKTOP-S5MOQUE", "Andre" with remote machine - line 52

Yes, this is right.
Just use the function call.

To understand truthiness a bit better, test this code:
def is_set(username=None):
    if username:
        print("bool(username) is True")
    else:
        print("bool(username) is False")


# all False
is_set()
is_set(None) # same call as above, but explicit supplying None as first argument
is_set("") # empty str is False
is_set(False) # False
is_set([]) # empty list is False

# all True
is_set(True)
is_set("string is not empty2") # True
is_set(print) # bool(function) is also True