You've got so many calls and shells to other scripts/programs it's really no telling where the hang up is.

I'd start by putting in some debug code in each section and displaying this information to the screen, so you know where the script is at a specific time and then can watch when it hangs. The problem is, with so many groups this could be somewhat tedious. Creating a log file for each user with sections and time stamps might be more suitable.

The other thing that might help is to check the values before trying to change them. I mean why keep setting values over and over. It adds code to your script, but a read is always faster than a write.

below is just a quick sudo example... you will need to format functions properly for them to work.
 Code:
If not exist("somefile")
  copy "somefile"
endif

if readvalue("somevalue")<>"blah"
  $RC=writevalue("somevalue")
endif