3dbc has asked for the wisdom of the Perl Monks concerning the following question:

Hi Perlmonks,

I'm developing a perl script on M$ for temporarily mapping a drive and then using robocopy to copy over a file I created to the NAS. Because of 2012 windows junk robocopy is choking with access denied errors without a drive mapping to the full unc path prior to executing the robocopy. pushd doesn't work and neither does net use without a drive letter. So my solution is to run a 'fsutil fsinfo drives' before triggering the net use, but want to use perl to decipher the available drive letter and looking for some wisdom on how best to do this.

my subprogram looks something like this, but I'm working to extend it for the above purpose.
sub copyDat { my $file = basename($_[0]); my $path = dirname($_[0]); #$path .= "\\"; #trailing slash was needed for xcopy, but xcopy no +t as reliable as robocopy for full automation with better logging. print "\n File: $file \n\n"; print "\n Dirname: $path \n\n"; chomp $_[1]; my $map = $_[1]; my $map = $1 if($map=~/(.*)\\$/); #trailing slash not needed for r +obocopy, but not sure if it's as picky, but it definately needs a map +ping and not a unc path to work. print "\nnet use $map && ROBOCOPY \"$path\" \"$map\" $file /B && n +et use $map /delete\n\n"; #I'll add some more flags to robocopy to j +azz it up but want to get this sequence to work first. open TASK, "net use $map && ROBOCOPY \"$path\" \"$map\" $file /B & +& net use $map /delete 2>&1|" or die "cannot pushd $_[1]"; while (<TASK>) { print; #chomp; #chop; #return $_; } }


Again, if I try to robocopy using unc path I get the following error: ERROR 5 (0x00000005) Getting File System Type of Destination Access is denied.

This is pretty well documented on google too, maybe it's something with 2012, who knows, but all I know is I want to use robocopy and that I need to map the drive first to an available drive letter which won't be known until runtime.

Thanks much perlmonks, if anyone's up for the challenge thanks, otherwise I'll post what I decided to write as soon as I've figured out how to get perl to pull a drive letter not in the list windows command 'fsutil fsinfo drives' returns. I'm sure there's a quick and simple solution I didn't want to reinvent the wheel.

- 3dbc

Replies are listed 'Best First'.
Re: perl robocopy to temp mapped drive.
by NetWallah (Canon) on Oct 04, 2018 at 23:07 UTC
    If I understand your question, you are trying to find a drive letter you can pass to "net use" to map.

    My suggestion is that you let "net use" figure that out, ane let you know what it mapped.

    The syntax "net use * \\UNC\PATH" will pick an available drive letter.

    You can scan the output of that command to discover what drive it used. eg:

    >net use * \\myserver\pub\MyPath Drive Y: is now connected to \\myserver\pub\MyPath. The command completed successfully.

                    Memory fault   --   brain fried

      This does it, thanks for the help Perl Monks!
      # $destination is the full unc path to the share directory # $extract is the full path the the individual file to be copied my $drive = netUse ($destination); copyDat ($extract, $drive); sub netUse { my @net_use_output; my $output; chomp $_[0]; $_ = $1 if($_[0]=~/(.*)\\$/); print "\nnet use \* \"$_[0]\""; #my $output = `net use \* \"$_[0]\" 2>&1|`; open TASK, "net use \* \"$_[0]\" 2>&1|" or die "cannot map $_[0]" +; while (<TASK>) { print "\n"; print; #chomp; #chop; push (@net_use_output, $_); #return $_; } print join(", ", @net_use_output); print "\n"; print "\n"; print "-----\n"; print @net_use_output[0]; $output = $2 if(@net_use_output[0]=~/^(Drive\s)([A-Z])\:(.*)$/); print "\n"; print "\n"; print "-----\n"; print $output; return $output; } sub copyDat { my $file = basename($_[0]); my $path = dirname($_[0]); #$path .= "\\"; #This one's for James print "\n File: $file \n\n"; print "\n Dirname: $path \n\n"; #chomp $_[1]; #my $map = $_[1]; #my $map = $1 if($map=~/(.*)\\$/); print "\nROBOCOPY \"$path\" $_[1]\:\\ $file /B \n\n"; open TASK, "ROBOCOPY \"$path\" $_[1]\:\\ $file /B 2>&1|" or die "c +annot $!"; while (<TASK>) { print; #return $_; } print "\nnet use $_[1]\:\\ /delete \n\n"; open TASK2, "net use $_[1]\: /delete 2>&1|" or die "cannot $!"; while (<TASK2>) { print; #return $_; } }
      - 3dbc
      I attempted to run net use * and pull the output but am getting errors.

      #!/usr/bin/perl -w use strict; use warnings; my $destination = qq(\\\\BLAH\\NESTED\\OBFUSCATED\.WITH SPECIAL_CHARS\ +\SHARE\\NAME\\DOWN\\DEEP); netUse ($destination); sub netUse { my @net_use_output; chomp $_[0]; $_ = $1 if($_[0]=~/(.*)\\$/); print "\nnet use \* \"$_[0]\""; open TASK, "net use \* \"$_[0]\"" or die "cannot map $_[0]"; while (<TASK>) { print; #chomp; #chop; #push (@net_use_output, $_); #return $_; } #print join(", ", @net_use_output); #return @net_use_output; }
      above code always produces error:
      cannot map \\BLAH\NESTED\OBFUSCATED.WITH SPECIAL_CHARS\SHARE\NAME\DOWN +\DEEP at ..\ examples\blah.pl line 12, <TASK> line 1. net use * "\\BLAH\NESTED\OBFUSCATED.WITH SPECIAL_CHARS\SHARE\NAME\DOWN +\DEEP"
      Even though copying and pasting the same command on the cmd shell works perfectly?

      - 3dbc

        Try adding pipe to open

            open TASK, '-|',"net use \* \"$_[0]\"" or die "cannot map $_[0]";

        or alternatively

        #!perl use strict; use warnings; use IPC::System::Simple qw/capture/; my $destination = "\\\\BLAH\\NESTED\\OBFUSCATED\.WITH SPECIAL_CHARS\\S +HARE\\NAME\\DOWN\\DEEP"; print netUse($destination); sub netUse { my $path = shift; my $cmd = "net use * $path"; my ($msg) = grep /Drive/, capture($cmd); return ($msg =~ /Drive (.*) is now connected/); }
        poj
Re: perl robocopy to temp mapped drive.
by Veltro (Hermit) on Oct 05, 2018 at 13:26 UTC

    Are you sure Robocopy does not work with the full unc path? I mean, just doing some googling here and I find topics that are related to your error on multiple forums and suggestions on how to overcome this.

    Examples of what I find: Using the flags /COPY:DT /DCOPY:T here or not using the /COPYALL flag here or using /FFT flag here. So maybe you can also show us the Robocopy command line instructions that you tried to use?

    If all not works, regards to mapping a drive you may also be interested in Win32::FileOp which seems to have a nice Map instruction.

    Hope it helps, Veltro

      I have some modules, not sure if I've got win32::FileOp, I'll check next.
      d:\>net use \\BLAH\NESTED\OBFUSCATED.WITH SPECIAL_CHARS\SHARE\NAME\DOW +N\DEEP Local name Remote name \\BLAH\NESTED\OBFUSCATED.WITH SPECIAL_CHARS\SHARE\NA +ME\DOWN\DEEP Resource type Disk Status Disconnected # Opens 0 # Connections 4 The command completed successfully. d:\>ROBOCOPY "C:\Users\test\AppData\Local\Temp" "\\BLAH\NESTED\OBFUSCA +TED.WITH SPECIAL_CHARS\SHARE\NAME\DOWN\DEEP" crap.csv /B ---------------------------------------------------------------------- +--------- ROBOCOPY :: Robust File Copy for Windows ---------------------------------------------------------------------- +--------- Started : Thu Oct 11 11:51:58 2018 2018/10/11 11:51:58 ERROR 5 (0x00000005) Getting File System Type of D +estination \\BLAH\NESTED\OBFUSCATED.WITH SPECIAL_CHARS\SHARE\NAME\DOWN\DEEP\ Access is denied. Source : C:\Users\test\AppData\Local\Temp\ Dest - \\BLAH\NESTED\OBFUSCATED.WITH SPECIAL_CHARS\SHARE\NAME\DOW +N\DEEP\ Files : crap.csv Options : /COPY:DAT /B /R:1000000 /W:30 ---------------------------------------------------------------------- +-------- 1 C:\Users\test\AppData\Local\Temp \ 100% Newer 2.2 m crap.csv ---------------------------------------------------------------------- +-------- Total Copied Skipped Mismatch FAILED Extras Dirs : 1 0 1 0 0 0 Files : 1 1 0 0 0 0 Bytes : 2.23 m 2.23 m 0 0 0 0 Times : 0:00:01 0:00:01 0:00:00 0:00:00 Speed : 1469544 Bytes/sec. Speed : 84.088 MegaBytes/min. Ended : Thu Oct 11 11:52:00 2018
      Thanks,
      - 3dbc
        Just had an error with robocopy using the /B flag and had to change it to the /z flag because of these errors when trying to copy to the mapped unc path (with drive letter).
        net use * "\\BLAH\NESTED\OBFUSCATED.WITH SPECIAL_CHARS\SHARE\NAME\DOWN +\DEEP" ----- Drive Z: is now connected to \\BLAH\NESTED\OBFUSCATED.WITH SPECIAL_CHA +RS\SHARE\NAME\DOWN\DEEP. ROBOCOPY "C:\Users\SERVICE_ACCOUNT~1\AppData\Local\Temp" Z:\ Crap.csv +/B ---------------------------------------------------------------------- +--------- ROBOCOPY :: Robust File Copy for Windows + ---------------------------------------------------------------------- +--------- Started : Fri Oct 12 11:12:23 2018 Source : C:\Users\SERVICE_ACCOUNT~1\AppData\Local\Temp\ Dest : Z:\ Files : Crap.csv Options : /COPY:DAT /B /R:1000000 /W:30 ---------------------------------------------------------------------- +-------- ERROR : You do not have the Backup and Restore Files user rights. ***** You need these to perform Backup copies (/B or /ZB). ERROR : Robocopy ran out of memory, exiting. ERROR : Invalid Parameter #%d : "%s" ERROR : Invalid Job File, Line #%d :"%s" Started : %hs Source %c Dest %c Simple Usage :: ROBOCOPY source destination /MIR source :: Source Directory (drive:\path or \\server\share +\path). destination :: Destination Dir (drive:\path or \\server\share +\path). /MIR :: Mirror a complete directory tree. For more usage information run ROBOCOPY /? **** /MIR can DELETE files as well as copy them ! net use Z:\ /delete Z: was deleted successfully.
        - 3dbc