Gary Willoughby
Gary Willoughby

Reputation: 52588

What is the best way to map windows drives using Python?

What is the best way to map a network share to a windows drive using Python? This share also requires a username and password.

Upvotes: 42

Views: 84035

Answers (8)

Rick FlyFish
Rick FlyFish

Reputation: 105

This is the best way I created, this works for windows 11

  #pip install pwinput

# Drive letter: P
# Shared drive path: \\vnas04a\lc_adc_data04$\ADCALFSR01_Public\Work\
# nUsr: Var for your network user name
# nPas: Var for your network user password
from datetime import datetime, date
import os
import subprocess
import pwinput

#common path to work
pPath = '\\\\vnas04a\\lc_adc_data04$\\ADCALFSR01_Public\\Work\\' 
NL = '\n' #global var Next Line

print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
#print("Disconnecting any past connections to work...")
#subprocess.call(r'net use p: /del', shell=True)

if os.path.exists(pPath):
    print("The path exists! Removing...")
    #Disconnect anything on P
    subprocess.call(r'net use p: /del', shell=True)
else:{
    print("The path does not exist.")
}

nUser = input('Network User Name : ')
nPass = pwinput.pwinput(prompt='Network Password: ')

nPath = 'net use p: ' + pPath + ' /user:' + nUser + ' ' + nPass
subprocess.call(nPath, shell=True)

print ('Network path: ' + nPath + ' connected!' )

    enter code here

Upvotes: 0

user3033659
user3033659

Reputation: 1

I had trouble getting this line to work:

win32wnet.WNetAddConnection2(win32netcon.RESOURCETYPE_DISK, drive, networkPath, None, user, password)

But was successful with this:

win32wnet.WNetAddConnection2(1, 'Z:', r'\\UNCpath\share', None, 'login', 'password') 

Upvotes: 0

David Metcalfe
David Metcalfe

Reputation: 2431

An alternative to subprocess:

import os

os.system("net use m: \\\\shared\folder")

Or

import os

cmd = "net use m: \\\\shared\folder"
os.system(cmd)

Upvotes: 5

aqua
aqua

Reputation: 3375

Building off of @Anon's suggestion:

# Drive letter: M
# Shared drive path: \\shared\folder
# Username: user123
# Password: password
import subprocess

# Disconnect anything on M
subprocess.call(r'net use m: /del', shell=True)

# Connect to shared drive, use drive letter M
subprocess.call(r'net use m: \\shared\folder /user:user123 password', shell=True)

I prefer this simple approach, especially if all the information is static.

Upvotes: 34

Pjl
Pjl

Reputation: 1812

If you want to map the current login user, i think subprocess solve your problem. But is you want to control different mappings for different users, from a single master account. You could do this from the register of windows

The idea is to load the profile of a given user.

import win32api
import win32security
import win32profile
import win32netcon
import win32net
import win32netcon
import win32con

il = 'G'
m = '\\\\192.168.1.16\\my_share_folder'
usu = 'my_user'
cla = 'passwd'

#login the user
hUser = win32security.LogonUser(
       usu,
       None,
       cla,
       win32security.LOGON32_LOGON_NETWORK,
       win32security.LOGON32_PROVIDER_DEFAULT 
    )

#load the profile
hReg = win32profile.LoadUserProfile (
             hUser,  
             {"UserName" : usu}
            )

#alter the regedit entries of usu
win32api.RegCreateKey(hReg, "Network")
hkey = win32api.RegOpenKey(hReg, "Network\\", 0, win32con.KEY_ALL_ACCESS)
win32api.RegCreateKey(hkey, il)
hkey = win32api.RegOpenKey(hReg, "Network\\%s" % il, 0, win32con.KEY_ALL_ACCESS)
win32api.RegSetValueEx(hkey, "ConnectionType", 0, win32con.REG_DWORD, 1)
win32api.RegSetValueEx(hkey, "DeferFlags", 0, win32con.REG_DWORD, 4)
win32api.RegSetValueEx(hkey, "ProviderName", 0, win32con.REG_SZ, "Red de Microsoft Windows")
win32api.RegSetValueEx(hkey, "ProviderType", 0, win32con.REG_DWORD, 131072)
win32api.RegSetValueEx(hkey, "RemotePath", 0, win32con.REG_SZ, m)
win32api.RegSetValueEx(hkey, "UserName", 0, win32con.REG_DWORD, 0)

Upvotes: 0

Varun
Varun

Reputation: 315

Okay, Here's another method...

This one was after going through win32wnet. Let me know what you think...

def mapDrive(drive, networkPath, user, password, force=0):
    print networkPath
    if (os.path.exists(drive)):
        print drive, " Drive in use, trying to unmap..."
        if force:
            try:
                win32wnet.WNetCancelConnection2(drive, 1, 1)
                print drive, "successfully unmapped..."
            except:
                print drive, "Unmap failed, This might not be a network drive..."
                return -1
        else:
            print "Non-forcing call. Will not unmap..."
            return -1
    else:
        print drive, " drive is free..."
    if (os.path.exists(networkPath)):
        print networkPath, " is found..."
        print "Trying to map ", networkPath, " on to ", drive, " ....."
        try:
            win32wnet.WNetAddConnection2(win32netcon.RESOURCETYPE_DISK, drive, networkPath, None, user, password)
        except:
            print "Unexpected error..."
            return -1
        print "Mapping successful"
        return 1
    else:
        print "Network path unreachable..."
        return -1

And to unmap, just use....

def unmapDrive(drive, force=0):
    #Check if the drive is in use
    if (os.path.exists(drive)):
        print "drive in use, trying to unmap..."
        if force == 0:
            print "Executing un-forced call..."
        try:
            win32wnet.WNetCancelConnection2(drive, 1, force)
            print drive, "successfully unmapped..."
            return 1
        except:
            print "Unmap failed, try again..."
            return -1
    else:
        print drive, " Drive is already free..."
        return -1

Upvotes: 13

Varun
Varun

Reputation: 315

Assuming that you import necessary libraries, This was a part of an RPC server where the client requested the server to map a drive locally...

#Small function to check the availability of network resource.
def isAvailable(path):
    winCMD = 'IF EXIST ' + path + ' echo YES'
    cmdOutPut = subprocess.Popen(winCMD, stdout=subprocess.PIPE, shell=True).communicate()
    return string.find(str(cmdOutPut), 'YES',)

#Small function to check if the mention location is a directory
def isDirectory(path):
    winCMD = 'dir ' + path + ' | FIND ".."'
    cmdOutPut = subprocess.Popen(winCMD, stdout=subprocess.PIPE, shell=True).communicate()
    return string.find(str(cmdOutPut), 'DIR',)

================Check the white spaces from here, these were a part of a function============

def mapNetworkDrive(self, drive, networkPath, user, password):

    #Check for drive availability
    if isAvailable(drive) > -1:
        #Drive letter is already in use
        return -1

    #Check for network resource availability
    if isAvailable(networkPath) == -1:
        print "Path not accessible: ", networkPath
        #Network path is not reachable
        return -1

    #Prepare 'NET USE' commands
    winCMD1 = 'NET USE ' + drive + ' ' + networkPath
    winCMD2 = winCMD1 + ' ' + password + ' /User' + user

    print "winCMD1 = ", winCMD1
    print "winCMD2 = ", winCMD2
    #Execute 'NET USE' command with authentication
    winCMD = winCMD2
    cmdOutPut = subprocess.Popen(winCMD, stdout=subprocess.PIPE, shell=True).communicate()
    print "Executed: ", winCMD
    if string.find(str(cmdOutPut), 'successfully',) == -1:
        print winCMD, " FAILED"
        winCMD = winCMD1
        #Execute 'NET USE' command without authentication, incase session already open
        cmdOutPut = subprocess.Popen(winCMD, stdout=subprocess.PIPE, shell=True).communicate()
        print "Executed: ", winCMD
        if string.find(str(cmdOutPut), 'successfully',) == -1:
            print winCMD, " FAILED"
            return -1
        #Mapped on second try
        return 1
    #Mapped with first try
    return 1

def unmapNetworkDrive(self, drive):

    #Check if the drive is in use
    if isAvailable(drive) == -1:
        #Drive is not in use
        return -1

    #Prepare 'NET USE' command
    winCMD = 'net use ' + drive + ' /DELETE'
    cmdOutPut = subprocess.Popen(winCMD, stdout=subprocess.PIPE, shell=True).communicate()
    if string.find(str(cmdOutPut), 'successfully',) == -1:
        #Could not UN-MAP, this might be a physical drive
        return -1
    #UN-MAP successful
    return 1

Upvotes: 3

Anon
Anon

Reputation: 12548

I don't have a server to test with here at home, but maybe you could simply use the standard library's subprocess module to execute the appropriate NET USE command?

Looking at NET HELP USE from a windows command prompt, looks like you should be able to enter both the password and user id in the net use command to map the drive.

A quick test in the interpreter of a bare net use command w/o the mapping stuff:

>>> import subprocess
>>> subprocess.check_call(['net', 'use'])
New connections will be remembered.

There are no entries in the list.

0
>>>

Upvotes: 3

Related Questions