Python Forum
using PowerShell from Python script for mounting shares - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: using PowerShell from Python script for mounting shares (/thread-41729.html)



using PowerShell from Python script for mounting shares - tester_V - Mar-09-2024

Greetings to you all!
I have a list of Hosts, I need to connect to each host and do something with the files on it.
For some reason some of the hosts refusing connection Angry , but I can mount it manually with no problems to my server.

I tried a Power Shell script and it connects without any errors to the Hosts that refusing Python “net use…” connections.
I thought I could create a PS script for each host and then call it from my script.
for some reason it fails with errors:
Directory Does not exists [WinError 32] The process cannot access the file because it is being used by another process
The process cannot access the file because it is being used by another process

here is part of th escript that producess errors:
try :
    call(r"net use Z: /delete /yes")
    ln1= f'$net = new-object -ComObject WScript.Network'
    ln2= f'$net.MapNetworkDrive("Z:", "\\{host_name}\c$", $false, "domain\UsER", "SOMEPASS")'
    with open('C:/Scripts/somescript/Connect-0.ps1','w') as ps :
        ps.write(f"{ln1}\n")
        ps.write(f"{ln2}\n")
        subprocess.call("C:/Scripts/somescript/Connect-0.ps1")
        #break
except OSError as ek :                                              
    print(f" Error - {ek}" )
Any help is appreciated.
Thank you.


RE: using PowerShell from Python script for mounting shares - deanhystad - Mar-09-2024

Close the file before calling the subprocess,


RE: using PowerShell from Python script for mounting shares - tester_V - Mar-10-2024

I thought when I open the file with "with open..." it closes automatically...
Should I use instead of it :
    #with open('C:/Scripts/somescript/Connect-0.ps1','w') as ps :
    ps = open('C:/Scripts/somescript/Connect-0.ps1','w')
        ps.write(f"{ln1}\n")
        ps.write(f"{ln2}\n")
        ps.close()
        subprocess.call("C:/Scripts/somescript/Connect-0.ps1")
Thank you for working on weekends! Wink


RE: using PowerShell from Python script for mounting shares - deanhystad - Mar-10-2024

The file closes when you exit the code block under the with. You do not exit the code block. The file is still open when you call the subprocess.


RE: using PowerShell from Python script for mounting shares - tester_V - Mar-10-2024

Like this will do, right?

try :
    call(r"net use Z: /delete /yes")
    ln1= f'$net = new-object -ComObject WScript.Network'
    ln2= f'$net.MapNetworkDrive("Z:", "\\{host_name}\c$", $false, "domain\UsER", "SOMEPASS")'
    with open('C:/Scripts/somescript/Connect-0.ps1','w') as ps :
        ps.write(f"{ln1}\n")
        ps.write(f"{ln2}\n")
    subprocess.call("C:/Scripts/somescript/Connect-0.ps1")
        
except OSError as ek :                                              
    print(f" Error - {ek}" )



RE: using PowerShell from Python script for mounting shares - deanhystad - Mar-10-2024

You need to be careful about "\" in string literals because backslash before some characters is the start of an escape sequence, while in front of other characters is just a backslash. "\\" is a single backslash. "\c" is not an escape sequence, but I had to look it up. When using backslashes in a string, as a backslash, use raw string to be safe.

I don't know if any of the network drive parts are correct, but this is how I would write.
script_file = 'C:/Scripts/somescript/Connect-0.ps1'
with open(script_file, 'w') as file :
    file.write(
        '$net = new-object -ComObject WScript.Network\n'
        fr'$net.MapNetworkDrive("Z:", "\\{host_name}\c$", $false, "domain\USER", "SOMEPASS")\n'
    )
print(subprocess.call(script_file))



RE: using PowerShell from Python script for mounting shares - tester_V - Mar-11-2024

Whatever you think is a good idea, it is a good idea for me too man! Dance
Thank you again.


RE: using PowerShell from Python script for mounting shares - DeaD_EyE - Mar-11-2024

A file is not required to send a script via stdin to powershell.exe.

Example with logging:
import subprocess
import logging
from pathlib import Path
from textwrap import indent

logging.basicConfig(
    level=logging.INFO, format="%(asctime)s %(message)s", datefmt="%Y-%m-%dT%H:%M:%S"
)
log = logging.getLogger(__file__)


def connect_drive_letter(
    host_name: str, share: str | Path, drive: str, username: str, password: str
) -> bool:
    share = Path(share)

    log.info(
        "Mouting %(share)s of %(host_name)s to %(drive_letter)s:",
        {"share": share, "host_name": host_name, "drive_letter": drive_letter},
    )

    script = (
        "$net = new-object -ComObject WScript.Network\n"
        rf'$net.MapNetworkDrive("{drive}:", "\\{host_name}\{share}", $false, "{username}", "{password}")'
        "\n"
    )

    log.info("Script:\n%(script)s", {"script": indent(script, " " * 4)})

    return (
        subprocess.run(
            "powershell.exe",
            input=script,
            encoding="utf8",
            creationflags=subprocess.CREATE_NO_WINDOW,
        ).returncode
        == 0
    )


host_name = "HOST_NAME"
share = Path("YOUR/SHARE/SOMEWHERE")
drive_letter = "Z"
username = "DEADEYE"
password = "1234"


if connect_drive_letter(host_name, share, drive_letter, username, password):
    log.info("Connected share to a drive letter.")
else:
    log.info("Culd not connect the share to a drive letter")
Without logging and type hints:
import subprocess
from pathlib import Path


def connect_drive_letter(host_name, share, drive, username, password):
    share = Path(share)
    script = (
        "$net = new-object -ComObject WScript.Network\n"
        rf'$net.MapNetworkDrive("{drive}:", "\\{host_name}\{share}", $false, "{username}", "{password}")'
        "\n"
    )
    return (
        subprocess.run(
            "powershell.exe",
            input=script,
            encoding="utf8",
            creationflags=subprocess.CREATE_NO_WINDOW,
        ).returncode
        == 0
    )


host_name = "HOST_NAME"
share = Path("YOUR/SHARE/SOMEWHERE")
drive_letter = "Z"
username = "DEADEYE"
password = "1234"


connect_drive_letter(host_name, share, drive_letter, username, password)



RE: using PowerShell from Python script for mounting shares - tester_V - Mar-12-2024

DeaD_EyE!
That is an amazing way, for me, how one could do that.
Thank you for sharing!
tester_V