|SMS/SCCM & Batch Files - Important notes on running .BAT files from UNC in SMS/SCCM|
By: John Nelson
Posted On: 8/20/2008
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"
Click to view image
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.
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
When you run it you would get the drive, path, filename and extension of the .bat file right there in the output
Click to view image
Now, since we have the full drive and path, let's just use some Windows Shell scripting magic to remove the filename and path 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
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
When you run this, you'll get just the drive (in the case of UNC's that's a \\) and path
Click to view image
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
Set THISDIR = %~dp0
- You need quotes around your files if there are spaces in the path.
- %~dp0 includes the trailing backslash \ so you use %THISDIR%File.exe instead of %THISDIR%\File.exe
- SETLOCAL is just something that I use to make sure we're only changing variables in the current script's scope.
- Obviously you wouldn't have a PAUSE in a real script that you send to a bunch of machines or it will hang :)
So, we've learned
- When you run a .bat file from a UNC path, the current working directory gets set to c:\Windows
- %0 evaluates to the full drive, path, filename and extension of the .bat file. (%1, %2, etc refer to the params)
- %~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.
- %~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
- If your path contains spaces, you'll need quotes around things.