44

I'm using the CTP of powershell v2. I have a script written that needs to go out to various network shares in our dmz and copy some files. However, the issue I have is that evidently powershell's cmdlets such as copy-item, test-path, etc do not support alternate credentials...

Anyone have a suggestion on how best to accomplish my task..?

xspydr
  • 3,030
  • 3
  • 31
  • 49
  • Here is a similar question. http://stackoverflow.com/questions/10313/can-i-copy-files-to-a-network-place-from-a-script-or-the-command-line – notandy Mar 04 '09 at 19:19

13 Answers13

49

I have encountered this recently, and in the most recent versions of Powershell there is a new BitsTransfer Module, which allows file transfers using BITS, and supports the use of the -Credential parameter.

The following sample shows how to use the BitsTransfer module to copy a file from a network share to a local machine, using a specified PSCredential object.

Import-Module bitstransfer
$cred = Get-Credential
$sourcePath = \\server\example\file.txt
$destPath = C:\Local\Destination\
Start-BitsTransfer -Source $sourcePath -Destination $destPath -Credential $cred

Another way to handle this is using the standard "net use" command. This command, however, does not support a "securestring" password, so after obtaining the credential object, you have to get a decrypted version of the password to pass to the "net use" command.

$cred = Get-Credential
$networkCred = $cred.GetNetworkCredential()
net use \\server\example\ $networkCred.Password /USER:$networkCred.UserName
Copy-Item \\server\example\file.txt C:\Local\Destination\
CB.
  • 58,865
  • 9
  • 159
  • 159
chills42
  • 14,201
  • 3
  • 42
  • 77
  • Just chiming in, but I tried the BITS piece, and it worked like a charm. – Marcus May 04 '12 at 17:33
  • Do I need to do `Complete-BitsTransfer` to wait for it to finish, or is it synchronous by default? – jpmc26 Mar 20 '15 at 09:43
  • 5
    Also, note that this doesn't work with locations like `\\server\C$`. See http://serverfault.com/q/512558/172060. – jpmc26 Mar 20 '15 at 10:12
  • 3
    I do not think the BITS transfer works as you suggest. I am using powershell 2 and I still need to create a mapping with "net use" before using the BITS, otherwise it (quite obviously) says that the unc path does not exist. So in my script I do: net use to add path...bits...net use /delete – Santhos Aug 29 '15 at 08:29
36

Since PowerShell doesn't support "-Credential" usage via many of the cmdlets (very annoying), and mapping a network drive via WMI proved to be very unreliable in PS, I found pre-caching the user credentials via a net use command to work quite well:

# cache credentials for our network path
net use \\server\C$ $password /USER:$username

Any operation that uses \\server\C$ in the path seems to work using the *-item cmdlets.

You can also delete the share when you're done:

net use \\server\C$ /delete
wes
  • 889
  • 9
  • 12
26

PowerShell 3.0 now supports for credentials on the FileSystem provider. To use alternate credentials, simply use the Credential parameter on the New-PSDrive cmdlet

PS > New-PSDrive -Name J -PSProvider FileSystem -Root \\server001\sharename -Credential mydomain\travisj -Persist

After this command you can now access the newly created drive and do other operations including copy or move files like normal drive. here is the full solution:

$Source = "C:\Downloads\myfile.txt"
$Dest   = "\\10.149.12.162\c$\skumar"
$Username = "administrator"
$Password = ConvertTo-SecureString "Complex_Passw0rd" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential($Username, $Password)

New-PSDrive -Name J -PSProvider FileSystem -Root $Dest -Credential $mycreds -Persist
Copy-Item -Path $Source -Destination "J:\myfile.txt"
Santosh Panda
  • 7,235
  • 8
  • 43
  • 56
8

This is an old question but I'm just updating it for future finders.

PowerShell v3 now supports using the -Credential parameter for filesystem operations.

Hope this helps others searching for the same solution.

x0n
  • 51,312
  • 7
  • 89
  • 111
  • 11
    It's seem that `-credential` parameter is supported only for New-PsDrive for file system provider. With `copy-item` on v3 stil doesn't work. – CB. Nov 09 '12 at 13:52
  • Right, that's because copy-item works against PSDrives. You have to remount the drive under different credentials, or create a new PSDrive to the same remote resource but this can fail sometimes due to underlying O/S constraints (namely, using differing network credentials for the same remote resource in the same session.) – x0n Nov 09 '12 at 15:00
6

I would try to map a drive to the remote system (using 'net use' or WshNetwork.MapNetworkDrive, both methods support credentials) and then use copy-item.

Shay Levy
  • 121,444
  • 32
  • 184
  • 206
  • This is the best answer because the filesystem provider (and thus copy-item) does not support credentials. – halr9000 Jun 10 '09 at 13:35
2

I know that PowerShell 3 supports this out of the box now, but for the record, if you're stuck on PowerShell 2, you basically have to either use the legacy net use command (as suggested by several others), or the Impersonation module that I wrote awhile back specifically to address this.

Jaykul
  • 15,370
  • 8
  • 61
  • 70
2

Here's my script that runs as LocalSystem on a machine, but needs credentials of a domaim user to access a network file location. It allows you to store the user's password in a "safe-ish" encrypted file; that can only be read by the user that wrote it.

Setting and changing the password is done by copying a file with the plaintext password in it to the machine. When the script is next run it reads the password, encrypts it, then deletes the plaintext password.

$plaintext_password_file = 'C:\plaintext.txt' # Stores the password in plain text - only used once, then deleted
$encryted_password_file = 'C:\copy_pass.txt'  # Stores the password in "safe" encrypted form - used for subsequent runs of the script
                                              #   - can only be decrypted by the windows user that wrote it
$file_copy_user = 'OURDOMAIN\A_User'

# Check to see if there is a new plaintext password
if (Test-Path $plaintext_password_file)
{
    # Read in plaintext password, convert to a secure-string, convert to an encrypted-string, and write out, for use later
    get-content $plaintext_password_file | convertto-securestring -asplaintext -force | convertfrom-securestring | out-file $encryted_password_file
    # Now we have encrypted password, remove plain text for safety
    Remove-Item $plaintext_password_file
}


# Read in the encrypted password, convert to a secure-string
$pass = get-content $encryted_password_file | convertto-securestring

# create a credential object for the other user, using username and password stored in secure-string
$credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $file_copy_user,$pass

# Connect to network file location as the other user and map to drive J:
New-PSDrive -Name J -PSProvider FileSystem -Root "\\network\file_directory" -Credential $credentials

# Copy the file to J:
Copy-Item -Force -Verbose -Path "C:\a_file.txt" -Destination "J:\"

As an extra refinement: The username could also be encrypted as well, rather than hardcoded.

Jason A
  • 46
  • 8
2

The newer verion of PowerShell handles this and the MS Documentation has a great example of copying a file with different credentials here

$Session = New-PSSession -ComputerName "Server02" -Credential "Contoso\User01"
Copy-Item "D:\Folder002\" -Destination "C:\Folder002_Copy\" -ToSession $Session
Paul42
  • 194
  • 1
  • 11
0

Bringing this back from the dead again. I got around a similar credentials problem by wrapping the .ps1 in a batch file and doing the Win7, Shift + r.Click RunAs. If you wanted to, you can also use PsExec thus:

psexec.exe /accepteula /h /u user /p pwd cmd /c "echo. | powershell.exe -File script.ps1"
Phlebass
  • 91
  • 2
  • 10
0

Here is a post where someone got it to work. It looks like it requires a registry change.

notandy
  • 3,330
  • 1
  • 27
  • 35
  • 1
    That guy is double hopping within the same domain. I need to be able to specify an account as I am accessing files on a different domain altogether... – xspydr Mar 04 '09 at 19:46
0

This question addresses a very related issue that may help using network shares in powershell.

Community
  • 1
  • 1
Eddie Groves
  • 33,851
  • 14
  • 47
  • 48
-1

that evidently powershell's cmdlets such as copy-item, test-path, etc do not support alternate credentials...

It looks like they do here, copy-item certainly includes a -Credential parameter.

PS C:\> gcm -syn copy-item
Copy-Item [-Path] <String[]> [[-Destination] <String>] [-Container] [-Force] [-Filter <String>] [-I
nclude <String[]>] [-Exclude <String[]>] [-Recurse] [-PassThru] [-Credential <PSCredential>] [...]
Richard
  • 106,783
  • 21
  • 203
  • 265
  • I keep receiving a error message stating -credential is not supported – xspydr Mar 04 '09 at 19:27
  • 3
    TechNet (http://technet.microsoft.com/en-us/library/dd315340.aspx) says "This parameter is not supported by any providers installed with Windows PowerShell." So they're too lazy to implement it and just expect anyone creating a new provider to do it. :( – Darrell Mozingo Feb 19 '10 at 14:12
  • 1
    To ship is to choose ;) The good news is they finally chose to implement it in PS3 – Jaykul Sep 25 '12 at 16:53
-6

You should be able to pass whatever credentials you want to the -Credential parameter. So something like:

$cred = Get-Credential

[Enter the credentials]

Copy-Item -Path $from -Destination $to -Credential $cred

EBGreen
  • 36,735
  • 12
  • 65
  • 85