I run across a lot of questions in the forums and from customers about why their batch files are failing when run using a ConfigMgr program. There is an easy answer to this (usually): the command shell, which executes batch files, cannot change its current directory to a UNC path. Although that’s a straight forward statement, I thought I’d create some demo programs to show the ramifications of this in action and to compare against an executable and a VBScript.
For each type, there are two possibilities, running from the DP — which is when a UNC is used — or running from the cache which is typically referred to as a download and execute. The choice between these two possibilities is set on the advertisement and not the program.
exe
For the exe, I wrote a small application that called the Win32 APIs GetCurrentUser and GetCurrentDirectory.
Run from DP
Run from Cache
VBScript
For the VBScript, I used the UserName and UserDomain of the WScript.Network object and the CurrentDirectory property of the WScript.Shell object.
Set WshNetwork = WScript.CreateObject("WScript.Network") Set WshShell = WScript.CreateObject("WScript.Shell") info = WshNetwork.UserDomain & "" & WshNetwork.UserName & vbCrLf & WshShell.CurrentDirectory WScript.Echo info
Run from DP
Run from Cache
batch
For the batch file, I output to a local file the USERNAME and USERDOMAIN environment variables as well as the “cd” command which if used by itself echoes the current directory.
echo %USERDOMAIN% > "c:context.txt" echo %USERNAME% >> "c:context.txt" cd >> "c:context.txt"
As you can see below, the current directory for the batch file when run from the DP is C:\Windows. Thus, if your batch file tries to call anything from the package using a relative path, it will fail.
Note that is XP/2003, the USERNAME and USERDOMAIN environment variables are blank for the SYSTEM account, thus the first two lines of the just say “ECHO is on.”
Run from DP
Run from Cache
batch2
This batch file calls the exe using the %~dp0 batch parameter: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/percent.mspx?mfr=true. This parameter returns the directory that the batch file was run from (including a trailing backslash).
%~dp0context.exe
The use of this parameter is pretty well documented within SMSConfigMgr circles — although it is not specific to SMS/ConfigMgr in any way — it is one possible solution to the batch file problem. Another is to set the program to use a drive letter instead of a UNC in the ConfigMgr program properties. This works; however, if you try to
use a download and execute advertisement for the program, you will get an error because these two settings — run with drive letter and download and execute — are not compatible. %~dp0 works either way though, so is usually the best solution.
Another thing to point out is that the child process inherits the current directory from the parent process, in this case, the child is the exe and the parent is the command shell. This isn’t a big deal in the run from cache scenario, but note the current directory in the run from DP scenario for the exe.
Also notice the warning at the top of the command prompt in the Run from DP scenario. It more or less sums up what I said in the opening paragraph of this post.
Run from DP
Second Batch Run From DP
Run from Cache
Second Batch Run From Cache
The main thing to keep in mind when using ConfigMgr programs, is that ConfigMgr is not doing anything “magic”. It is simply running the command-line you tell it to run. Things don’t work the way you think they should sometimes because you’ve made some false assumptions, not because ConfigMgr is broken.