SMS/SCCM & Batch Files - Important notes on running .BAT files from UNC in SMS/SCCM

THE PROBLEM

When you run a .BAT file from a UNC path, the first thing you might notice is the warning about "UNC paths are not supported.  Defaulting to the Windows Directory"

All this really means is that the current working folder is your Windows folder, and not the UNC path to where the script is sitting.

The problem with this is that any commands inside your .bat file that try to call or reference a file that you know is in the same UNC path as the .bat file will come up empty because the directory is now Windows.

THE SOLUTION

This isn't really that big of a deal.  You can get the folder from where the script is being run by using %~dp0.

Let me explain that a little better...

When a .BAT file is being executed, %0 evaluates to the full drive, path, filename and extension of the .bat file itself.  %1 refers to the first parameter passed in, %2 to the second parameter and so on.  So if you had a .bat file that looked like this:

SNIPPET #1 - .BAT FILE THAT ECHO'S IT'S OWN FILENAME

@ECHO OFF
ECHO %0
PAUSE

OUTPUT #1
When you run it you would get the drive, path, filename and extension of the .bat file right there in the output

Now, since we have the full drive and path, let's just use some Windows Shell scripting magic to remove the filename and extension and just return the drive and path:

Here are the commands you can use to modify that %0 (which contains a drive, path, filename and extension)

(taken from the syntax help on the FOR command...run FOR /? from a command prompt, and replace %I with %0)

    %~I         - expands %I removing any surrounding quotes (")
    %~fI        - expands %I to a fully qualified path name
    %~dI        - expands %I to a drive letter only
    %~pI        - expands %I to a path only
    %~nI        - expands %I to a file name only
    %~xI        - expands %I to a file extension only
    %~sI        - expanded path contains short names only
    %~aI        - expands %I to file attributes of file
    %~tI        - expands %I to date/time of file
    %~zI        - expands %I to size of file
    %~$PATH:I   - searches the directories listed in the PATH
                   environment variable and expands %I to the
                   fully qualified name of the first one found.
                   If the environment variable name is not
                   defined or the file is not found by the
                   search, then this modifier expands to the
                   empty string

The modifiers can be combined to get compound results:

    %~dpI       - expands %I to a drive letter and path only
    %~nxI       - expands %I to a file name and extension only
    %~fsI       - expands %I to a full path name with short names only
    %~dp$PATH:I - searches the directories listed in the PATH
                   environment variable for %I and expands to the
                   drive letter and path of the first one found.
    %~ftzaI     - expands %I to a DIR like output line

So, let's combine the "d" and "p" to get the drive and path

SNIPPET #2 - .BAT FILE THAT ECHO'S IT'S OWN PATH

@ECHO OFF
ECHO %~dp0
PAUSE

OUTPUT #2
When you run this, you'll get just the drive (in the case of UNC's that's a \\) and path

 

So, if you have a more complex .BAT file and want to execute any programs that exist in the same folder as the .BAT file sits, you simply need to reference %~dp0.  Perhaps it would be easier to understand if we set a variable called THISDIR...

SNIPPET #3 - .BAT FILE THAT SETS VARIABLE AND CALLS PROGRAMS

@ECHO OFF
SETLOCAL

Set THISDIR = %~dp0

"%THISDIR%file.exe"
"%THISDIR%myFile.exe" /f1"%THISDIR%myINI.ini"

PAUSE

NOTES:

  1. You need quotes around your files if there are spaces in the path.
  2. %~dp0 includes the trailing backslash \ so you use %THISDIR%File.exe instead of %THISDIR%\File.exe
  3. SETLOCAL is just something that I use to make sure we're only changing variables in the current script's scope.
  4. Obviously you wouldn't have a PAUSE in a real script that you send to a bunch of machines or it will hang :)

 

SUMMARY

So, we've learned

  1.  When you run a .bat file from a UNC path, the current working directory gets set to c:\Windows
  2. %0 evaluates to the full drive, path, filename and extension of the .bat file. (%1, %2, etc refer to the params)
  3. %~dp0 evaluates to the drive & path of the current .bat file, essentially to what the current working directory WOULD be if UNC paths were supported.
  4. %~dp0 includes the trailing backslash so if you're going to use it to reference files, use
    %~dp0FILENAME.EXE not %~dp0\FILENAME.EXE 
       or, if you put %~dp0 into a variable called THISDIR, use
    %THISDIR%FILENAME.EXE not %THISDIR%\FILENAME.EXE
  5. If your path contains spaces, you'll need quotes around things.

Number2 (John Nelson)
MyITForum - Forum Posts
MyITForum - Blog
Add to Google

Published Friday, August 15, 2008 4:31 PM by jnelson

Comments

# re: SMS/SCCM & Batch Files - Important notes on running .BAT files from UNC in SMS/SCCM

Tuesday, August 19, 2008 11:02 AM by scassells

This is a great post.  It has been a long time since i've used %0 and the conjunction with text parsing from the For help is really creative.

Great job John

Powered by Community Server (Commercial Edition), by Telligent Systems