31

I am new to Python and I am trying to make a script that connects to a remote windows machine and execute commands there and test ports connectivity.

Here is the code that I am writing but it is not working. Basically, I want to and it returns with the local machine data, not the remote one.

import wmi
import os
import subprocess
import re
import socket, sys

def main():

     host="remotemachine"
     username="adminaam"
     password="passpass!"
     server =connects(host, username, password)
     s = socket.socket()
     s.settimeout(5)
     print server.run_remote('hostname')

class connects:

    def __init__(self, host, username, password, s = socket.socket()):
        self.host=host
        self.username=username
        self.password=password
        self.s=s

        try:
            self.connection= wmi.WMI(self.host, user=self.username, password=self.password)
            self.s.connect(('10.10.10.3', 25))
            print "Connection established"
        except:
            print "Could not connect to machine"


   def run_remote(self, cmd, async=False, minimized=True):
       call=subprocess.check_output(cmd, shell=True,stderr=subprocess.STDOUT )
       print call

main() 
zewOlF
  • 403
  • 3
  • 8
  • 13
  • It is important to prefix the domain in front of the username. For example `username = r"EUR\adminaam"` – MathKid Nov 04 '14 at 11:35

11 Answers11

12

You can connect one computer to another computer in a network by using these two methods:

  • Use WMI library.
  • Netuse method.

WMI

Here is the example to connect using wmi module:

ip = '192.168.1.13'
username = 'username'
password = 'password'
from socket import *
try:
    print("Establishing connection to %s" %ip)
    connection = wmi.WMI(ip, user=username, password=password)
    print("Connection established")
except wmi.x_wmi:
    print("Your Username and Password of "+getfqdn(ip)+" are wrong.")

netuse

The second method is to use netuse module.

By Netuse, you can connect to remote computer. And you can access all data of the remote computer. It is possible in the following two ways:

  1. Connect by virtual connection.

    import win32api
    import win32net
    ip = '192.168.1.18'
    username = 'ram'
    password = 'ram@123'
    
    use_dict={}
    use_dict['remote']=unicode('\\\\192.168.1.18\C$')
    use_dict['password']=unicode(password)
    use_dict['username']=unicode(username)
    win32net.NetUseAdd(None, 2, use_dict)
    

    To disconnect:

    import win32api
    import win32net
    win32net.NetUseDel('\\\\192.168.1.18',username,win32net.USE_FORCE)
    
  2. Mount remote computer drive in local system.

    import win32api
    import win32net
    import win32netcon,win32wnet
    
    username='user'
    password='psw'
    
    try:
        win32wnet.WNetAddConnection2(win32netcon.RESOURCETYPE_DISK, 'Z:','\\\\192.168.1.18\\D$', None, username, password, 0)
        print('connection established successfully')
    except:
        print('connection not established')
    

    To unmount remote computer drive in local system:

    import win32api
    import win32net
    import win32netcon,win32wnet
    
    win32wnet.WNetCancelConnection2('\\\\192.168.1.4\\D$',1,1)
    

Before using netuse you should have pywin32 install in your system with python also.


Source: Connect remote system.

Rafiki
  • 604
  • 6
  • 19
Ashish Jain
  • 760
  • 1
  • 8
  • 23
10

You can use pywinrm library instead which is cross-platform compatible.

Here is a simple code example:

#!/usr/bin/env python
import winrm

# Create winrm connection.
sess = winrm.Session('https://10.0.0.1', auth=('username', 'password'), transport='kerberos')
result = sess.run_cmd('ipconfig', ['/all'])

Install library via: pip install pywinrm requests_kerberos.


Here is another example from this page to run Powershell script on a remote host:

import winrm

ps_script = """$strComputer = $Host
Clear
$RAM = WmiObject Win32_ComputerSystem
$MB = 1048576

"Installed Memory: " + [int]($RAM.TotalPhysicalMemory /$MB) + " MB" """

s = winrm.Session('windows-host.example.com', auth=('john.smith', 'secret'))
r = s.run_ps(ps_script)
>>> r.status_code
0
>>> r.std_out
Installed Memory: 3840 MB

>>> r.std_err
kenorb
  • 155,785
  • 88
  • 678
  • 743
  • I was trying this and I am facing an issue when I run a command like 'ipconfig'. It says "HTTPSConnectionPool(host='192.168.1.13', port=5986): Max retries exceeded with url: /wsman (Caused by ConnectTimeoutError(, 'Connection to 192.168.1.13 timed out. (connect timeout=30)'))"" – Adnan Sheikh Jun 19 '21 at 07:02
7

Maybe you can use SSH to connect to a remote server.

Install freeSSHd on your windows server.

SSH Client connection Code:

import paramiko

hostname = "your-hostname"
username = "your-username"
password = "your-password"
cmd = 'your-command'

try:
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname,username=username,password=password)
    print("Connected to %s" % hostname)
except paramiko.AuthenticationException:
    print("Failed to connect to %s due to wrong username/password" %hostname)
    exit(1)
except Exception as e:
    print(e.message)    
    exit(2)

Execution Command and get feedback:

try:
    stdin, stdout, stderr = ssh.exec_command(cmd)
except Exception as e:
    print(e.message)

err = ''.join(stderr.readlines())
out = ''.join(stdout.readlines())
final_output = str(out)+str(err)
print(final_output)
Beatrice Lin
  • 1,456
  • 14
  • 17
  • This solution helped me a big time. From windows machine I was trying to run a shell script on a remote machine which eventually has python script path to run. If I need to run multiple commands then can I repeat the execution command box ? Please suggest. – Rohit Jul 03 '20 at 00:27
  • When you run exec_command multiple times, each command is executed in its own "shell". So the previous commands have no effect on an environment of the following commands. – Beatrice Lin Jul 08 '20 at 08:17
  • If you need the previous commands to affect the following commands, just use an appropriate syntax of your server shell. Most *nix shells use a semicolon or an double-ampersand (with different semantics) to specify a list of commands. In your case, the ampersand is more appropriate, as it executes following commands, only if previous commands succeed: like this: stdin,stdout,stderr=ssh.exec_command("ORACLE_SID=PROD && cd /01/application/dataload && pwd") – Beatrice Lin Jul 08 '20 at 08:18
6

For connection

c=wmi.WMI('machine name',user='username',password='password')

#this connects to remote system. c is wmi object

for commands

process_id, return_value = c.Win32_Process.Create(CommandLine="cmd.exe /c  <your command>")

#this will execute commands
fhulprogrammer
  • 599
  • 2
  • 7
  • 16
2

do the client machines have python loaded? if so, I'm doing this with psexec

On my local machine, I use subprocess in my .py file to call a command line.

import subprocess
subprocess.call("psexec {server} -c {}") 

the -c copies the file to the server so i can run any executable file (which in your case could be a .bat full of connection tests or your .py file from above).

Chet Meinzer
  • 1,691
  • 2
  • 21
  • 35
2

I have personally found pywinrm library to be very effective. However, it does require some commands to be run on the machine and some other setup before it will work.

kenorb
  • 155,785
  • 88
  • 678
  • 743
Rusty Weber
  • 1,541
  • 1
  • 19
  • 32
1

I don't know WMI but if you want a simple Server/Client, You can use this simple code from tutorialspoint

Server:

import socket               # Import socket module

s = socket.socket()         # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345                # Reserve a port for your service.
s.bind((host, port))        # Bind to the port

s.listen(5)                 # Now wait for client connection.
while True:
   c, addr = s.accept()     # Establish connection with client.
   print 'Got connection from', addr
   c.send('Thank you for connecting')
   c.close()                # Close the connection 

Client

#!/usr/bin/python           # This is client.py file

import socket               # Import socket module

s = socket.socket()         # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345                # Reserve a port for your service.

s.connect((host, port))
print s.recv(1024)
s.close                     # Close the socket when done

it also have all the needed information for simple client/server applications.

Just convert the server and use some simple protocol to call a function from python.

P.S: i'm sure there are a lot of better options, it's just a simple one if you want...

Kobi K
  • 7,743
  • 6
  • 42
  • 86
  • ***Thank you Kobi for replying me, but this is gonna be so hard to go to every client and run a script there.... what i am trying to do is accessing multiple machines from 1 machine and execute commands there*** – zewOlF Sep 23 '13 at 15:03
1

The best way to connect to the remote server and execute commands is by using "wmiexec.py"

Just run pip install impacket

Which will create "wmiexec.py" file under the scripts folder in python

Inside the python > Scripts > wmiexec.py

we need to run the wmiexec.py in the following way

python <wmiexec.py location> TargetUser:TargetPassword@TargetHostname "<OS command>"

Pleae change the wmiexec.py location according to yours

Like im using python 3.8.5 and my wmiexec.py location will be C:\python3.8.5\Scripts\wmiexec.py

python C:\python3.8.5\Scripts\wmiexec.py TargetUser:TargetPassword@TargetHostname "<OS command>"

Modify TargetUser, TargetPassword ,TargetHostname and OS command according to your remote machine

Note: Above method is used to run the commands on remote server.

But if you need to capture the output from remote server we need to create an python code.

import subprocess
command = 'C:\\Python36\\python.exe C:\\Python36\\Scripts\\wmiexec.py TargetUser:TargetPassword@TargetHostname "ipconfig"'
command = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
stdout= command.communicate()[0]
print (stdout)

Modify the code accordingly and run it.

0

is it too late?

I personally agree with Beatrice Len, I used paramiko maybe is an extra step for windows, but I have an example project git hub, feel free to clone or ask me.

https://github.com/davcastroruiz/django-ssh-monitor

David Castro
  • 193
  • 1
  • 6
0

pypsrp - Python PowerShell Remoting Protocol Client library

At a basic level, you can use this library to;

Execute a cmd command
Run another executable
Execute PowerShell scripts
Copy a file from the localhost to the remote Windows host
Fetch a file from the remote Windows host to the localhost
Create a Runspace Pool that contains one or multiple PowerShell pipelines and execute them asynchronously
Support for a reference host base implementation of PSRP for interactive scripts

REF: https://github.com/jborean93/pypsrp

reddy nishanth
  • 396
  • 6
  • 11
0

Many answers already, but one more option

PyPSExec https://pypi.org/project/pypsexec/

It's a python clone of the famous psexec. Works without any installation on the remote windows machine.

Red
  • 144
  • 1
  • 7