http://www.perlmonks.org?node_id=491533
Category: Win32 Stuff
Author/Contact Info grinder on perlmonks
Description:

I need to transfer files from one Windows machine to another. I've always needed to one way or another, over the years, and have always hacked up fragile workarounds, usuall involving batch files, "RunAs" commands, shares using hard-coded drive letters and so on.

All the pieces are already bundled with the Perl distribution, it was just a question of putting them together. This code, then, lays down an approach to the problem in a Perl-only manner.

# copy files to a remote share requiring authentication
#
# This program demonstrates how to find a free drive letter
# on the local machine, setting up the shared connection,
# copying the file over and then tearing down the connection
# afterwards. I hope this helps someone else save the two hours
# it took me to gather all the loose ends together.
#
# copyright (c) David Landgren 2005
#
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.

use strict;
use warnings;

use Win32::NetResource qw/GetUNCName AddConnection CancelConnection/;
use Win32API::File qw/ CopyFile fileLastError /;

use constant SHARE_NAME => '\\\\remote_svr\\sharename'; # must use bac
+kslashes
use constant USER_NAME  => 'myusername';
use constant PASSWORD   => 'mysekretpassword';

my $drive;
for my $letter ('g' .. 'z' ) {
    my $mapped;
    $drive = "$letter:";
    GetUNCName( $mapped, $drive );
    last if not $mapped;
}

my $share = {
    RemoteName => SHARE_NAME,
    LocalName  => $drive,
};

print "connecting $share->{RemoteName} to $share->{LocalName}\n";
if( not AddConnection( $share, PASSWORD, USER_NAME, 0 )) {
    die "connection error:\n", win32err();
}

for my $file( @ARGV ) {
    print "copying $file\n";
    CopyFile( $file, "$share->{LocalName}$file", 0 )
        or print "\tfailed: " . fileLastError() . "\n";
}

if( not CancelConnection( $share->{LocalName}, 0, 1 )) {
    print "disconnection error:\n", win32err();
}

sub win32err {
    my $err;
    # Win32::GetError($err); -- bug spotted by puploki
    Win32::NetResource::GetError($err);
    Win32::FormatMessage($err);
}