无法访问 Powershell 远程会话中的 UNC 路径
Posted
技术标签:
【中文标题】无法访问 Powershell 远程会话中的 UNC 路径【英文标题】:Unable to access UNC Paths in Powershell remote session 【发布时间】:2013-07-22 16:31:58 【问题描述】:我无法在本地计算机的 Powershell 远程会话中访问服务器上的 UNC 路径。我可以直接在 Servers Cmd 提示符下使用它们。
实际上,我已经登录到服务器并将 UNC 路径映射为本地驱动器(比如 X:)。使用登录时重新连接选项。
我有一个位于此 X: 驱动器中的批处理文件,我想使用本地脚本中的调用命令远程运行它。但是,它失败了。
它说“找不到驱动器。名称为 X 的驱动器不存在”。
此外,当我尝试在脚本块中使用 net use 命令映射驱动器时,它也会引发错误 - 系统错误 1223 - 本机命令错误。
我使用管理员凭据登录此服务器。
谁能帮我解决这个问题,我要做的就是远程运行驻留在这个 UNC 路径上的脚本?
另外,当我将服务器中的 UNC 路径映射为本地驱动器时,为什么我无法在 PS 远程会话中使用它?
提前致谢。 TS
【问题讨论】:
您是否尝试过在文件路径中的“x”之后放置$
,例如:"\\ServerName\X$\Folder\PowershellFile.ps1"
?
我试过了,但是没有用。
【参考方案1】:
这里确实发生了 3 种不同的事情。
1 & 3. 只有在您以交互方式登录时才会映射驱动器。因此,当您远程访问另一台计算机,映射驱动器,然后注销/断开连接时,该映射驱动器已断开连接。除了在交互式 GUI 用户会话中,您不能依赖不是您自己创建的映射驱动器号。在脚本或任何远程会话中,只需对所有内容使用 UNC 路径 - 它更可靠。
2 。当您尝试在远程 PS 会话中映射驱动器时,您会遇到所谓的“双跳”问题。有一个解决方案,但是您必须做一些额外的设置。见Double hop access to copy files without CredSSP
【讨论】:
您提供的信息非常有用。我刚刚想出了另一种方法 - 只需将凭据传递到您在 Scriot 块中使用的 UNC 路径,作为 net use 命令的一部分 - 请参阅 Net Use 命令的语法。这解决了我的问题。一开始我使用 Get-Credential cmd-let 从用户那里获取 AD 凭据,它适用于所有服务器。将用户名和密码传递给 net use cmd - 我使用了 GetNetworkCredential().Username 和 GetNetworkCredential().Password 并且它有效 - 此密码是纯文本的。你甚至可以在输出控制台上打印它。 PS 并不安全,因为即使您使用 Get-Credential cmd-let,您也可以获得纯文本形式的密码。因此,我无法实现我的脚本。密码以纯文本形式提供,在公司中不安全。【参考方案2】:您可以尝试通过调用 WmiMethod 来打开脚本:
$cmd = "CMD.EXE /c *\\\servername\somefolder\yourscript*.cmd"
Invoke-WmiMethod -class Win32_process -name Create -ArgumentList $cmd -ComputerName *servername*
请注意,这将在服务器上运行脚本。你可以用它做更多的事情,比如远程安装一个包(在远程机器上本地复制包之后)。
希望对您有所帮助!
【讨论】:
这种方法并没有解决我的问题。我相信双跳问题仍然存在。直接从 WMI 像这样使用它:“powershell -ExecutionPolicy Bypass -file “\\server\path\file.ps1。”Powershell 抱怨它找不到文件。还尝试将其作为 .bat 脚本中的嵌入式命令远程服务器。直接从服务器(ps1 或 bat -> ps1)运行时,它可以工作。powershell 看到的用户名在所有情况下都是相同的。【参考方案3】:alroc's helpful answer 很好地解释了问题并指出了通过先前配置解决问题的资源。
可以找到对底层问题(臭名昭著的 Kerberos双跳问题的解释,以及可用解决方案概述在this blog post。关于在远程会话 (PSv3+) 中访问网络共享的临时解决方案:
通过变量传递会话的凭据;例如,-Credential $cred
然后在会话中使用这些凭据 - 例如,$using:cred
- 使用 New-PSDrive
建立映射网络位置的会话范围辅助驱动器。
映射驱动器后,即可访问目标位置 - 无论是通过驱动器名称还是直接通过 UNC 路径。
注意:这是 OP 他/她自己发现的方法的一种变体,并在对 alroc 答案的评论中进行了简要讨论,除了使用 New-PSDrive
而不是 net use
,这消除了对以纯文本形式检索密码。
以下示例代码演示了从远程会话内部的网络共享运行脚本:
# A sample script to run from a network share on a remote computer.
$script = '\\server-001\install\Install-Agent.ps1'
# A sample target computer.
$computer = 'ws-002'
# Obtain the credentials for the remote session and store them in a variable.
$cred = Get-Credential $env:USERNAME
Invoke-Command -ComputerName $computer -Credential $cred
# Map the target network share as a dummy PS drive using the passed-through
# credentials.
# You may - but needn't - use this drive; the mere fact of having established
# a drive with valid credentials makes the network location accessible in the
# session, even with direct use of UNC paths.
$null = New-PSDrive -Credential $using:cred -Name dummy -Root (Split-Path -Parent $using:script) -PSProvider FileSystem
# Invoke the script via its UNC path.
& $using:script
注意:
$null = ...
抑制 New-PSDrive
的输出(它输出一个描述新创建的驱动器的对象)。
由于New-PSDrive
创建的驱动器不是持久的(除非您传递-Persist
),因此无需再次显式删除虚拟驱动器,但您可以使用Remove-PSDrive
这样做。
& ...
中的包装语句可以在 child 范围内调用它们,这意味着在该块内创建的 PS 驱动器将在退出该块时自动超出范围。
【讨论】:
以上是关于无法访问 Powershell 远程会话中的 UNC 路径的主要内容,如果未能解决你的问题,请参考以下文章
在 powershell ssh 会话中访问 Windows 网络驱动器