Error Logging in Batch Files and Microsoft System

advertisement
Error Logging in Batch Files and Microsoft System Center Configuration
Manager 2012
When Configuration Manager 2012 launches a batch file on a command line (using either an Application, Package or
TS Run Command Line) what happens behind the scenes is the executable cmd.exe is launched running each line of
the batch file. When Cmd.exe runs it holds the error value from the execution of each line of the batch file in a
variable called ERRORLEVEL. Since cmd.exe’s execution of each line of the batch file will not stop if a non-zero
return code is returned from a specific line of the batch file, the ERRORLEVEL variable is continually overwritten.
When the last line of the batch file is executed, the line's return code will be entered into ERRORLEVEL. At this point
(unless cmd.exe is instructed otherwise), cmd.exe will close and return the present ERRORLEVEL as the return code
which will be logged in Configuration Manager 2012's log files. In summary, by default only the last line of a batch file
will be returned to Configuration Manager 2012.
Example of How a Batch Behaves and Reports Errors in Configuration Manager 2012
Let's look at an example of this behavior. Consider a batch file with a single command that has an error such as
'copy' with no parameters
Batch file contents:
copy
When this batch file is run on a client through Software Center (I chose a simple package) the following error will be
displayed in Software Center. This is because the copy command returns 1 if there is a bad parameter.
Let’s now change the batch file by adding a remark at the end which will always execute successfully.
Batch file contents:
copy
rem This will always work
When we redistribute and check the return code in Software Center we see that no error is displayed since the last
line was successful.
How to Add Logging to Every Line in a Batch File and Report a Failure in Configuration Manager
2012
Now what if we want EVERY line within a batch file logged within Configuration Manager 2012. As with other
scripting, a decision will have to be made on what to do when an error is encountered. For this example, I am
choosing to stop the batch file and return the error to Configuration Manager 2012 if it is non-zero. NOTE that NOT
EVERY command returns a 0 return code when it is successful. Scenarios like rerunning a script and thereby
creating a directory that’s already there OR running an .msi that has a reboot pending may return non-zero return
codes. It is important to ensure the error logging you put in place acts how you want it to.
Now for an example on how to return any non-zero return codes to Configuration Manager 2012 from any line in the
batch file. Adding the following line in the batch immediately following the line you want to return will allow you to
return a specific error number and exit the batch file. This command will trigger if the error is 1 or greater, then exit
with the return code specified.
IF ERRORLEVEL 1 EXIT /B <error to return>
A simple strategy around using this command to map errors to where they occur within the batch file could be to set
them up sequentially and perhaps starting a little higher to highlight that’s they are custom errors. When an error is
reported to Configuration Manager 2012, the batch file can then be referenced to see which line failed. For example,
a two line batch file might look like:
Md c:\temp\test
IF ERRORLEVEL 1 EXIT /B 11
Copy “%~dp0test.txt” c:\temp\test /y
IF ERRORLEVEL 1 EXIT /B 12
Some command-shell commands like ‘md’ will have non-zero commands if they are rerun. In this case it’s because
creating a directory that’s already present generates a non-zero error. A strategy to work around this might be to
avoid error logging on lines that react this way if rerunning is a scenario that’s supported. The example batch file
would then be as shown:
Md c:\temp\test
Copy “%~dp0test.txt” c:\temp\test /y
IF ERRORLEVEL 1 EXIT /B 11
How to View Errors within Configuration Manager 2012
Moving on to how to check for errors within the Configuration Manager 2012 console and on the client, I’ll cover
Configuration Manager 2012 Packages and Task Sequences. Since Configuration Manager 2012 Applications
evaluate to true/false based on an assigned criteria this criteria can be used to detect any errors instead of built-in
error logging so it will not discussed here.
First, let’s make a deliberate error to the batch file we used in the last section. Then distribute a Package containing it
and see how the custom error looks in Software Center. Here’s the batch file with the error:
Md c:\temp\test
Cpy “%~dp0test.txt” c:\temp\test /y
IF ERRORLEVEL 1 EXIT /B 11
When this batch file is run on a client through Software Center the following error is displayed in Software Center.
Within the Configuration Manager 2012 console this same error can be seen in both the Deployment Monitoring
section and within the State Messages. Note to reference the state messages grab the deployment ID from the first
picture and put it into the state message query ‘All Status Messages for a Specific Deployment at a Specific Site’. A
screenshot of each view is shown below:
Moving on to how to monitor custom errors within a task sequence I put together a task sequence that runs the
following steps with ‘Continue on Error’ checked for all three:
-
Runs a package with the same batch file from the last section
Runs the same batch file using the TS Run Command Line step referencing a package
Since ‘Continue on Error’ is set for both steps the TS will finish regardless and should have custom errors logged in
the state messages and smsts.log when the batch file runs in each of the first two steps.
Looking at the smsts.log on the client the first two steps report the custom error code as shown below and when
executed from the TS run command line step even provide a detail on what the issue was:
TS Run Command Line Referencing a Package:
On a side note, the next line in the log will attempt to translate the custom error code into the associated Windows
error. In this case the description will not be correct since the custom error 11 was arbitrary. It should be possible to
leave the native error code from cmd.exe, but then it may be difficult to determine what line the error occurred on.
Package:
In the case of the package, a hex prefix of 0x80070000 is added to the exit code of 11 creating 0x8007000B which
when translated to decimal is the exit code shown of 2147942411.
Next, how do we report on these errors within the Configuration Manager 2012 console? Since the Deployment
Monitoring section will only tell you that the TS step failed, we’ll need to look at the state messages. Use the same tip
we used before to grab the deployment ID from the Deployment Monitoring section and put it into the state message
query ‘All Status Messages for a Specific Deployment at a Specific Site’. The screenshots below show the
corresponding errors:
TS Run Command Line Referencing a Package:
Package:
That’s all I have for now. If this technique is useful to you I hope this demonstration gave you some ideas on how to
implement it. Jim Riekse
Download