I have two computers: A and B. I'm trying to automate some CI\CD tasks, and my task is to start some process on B remotely, from A. The .exe file itself is on the R
drive, which is a local network drive. So I do this:
# here $cred has encrypted credentials, but it is off topic...
Invoke-Command -ComputerName B -Credential $cred -ScriptBlock {
R:\WebClient\Platform\UP_110\Proc.exe
}
So apparently this would be the same thing as typing R:\WebClient\Platform\UP_110\Proc.exe
on B's PowerShell and hitting Enter.
Now the problem is that I get this error when running the above code on A:
The term 'R:\WebClient\Platform\UP_110\Proc.exe' is not recognized as the name of a cmdlet, function, sc
ript file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is corr
ect and try again.
CategoryInfo : ObjectNotFound: (R:\WebClient\Pl...IMS.UP.Host.exe:String) [], CommandNotFoundException
FullyQualifiedErrorId : CommandNotFoundException
PSComputerName : B
Apparently it says that there is no such file as R:\WebClient\Platform\UP_110\Proc.exe
on my B computer. But that is not true. I do have it:
As a matter of a fact, I have this R drive both on A and B.
The code works fine if I move the .exe to any directory under the C
drive (which is the system disk for me), but not for R
.
Now even funnier is that I can run R:\WebClient\Platform\UP_110\Proc.exe
on A and B manually. And it works.
So what's the issue here I'm facing? Thanks.
CodePudding user response:
PowerShell Remoting can only access drives by default that are mapped within the system context. Most commonly, this will be letter drives based on attached hardware (whether this be USB, SATA, SCSI, etc.).
Drives mapped in the user context, such as remote drives, are not mapped because a full logon does not occur the same way as if you log in locally. There are two workarounds you have at your disposal:
Use the UNC path when accessing files over an SMB/CIFS share (e.g.
\\server.domain.tld\ShareName\Path\To\Folder\Or\file.ext
Map the drive within the
ScriptBlock
passed toInvoke-Command
usingNew-PSDrive
:# Single letter drive name New-PSDrive -Name "R" -PSProvider FileSystem -Root "\\server.domain.tld\ShareName" Get-ChildItem R: # More descriptive drive name New-PSDrive -Name "RemoteDrive" -PSProvider FileSystem -Root "\\server.domain.tld\ShareName" Get-ChildItem RemoteDrive:
Three things to note:
Get-ChildItem
in the example above is to show that listing the contents of the new drives should show the files you expect to see at the remote directory. This can be omitted once you are sure it works for you.Additionally, using a longer drive name is a PowerShell feature and does not mean that you can map shared folders as a drive from within File Explorer with more than a single character.
You may run into the double hop issue trying to map to a remote drive this way, if you are attempting to use the same credential you initiated
Invoke-Command
with. Solving it properly is beyond the scope of Stack Overflow as this is a major architectural consideration for Active Directory.However, you can work around it by building the credential object and passing it to
New-PSDrive
from within theScriptBlock
, or runningInvoke-Command
with-Authentication CredSSP
if your organization does not block it (many do).