in reply to I just can't see the error in this code

Oh my. Where to begin? Hmm. How about here:

while (<SHORTNAMES>) { # loop through all lines of shor +tnames my @array2 = split /:/; # seperate by those ugly colens + created by OSX $finishedusers{$array2[7]} = $array2[0];# Setup keys: "Long Name" + => "shortname" }
What's with all of the commentary? Why not make your code self-documenting? To wit:
open SHORTNAMES, "< $usershortfile" or die "$!"; while (<SHORTNAMES>) { my ($longname,$shortname) = (split /:/)[7,0]; $finishedusers{$longname} = $shortname; } close SHORTNAMES;

Notice how I use descriptive variable names? Also, I closed the file when I was finished mucking with it. Good practice that. And you should also open a file quite near where you intend on using it. The USERNUMS file is open for quite a while before you ever do anything with it.

Skipping down ... surely this can't be right?

my %final; # Hash %final while (($fullname, $uid) = each(%final)) { # Loop through hash

You're creating an empty hash then iterating over it. That's going to be one short loop! :-)

And even if your loop did work, it's doing too much work because you're not taking advantage of the nature of hashes but rather iterating over another hash to find the keys that match in the first one. The canonical way to do this is simply use the key from one hash as the key into the other:

while (($fullname, $uid) = each(%lookup)) { # corrected to use %l +ookup hash instead. next unless exists $finishedusers{$fullname}; system ("cp '$oldserv/$uid/Documents/*' '$newserv/$finishedusers{$f +ullname}/Documents/'"); print "Copying Files for $fullname"; }

I think I'll stop there as I'm tired now.