使用Invoke-Command无法复制共享网络文件夹的技术求助
解决Invoke-Command远程执行时无法访问共享文件夹的问题
在使用PowerShell的Invoke-Command远程执行脚本时,遇到无法从共享文件夹\\Server01\Zabbix复制文件到目标服务器Server02的问题,报错权限拒绝和路径不存在,但同一账号直接在Server02上执行脚本则正常。
问题原因
这是PowerShell远程的**双跳(Double Hop)**限制导致:当你从本地机器远程连接到Server02后,Server02无法自动将你的凭据传递到第三个资源(Server01的共享文件夹),因此无法访问共享。
解决方案
方案1:启用CredSSP认证(解决双跳问题)
CredSSP允许将凭据从本地机器传递到远程服务器,进而访问第三方资源,但注意此方式会传递明文凭据,存在安全风险,使用后建议禁用。
- 在本地发起机器上启用CredSSP客户端:
Enable-WSManCredSSP -Role Client -DelegateComputer "Server02" - 在目标服务器
Server02上启用CredSSP服务端:Enable-WSManCredSSP -Role Server - 修改远程执行脚本,添加
-Authentication Credssp和-Credential参数:$servers = @('Server02') $cred = Get-Credential # 输入有权限访问共享和远程服务器的账号 foreach ($server in $servers) { Invoke-Command -ComputerName $server -Authentication Credssp -Credential $cred -ScriptBlock { $Installer = '\\Server01\Zabbix' Write-Host -f green "[INFO]: Attempting to copy the folder located on $installer." try{ Copy-Item -Path $installer -Destination c:\ -Recurse -Force Write-Host -f green "[INFO]: $installer is successfully copied to C:\Zabbix on $env:computername." } catch { Write-Host -f red "[ERROR]: Copying $installer encountered an error on $env:computername : $($_.Exception.Message)" } } } - 使用完成后禁用CredSSP:
# 本地客户端禁用 Disable-WSManCredSSP -Role Client # 远程服务端禁用 Disable-WSManCredSSP -Role Server
方案2:先复制到本地,再传到远程服务器
绕开双跳问题,先将共享文件复制到本地临时目录,再通过PowerShell会话传到远程服务器:
$servers = @('Server02') $localTempDir = "C:\Temp\ZabbixInstaller" $sharePath = '\\Server01\Zabbix' # 先将共享文件复制到本地 Copy-Item -Path $sharePath -Destination $localTempDir -Recurse -Force foreach ($server in $servers) { # 建立远程会话 $session = New-PSSession -ComputerName $server # 从本地传到远程C盘 Copy-Item -Path $localTempDir -Destination "C:\" -Recurse -Force -ToSession $session Invoke-Command -Session $session -ScriptBlock { Write-Host -f green "[INFO]: Zabbix installer copied to C:\Zabbix on $env:computername." # 这里添加卸载旧版本、安装新版本的逻辑 } # 清理会话和本地临时文件 Remove-PSSession $session Remove-Item -Path $localTempDir -Recurse -Force }
方案3:在远程服务器映射共享时指定凭据
如果Server01上有独立的共享账号,可以在远程脚本中手动映射共享并指定凭据:
$servers = @('Server02') # 输入Server01共享文件夹的授权账号 $shareCredential = Get-Credential foreach ($server in $servers) { Invoke-Command -ComputerName $server -ScriptBlock { param($targetShare, $shareCred) Write-Host -f green "[INFO]: Attempting to copy from $targetShare." try{ # 临时映射共享驱动器 New-PSDrive -Name Z -PSProvider FileSystem -Root $targetShare -Credential $shareCred Copy-Item -Path "Z:\" -Destination "C:\" -Recurse -Force Remove-PSDrive -Name Z Write-Host -f green "[INFO]: $targetShare copied to C:\Zabbix on $env:computername." } catch { Write-Host -f red "[ERROR]: Copy error on $env:computername : $($_.Exception.Message)" # 异常时清理映射的驱动器 if (Get-PSDrive -Name Z -ErrorAction SilentlyContinue) { Remove-PSDrive -Name Z } } } -ArgumentList $sharePath, $shareCredential }
内容的提问来源于stack exchange,提问作者bujom
相关产品推荐
相关产品推荐

