Avoid 'access is denied' when using Powershell Remoting to Copy to a Shared Network Folder (i.e. Defeating Kerberos)
Scenario You are using remoting, and have assigned credentials to the remoting session...
Within the remote session block you are trying to talk a network fileshare, but failing with Access Denied. (UnauthorizedAccessException
)
For example:
$Credentials = Get-Credential -Message "Provide the credentials for remote access" # prompts for credentials
$TargetServer = "YourServer"
$PSSessionOption = New-PSSessionOption -ProxyAccessType NoProxyServer
$RemoteSession = New-PSSession -ComputerName $TargetServer -Credential $Credentials -SessionOption $PSSessionOption
$TargetFolder = "\\OtherServer\ShareName\Pathy\Path"
write-host "THIS WON'T WORK..." -f red
Invoke-Command -Session $RemoteSession {
# This works: we can view local folders on machine
dir;
# This doesn't work: we cannot authenticate to view restricted network shares
dir $using:TargetFolder
}
But it errors with "Access is Denied"
You can't believe it, because when you remote onto the same machine with Remote Desktop Connection Manager (etc) and run the same command in powershell, with the exact same user -- you do have permission!
What's going on?
It kerberos of course! It's always kerberos!
Those credentials are being quietly refused to be passed along to the second machine -- so it just don't matter.
Instead -- do this...
$Credentials = Get-Credential -Message "Provide the credentials for remote access" # prompts for credentials
$TargetServer = "YourServer"
$PSSessionOption = New-PSSessionOption -ProxyAccessType NoProxyServer
$RemoteSession = New-PSSession -ComputerName $TargetServer -Credential $Credentials -SessionOption $PSSessionOption
$TargetFolder = "\\OtherServer\ShareName\Pathy\Path"
write-host "HOW ABOUT THESE APPLES..." -f green
Invoke-Command -Session $RemoteSession {
# This still works: we can view local folders on machine
dir;
# NOW, we create a new PS-Drive to the share. (You can give it a nice name, not just one letter).
# And provide the credential to it!
new-psdrive -name "MyNewDrive" -root $using:TargetFolder -PSProvider "FileSystem" -Credential $using:Credentials | out-null
dir "MyNewDrive:\"
remove-psdrive "MyNewDrive"
# ^^ Remember to remove it... (though it will dissappear anyway if it doesn't have a "-persist" flag)
}
...i.e. create a new drive, and pass the credentials in when creating that drive... and then use that new drive name, instead of the UNC path of the share.
Historical Note
We were actually trying to copy a file, not just view a directory.
And here's something we tried along the way that failed -- but gave an error message with a hint that taught us the ps drive trick!!
Invoke-Command -Session $remoteSession {
copy $using:SourceFile $using:TargetFolder -credential $using:Credentials
}
...the error message said
The FileSystem provider supports credentials only on the New-PSDrive cmdlet. Perform the operation again without specifying credentials.
+ CategoryInfo : NotImplemented: (:) [], PSNotSupportedException
+ FullyQualifiedErrorId : NotSupported
+ PSComputerName : YourServer.YourDomain.com
What a sneaky message!
The command we're using (copy... really it's copy-item) has a credential
parameter. But with the underlying provider (FileSystem
) -- it throws this message.
It's really giving you a clue about how to achieve the workaround. So even though they say
Perform the operation again without specifying credentials
...what they've helped us to "think" is:
Use
New-PsDrive
with your credential to make a new, temporary, PsDrive, and then use that PsDrive to achieve your File Operation!
Credits
Big thanks to Paul Gaske for developing this as we paired on it. He has a lot of very neat powershell bits n pieces.