/* ]]> */
Mar 082011
 

I was amazed to learn that the Copy-Item cmdlet in PowerShell 2.0 has no built-in support to access a remote file system where alternate credentials are required. A “-Credential” parameter exists, but apparently only as a stub for future use as the cmdlet help clearly states that “This parameter is not supported by any providers installed with Windows PowerShell.”

Also, there is no native drive-mapping cmdlet (that I could find anyway).

So, you could use the trusty old “NET USE” command and I’ll bet there is actually a .NET class to support this, but I have opted here to borrow from my VbScript archives and use the wscript.network COM object.

Basically, there are two steps needed to map a drive:

?View Code POWERSHELL
$net = new-object -ComObject Wscript.Network
$net.MapNetworkDrive("x:","\\servername\sharename",$false,"username","userpassword")

To clean-up afterward, I like to remove the mapped drive

?View Code POWERSHELL
$net.RemoveNetworkDrive("x:")

This is all fine and good but it needs to be in a script and I need to safely pass credentials without keying them in every time I use it. To this end, I will employ the Import-PSCredential function (accessed using the alias “icred”) to pass user credentials to the MapNetworkDrive method. Also, I will omit the drive letter “x:” which will enable me to do the File Copy operation using a UNC path.

The following script contains a static list of UNC destinations where I want to distribute a particular file. This same list can also contain a file reference to an encrypted credentials file (created with Export-PSCredential) which can be used to access a remote file system.

?View Code POWERSHELL
$Destinations=(
    "c:\dev\svn\powershell         |",
    "\\pt001\c$\scripts\powershell |xbcred_pt001.enc.xml",
    "\\pt002\c$\scripts\powershell |xbcred_pt002.enc.xml",
    "\\pt003\c$\scripts\powershell |xbcred_pt003.enc.xml"
    )

A vertical bar “|” character is used to separate UNCs from credentials. If credentials are omitted, then the mapping operation will be skipped. Where mapping is needed, the first two elements in the UNC path are used; for example, the second item in the list will result in  “\\pt001\c$” being mapped using credentials found in the file “xbcred_pt001.enc.xml“.  Note that any valid share name on the remote host will work; I have specified the administrative “c$” shares in this example, but any user-created share will work.
Again, be reminded that this scripts has the following prerequisites:

  • Credentials files must be created using Export-PSCredential function
  • Import-PSCredential function must be already loaded into memory with an alias “icred” created (alternatively, you could modify this script to include the Import-PSCredential function)
  • See my post on credentials here: http://poshtips.com/2011/03/04/import-and-export-user-credentials-in-powershell/
  • The $Destinations array (at beginning of this script)  must be modified to suit your file-copy needs. Be sure to include a vertical-bar character in each line (even if you do not specify user credentials).

Hopefully that’s enough information to make sense of the following script.

 

?View Code POWERSHELL
param($File,[switch]$Help)
$Destinations=(
    "c:\dev\svn\powershell         |",
    "\\pt001\c$\scripts\powershell |xbcred_pt001.enc.xml",
    "\\pt002\c$\scripts\powershell |xbcred_pt002.enc.xml",
    "\\pt003\c$\scripts\powershell |xbcred_pt003.enc.xml"
    )
 
$HelpText = @'
#######################################################################################
 Name    : CopyFile.ps1
 Date    : 03/08/2011
 Author  : xb90@poshtips.com
 Purpose : Copy a file to multiple locations; temporarily map remote drives using
           alternate user credentials
 Usage
           ./CopyFile -File  [-Help]
           where
                   specifies a valid file [path]Filename to be distributed
                  -Help      produces this help output
 
 Notes
           * Update the $Destinations array in this script to modify file distributions
             and/or credentials file specifications.
           * Use Export-Credential function to create a new credential file
           * This script utilizes the Import-Credential function via alias "icred"
             which should be loaded into memory via a powershell profile script
 
#######################################################################################
'@
 
if ($help -or !$File){
    $HelpText
    "Defined Destinations:"
    write-host "    " -nonewline
    write-host "$("Path".padright(40))" -fore yellow -back DarkGreen -nonewline
    write-host " " -nonewline
    write-host "$("Credentials".padright(40))"  -fore yellow -back DarkGreen
    foreach ($x in $destinations){
        $p=$($x.split("|")[0].trim())
        $c=$($x.split("|")[1].trim())
        write-host "    $($p.padright(40)) " -fore green  -nonewline
        if ($c) {
            write-host "$c" -fore green -back black
            }
        else{
            write-host "(default credentials)" -fore green -back black
            }
        }
    write-host "`n"
    exit
    }
 
if ($File){
    if (!(test-path $File)){
        write-host "ERROR: `"$File`" is not a valid file" -back yellow -fore red
        }
    else{
        $net = new-object -ComObject Wscript.Network
        write-host "Copying File: $File to..." -fore white
        foreach ($d in $Destinations){
            $dPath = $d.split("|")[0]
            $dCred = $d.split("|")[1]
            write-host "       ==> $dPath" -fore yellow
            if ($dCred){
                $dMap = "\\$($dPath.split("\")[2])\$($dPath.split("\")[3])"
                $cred = icred $dCred
                $net.MapNetworkDrive("",$dMap,$false,$($cred.UserName),$($cred.GetNetworkCredential().password))
                }
            copy-item $File -Destination $dPath
            if ($dCred){
                $net.RemoveNetworkDrive($dMap)
                }
            }
        }
    }

 Posted by at 1:09 pm

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Page optimized by WP Minify WordPress Plugin