Brad - Notice that he's using RUN and not SHELL, so - while there's some brief delay to launch, these processes run asynchronously to the login script. Improves performance, but you can't tell if they are successful. The LoadHive() function is often overlooked and can load many reg values with a single command, similar to running "RegEdit /s file.reg" and could be used to eliminate the RUN commands entirely with little or no change to the REG file.

Sparkie - Calls to VB and other external processes all affect performance. It's crucial to bring as many processes internal as possible, and to not duplicate effort during each login. Group common processes together and only run all of them if one particular test fails whenever possible. For example - Test for "User Customization" - if the reg key is not present, do all user customization tasks, rather than individually testing for Outlook, Office, accounting, Acrobat, Flash, and whatever else might be in a per-user customization. Use a date rather than a boolean, and set a flag externally that defines the last time the user customization was changed. If the user's reg value is older than the external date, run all the updates.

I've spent a lot of time optimizing our login script, and it's been in service at many companies in one form or another since 1996. Our login script runs so fast I was asked to add a delay option. Timing our script with 5 drive and 3 printer mappings results in 0.88 seconds of process time(seven-eighths of a second). This includes the time to process various authorization tests to determine which of several resources should be mapped. Adding the Outlook signature refresh using the code from the vault adds another half-second.

Two key elements of our script are that all data is external to the script in an INI file, and all authorization is performed before any actions are actually processed. One way to optimize your code is to display (or log) the elapsed time, in milliseconds, at various points in your script. Here's an example:
 Code:
$STime = @TICKS  ; place this at the top of the script
;
; script commands...
'Task - Elapsed: ' 1.0 * (@TICKS - $STime) / 1000.0 ' seconds' @CRLF
;
; more script commands, then repeat above to show cumulative time
Insert the "Elapsed" line after each major code block, or after functions that you suspect are taking a long time. If you use my fMsg function, you can configure it so it will display these messages only when a DEBUG variable is set (or set to a specific value or greater). "Task" should represent the recently completed task, so the time between the prior and current tasks can be determined without guesswork.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D