【问题标题】:Powershell copy across network pc path跨网络 pc 路径的 Powershell 复制
【发布时间】:2020-05-02 18:42:16
【问题描述】:

我有一些 powershell 代码来尝试跨网络设备复制图像文件。但是,如果目标存在部分,脚本总是失败。运行脚本的用户拥有文件路径的完全权限。

但是 Powershell 每次都找不到目标文件夹。这是脚本:

$Servers = (@"
    PCLIST01
    PCLIST02
    PCNAME03
    PCLIST04
    "@ -split "`r`n").Trim() 

$Source = '\\SERVER\Folder name\subfolder\100 Project Name\moneydreams.jpg'
$Destination = 'C:\ProgramData\Program Folder Name\Subfolder for Program\HTML\' -replace "C:","c$"

$Logfile = "\\SERVER\Folder name\subfolder\100 Project Name\Failed.log"
If (!(Test-Path $Logfile)) { Remove-Item $Logfile}
New-Item $Logfile -ItemType File 

ForEach ($Server in $Servers) { 
  Try {
    If (!(Test-Path "$Server\$Destination" )) {  
      ROBOCOPY "$Source" "\\$Server\$Destination" /LOG:copylog.log 
    } 
    Else { 
      Add-Content $Logfile "Folder does not exist on $Server , \\$Server\$Destination" 
    } 
  } Catch {
    Add-Content $Logfile "$Server - $($_.Exception.Message)"
    }
} 

代码在 If (!(Test-Path "$Server\$Destination" )) 处失败。 奇怪的是,如果我在 $logfile 上执行测试路径,它也会失败,但是文件会使用 Add-Content 表示法更新! 需要注意的是,我确实尝试在文件路径中使用反引号 ` 来查看是否存在空格问题,但并没有解决问题。

我不明白为什么它无法找到目标文件夹并更新!

【问题讨论】:

  • 你为什么否定目标文件夹的检查?
  • ... 并且您也否定了对日志文件的检查,但是如果它不存在则尝试将其删除。
  • 您在Test-Path 调用中查看过您正在测试的内容吗?我看不到您在哪里添加所需的 unc 前缀。所以你似乎最终得到PCLIST01\c$\... 而不是\\PCLIST01\c$\...
  • 这可能是我的第一个 powershell 文件,所以我想尽我所能。我在下面使用了 Theo 的信息并稍作更改,现在可以正常工作了。

标签: powershell copy


【解决方案1】:

OlafLee 都是正确的。您正在以完全相反的方式使用Test-Path,将返回的布尔值与! 取反,并且您构造了错误的最终目标路径。

最后,由于您没有添加 -ErrorAction Stop,因此可能发生的错误可能不会出现在您的 catch 块中。

试试:

$Servers     = 'PCLIST01','PCLIST02','PCNAME03','PCLIST04'
$Source      = '\\SERVER\Folder name\subfolder\100 Project Name\moneydreams.jpg'
# $Destination is a template path. The server name is inserted inside the foreach loop later
$Destination = '\\{0}\c$\ProgramData\Program Folder Name\Subfolder for Program\HTML'
$Logfile     = '\\SERVER\Folder name\subfolder\100 Project Name\Failed.log'
$copyLog     = '\\SERVER\Folder name\subfolder\100 Project Name\Copylog.log'

# if the log file already exists, remove it
If (Test-Path -Path $Logfile -PathType Leaf) { Remove-Item -Path $Logfile -Force}

foreach ($Server in $Servers) { 
    # test if the server is not off-line
    # in this case i DO want to negate the result.
    if (!(Test-Connection -ComputerName $Server -Count 1 -Quiet)) {
        Add-Content -Path $Logfile -Value "Server $Server is unreachable"
        # skip this server and move on to the next one
        continue
    }
    # insert the server name to the destination
    $targetPath = $Destination -f $Server
    # $targetPath will be '\\servername\c$\ProgramData\Program Folder Name\Subfolder for Program\HTML'
    Try {
        # see if you can reach the targetpath on this server
        # -ErrorAction Stop ensures the catch block is entered on errors
        if (Test-Path -Path $targetPath -PathType Container -ErrorAction Stop) {  
            ROBOCOPY $Source $targetPath /LOG:$copyLog 
        } 
       else { 
            Add-Content -Path $Logfile -Value "Folder does not exist on $Server , $targetPath" 
        } 
    } 
    catch {
        Add-Content -Path $Logfile -Value "$Server - $($_.Exception.Message)"
    }
} 

希望对你有帮助

如您所见,我也在为各种 cmdlet 上的参数命名,以使代码更易于理解,同时也不要盲目依赖参数的位置,这样很容易出错。

【讨论】:

  • 谢谢@Theo,这对我很有效。我不得不用 Copy-Item 替换 ROBOCOPY,因为它在解析源文件名方面效果更好。我的下一个改进来源是从文本文件中读取 $Servers 列表,然后就完成了。
  • @Altie 我很高兴听到它对你有用。如果您觉得我的回答解决了您的问题,请考虑通过单击左侧的 ✓ 图标来接受答案。这将帮助其他有类似问题的人更轻松地找到它
  • P.S.我添加了:$ListofPC = '\\place\file.txt' 然后我只是将 $servers 更改为 $Servers = Get-Content $ListofPC
猜你喜欢
  • 2020-10-01
  • 2012-02-09
  • 1970-01-01
  • 2021-06-01
  • 2020-12-08
  • 1970-01-01
  • 2011-12-30
  • 2013-12-22
  • 1970-01-01
相关资源
最近更新 更多