Search code examples
batch-filenetwork-shares

System Error 53 when mounting a network drive


Hi everyone first time posting, looking for a review of a batch file that I can't get to work correctly:

@echo Mounting ServerName as local drive
net use M: \\ServerName\"R Share"
@echo Clearing IE Cache
taskkill /im iexplore.exe /f
M:\"R Share"\PSExec\psexec.exe -l c:\windows\system32\RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 32
@echo Removing ServerName
@net use M: /delete
@echo IE Cleared
@pause

The point of the script is to mount a share as a drive, close any open IE windows, then run psexec to clear IE saved credentials, then unmount the drive. I keep running into a system error 53 when trying to mount the drive initially and want to make sure i'm not missing anything in my code. I've attempted to mount the drive using name and IP of the machine and either way I still run into the SysError 53 even though the share is reachable in Explorer. Thanks for any help you can provide. P.S. I also tried executing PSExec directly from the network location


Solution

  • It is wrong to enclose just a part of an argument string in double quotes on containing a space character or one of the characters &()[]{}^=;!'+,`~|<>. The last 3 characters can't be used in a file/folder name, just in other argument strings.

    Windows command interpreter respectively the startup code of the executable (= code of executable run before main parsing command line string) must do a lot of extra work to automatically correct a wrong quoted argument string if the startup code of executable does such an auto-correction at all.

    See answer on batch file: list rar file in specific folder and write result into text file and answer on How to set environment variables with spaces? for details on what could happen on wrong double quoting an argument string.

    So wrong is:

    net use M: \\ServerName\"R Share"
    

    Correct is:

    net use M: "\\ServerName\R Share"
    

    Argument 0 is net, argument 1 is use, argument 2 is M: and argument 3 is "\\ServerName\R Share".

    However, net.exe has a startup code which interprets \\ServerName\"R Share" with automatic correction as \\ServerName\R Share. So this is not the coding error resulting in system error 53 message.

    System error 53 is caused by assigning \\ServerName\R Share to drive letter M: and using next:

    M:\"R Share"\PSExec\psexec.exe
    

    The share R Share is already included in M:. So the correct line would be:

    "M:\PSExec\psexec.exe"
    

    The entire batch code with corrections applied:

    @echo off
    echo Mounting ServerName as local drive
    %SystemRoot%\System32\net.exe use M: "\\ServerName\R Share"
    echo Clearing IE Cache
    %SystemRoot%\System32\taskkill.exe /im iexplore.exe /f
    "M:\PSExec\psexec.exe" -l c:\windows\system32\RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 32
    echo Removing ServerName
    %SystemRoot%\System32\net.exe use M: /delete
    echo IE Cleared
    pause
    

    It is better to specify executables in system directory of Windows with full path and with file extension because then Windows command interpreter must not search for those executables using local environment variables PATH and PATHEXT. A batch file being as much independent as possible on current values of those two environment variables is a batch file working also on wrongly updated system PATH, see for example Why does the command "Timeout" in a batch file suddenly not work anymore?

    This batch code could be optimized by using command PUSHD which pushes the current directory path on stack and sets the specified directory as current directory whereby with enabled command extensions a UNC path is automatically mapped to next free drive letter. Command extensions are enabled by default, but it is of course possible to explicitly enable them for security. The command POPD removes the mapping done by PUSHD and sets the current directory back to the directory pushed before on stack.

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    pushd "\\ServerName\R Share"
    %SystemRoot%\System32\taskkill.exe /im iexplore.exe /f
    echo Current directory is: %CD%
    PSExec\psexec.exe -l c:\windows\system32\RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 32
    popd
    echo IE Cleared
    endlocal
    pause
    

    Note: PUSHD and POPD can't be used if user name and/or password must be also used on command line to successfully map the network share to a drive letter and accessing the directories and files on that share because the batch file is running with a user account not having required access on network share.

    Hints regarding terminating versus killing IE

    I think using TASKKILL without /f would be better here. Internet Explorer should not be killed by operating system as done on using option /F. It would be better to use TASKKILL without /f which results in sending to IE the event message to close/exit/terminate itself which IE processes usually and terminates itself gracefully. Of course a delay of about 1 to 2 seconds should be added before the next command is executed to give IE the necessary time to gracefully terminate itself.

    The optimal solution would be using TASKKILL without /f to send to IE the WM_CLOSE message, wait 1 or 2 seconds, check with TASKLIST if IE really terminated and otherwise use TASKKILL with /f to kill not responding IE process by the operating system.

    And last it is possible that multiple instances of Internet Explorer are running and therefore it would be better to use TASKLIST to get the process identifier (PID) of each running Internet Explorer instance if there is an IE instance running at all, use TASKKILL without /F on each running instance of IE using PID, check after 1 to 2 seconds with TASKLIST if all instances of IE gracefully terminated and in case of 1 or more instances of IE are still running use TASKKILL with /F to kill those remaining IE instances not responding in the 1 to 2 seconds with terminating itself.