Case Else:

/*** Code’s last stand ***/

Case Else: Killer Whales hunting off the Haida Gwaii (or Queen Charlotte Islands)

How to close open files on a server share

May 17th, 2008 · 14 Comments

One of our departments needed to upgrade software on a number of their servers, but it is an application that users like to leave running when they leave at night, and the connected files keep the upgrade from working. They needed to close thousands of open files in the application shares on several hundred servers.

They asked me if there’s a way to close all of the connected files in the application shares on those servers. I put together this little batch script to do just that.

@echo off
(set share=d:\share\)
REM !! IMPORTANT set length in 4th from last line !!

FOR /f "Skip=4 tokens=1,2" %%i in ('NET FILES') do (
 IF /I NOT "%%i"=="The" (
  call :checkpath %%i "%%j"
 )
)
::pause
GOTO :EOF

:checkpath
 set id=%1
 set folder=%~2\
 :: !! The last number in the next line needs to
 :: be the length of the SHARE string
 SET root=%FOLDER:~0,9%
 IF /I NOT "%ROOT%"=="%SHARE%" GOTO :EOF
 echo %ID% is open on %FOLDER%. Closing...
 NET FILE %id% /CLOSE

This was run directly from the package that pushes the installer, but it could just as easily be pushed in any other manner. You could also use it on a schedule to drop open locks. You just need to uncomment the pause if you want to see the results. (the :: is the equivalent of REM in batch, except it actually runs faster.)

Tags: Batch Scripts · dev · scripting

14 responses so far ↓

  • 1 Christian // Oct 20, 2008 at 2:55 am

    how to deal with long Paths to the Share?
    net files displays  c:\share\…\file

  • 2 Neil // Nov 13, 2008 at 12:12 pm

    Christian,

    Just make sure you match the SHARE variable to whatever the path to the share is, ie:

    (SET SHARE=c:\share\…\)

    and make sure you set the length near the end:

    SET root=%FOLDER:~0,9%

    ‘9’ should be whatever the length of SHARE is. That line chops off the beginning of the files returned from NET FILES, and compares it to the SHARE you set. If it matches, it’s dropped, and if it doesn’t match it’s ignored.

    The upshot is that anything below the path you set in SHARE will be closed. (Technically, any file whose path begins with that string.)

    HTH

  • 3 Anthony // Feb 25, 2009 at 3:24 am

    I have a need to not close open shares, but, one share-a particular file that needs to be closed so someone else can reopen it. It gets locked up often enough that it has become a nuisance!

    The problem is that although the file path is always the same, all the tools need the ID of the process, which changes every time it is opened on the server where i need to run it…to then use the net file command to close it.

    I would love to run it every 1 minute as well. I appreciate your code. I was searching for weeks to find someone who had a similar need – and solved it. It seems that it is you!

    Thanks!

  • 4 Ashley // Feb 9, 2010 at 11:13 pm

    how to deal with long Paths to the Share?
    net files displays c:\share\…\file

    Set folder=%~2\

    sets it to the filename within the folder i have set as SHARE eg: C:\Share\Database So if a file by CAT.HDX is open within this folder the Folder variable gets set to that.

    when I am setting root=%FOLDER:~0,53% i get the path with the filename set as root because the lenth of th epath is being displayed as indicated by Christian earlier…..

    it never goes to closing the file as the IF command after that is never equal….

    Can you please help….The length of my SHARE path is 53 characters…..

    Thanks

  • 5 Neil // Feb 10, 2010 at 12:52 am

    Ashley, I’m not certain I understand the question; but try replacing the last three lines with these:

    Echo.
    Echo %ROOT%*
    Echo %SHARE%*

    Then run it, and make sure the two strings are the same length. If not, adjust your ’53’ until they are. Chances are, you’re not accounting for the ‘\’, and it needs to be 54 characters, or something similar.

  • 6 Ashley // Feb 10, 2010 at 12:59 am

    Here is the extract of the logs after running the file:

    C:\Documents and Settings\adm2sultana>(set share=F:\Infrastructure\Snowinst2\AppData\Nielsen\DATABASE\ ) – is 53 including the /

    C:\Documents and Settings\adm2sultana>REM !! IMPORTANT set length in 4th from last line !!

    C:\Documents and Settings\adm2sultana>FOR /F “Skip=4 tokens=1,2″ %i in (‘NET FILES’) do (IF /I NOT “%i” == “The” (call :checkpath %i “%j” ) )

    C:\Documents and Settings\adm2sultana>(IF /I NOT “14232357” == “The” (call :checkpath 14232357 “F:\Infrastructure…V_CONFECTIONERY.IDX” ) ) – This one is a problem as it is not displaying the whole path and hence when trying to trim this to 53 charecters….it returns the same.

    C:\Documents and Settings\adm2sultana>set id=14232357

    C:\Documents and Settings\adm2sultana>set folder=F:\Infrastructure…V_CONFECTIONERY.IDX\

    C:\Documents and Settings\adm2sultana>SET root=F:\Infrastructure…V_CONFECTIONERY.IDX\

    C:\Documents and Settings\adm2sultana>IF /I NOT “F:\Infrastructure…V_CONFECTIONERY.IDX\ ” == “F:\Infrastructure\Snowinst2\AppData\Nielsen\DATABASE\” GOTO :EOF

    C:\Documents and Settings\adm2sultana>(IF /I NOT “14232359” == “The” (call :checkpath 14232359 “F:\Infrastructure…V_CONFECTIONERY.TAD” ) )

    C:\Documents and Settings\adm2sultana>set id=14232359

    C:\Documents and Settings\adm2sultana>set folder=F:\Infrastructure…V_CONFECTIONERY.TAD\

    C:\Documents and Settings\adm2sultana>SET root=F:\Infrastructure…V_CONFECTIONERY.TAD\

    C:\Documents and Settings\adm2sultana>IF /I NOT “F:\Infrastructure…V_CONFECTIONERY.TAD\ ” == “F:\Infrastructure\Snowinst2\AppData\Nielsen\DATABASE\” GOTO :EOF

    C:\Documents and Settings\adm2sultana>(IF /I NOT “14232360” == “The” (call :checkpath 14232360 “F:\Infrastructure…V_CONFECTIONERY.CHR” ) )

    C:\Documents and Settings\adm2sultana>set id=14232360

    C:\Documents and Settings\adm2sultana>set folder=F:\Infrastructure…V_CONFECTIONERY.CHR\

    C:\Documents and Settings\adm2sultana>SET root=F:\Infrastructure…V_CONFECTIONERY.CHR\

    C:\Documents and Settings\adm2sultana>IF /I NOT “F:\Infrastructure…V_CONFECTIONERY.CHR\ ” == “F:\Infrastructure\Snowinst2\AppData\Nielsen\DATABASE\” GOTO :EOF

    C:\Documents and Settings\adm2sultana>(IF /I NOT “The” == “The” (call :checkpath The “command” ) )

    C:\Documents and Settings\adm2sultana>GOTO :EOF

  • 7 Neil // Feb 10, 2010 at 1:51 am

    Ashley, I see what you mean about the compressed path. I expect you’re hitting a limit of the net command.

    My advice would be to try setting a shorter share (eg, \Database). Even if all you use it for is this script, it should work.

  • 8 Ashley // Feb 10, 2010 at 1:58 am

    When setting SHARE can I use UNC path?

    How will this fix the issue because the NET FILES command is returning the compressed path?

  • 9 Neil // Feb 10, 2010 at 10:07 am

    Scratch the last line… it was late.

    You’ll need the SHARE variable to match the output of NET FILES if you need to restrict the files you close to a certain path (ie, not close all open files.)

    If NET FILES is truncating your paths, you will need to use shorter ones, or the Script just isn’t up to what you need it for. You would proably be better off looking into a WMI or PowerShell solution.

  • 10 Ashley // Feb 10, 2010 at 8:59 pm

    How about using OPENFILES instead of Net Files? The OPENFILES /Query /V command gives the full path to the files. I cannot seem to fit this in your script. Can you help please ?

  • 11 David // Oct 25, 2010 at 1:14 pm

    Many Thanks Niel!

    Ashley – I was having the same issue as you and modified neils code to work for me, I am getting strange errors but it still runs. I dont know enought about this kind of scripting to figure out why, but if anyone sees my error please let me know. I hope this helps someone.

    @echo off
    (set share=D:\LONGPATH\)
    REM !! IMPORTANT set length in 4th from last line !!

    FOR /f “Skip=4 tokens=2,7″ %%i in (‘OPENFILES /Query /V’) do (
    IF /I NOT “%%i”==”The” (
    call :checkpath %%i “%%j”
    )
    )
    pause
    GOTO :EOF

    :checkpath
    set id=%1
    set folder=%~2\
    :: !! The last number in the next line needs to
    :: be the length of the SHARE string
    SET root=%FOLDER:~0,40%
    IF /I NOT “%ROOT%”==”%SHARE%” GOTO :EOF
    Echo %SHARE%
    Echo %ROOT%
    echo %ID% is open on %FOLDER%. Closing…
    NET FILE %id% /CLOSE

  • 12 Ashley // Oct 25, 2010 at 6:01 pm

    I managed to get what I wanted by the below code. It closes all open files in the path specified on the server when run. Hope this helps?

    Dim Share

    Set objConnection = GetObject(“WinNT://SERVERNAME/LanmanServer”)
    Set colSessions = objConnection.Sessions
    Set colResources = objConnection.Resources
    Set Shell = CreateObject(“WScript.Shell”)

    On Error Resume Next

    For Each objResource in colResources

    Share = left(objResource.Path,53)
    If Share = “F:\Infrastructure\Snowinst2\AppData\Nielsen\database\” Then

    Shell.Run”OPENFILES /Disconnect /ID “&objResource.Name,1,True

    End If
    Next

  • 13 Chris // Oct 24, 2011 at 4:14 am

    Thanks a lot for this Script, I was looking exactly for this and it does its job perfectly.

  • 14 Matthijn // Jul 2, 2013 at 4:07 pm

    Thanks tested it on Windows 8 and works perfect

Leave a Comment