【问题标题】:Powershell - Struggling to copy file from variable locationPowershell - 努力从变量位置复制文件
【发布时间】:2020-03-15 12:04:11
【问题描述】:

我一直在用我尝试了几种不同方法的 powershell 脚本敲我的脑袋,想知道是否有人可以提供帮助?

现在不确定我是否只是在做一些愚蠢的事情,在此先感谢

目标:

要将 vbs 文件从用户的 homedrives 复制到不同的位置,vbs 文件的位置会根据需要帐户管理员执行的用户而更改,因此这需要可变。它从一个文本文件中获取位置,该文​​本文件包括要到达的确切路径和已经创建的将文件复制到的目标。

我目前遇到的问题:

$location = Get-Content C:\Users\Administrator\Desktop\here\drive4.txt | Out-String
$dest = "C:\Users\Administrator\Desktop\here"
Get-ChildItem -Path $location | 
Copy-Item -Destination $dest -Recurse -Container -filter "peruser.vbs"
write-host $location

Read-Host -Prompt "Press Enter to continue or CTRL+C to quit"

问题

请参阅下面的内容,我已将写入主机显示为 powershell 试图到达的位置,作为旁注,我可以通过文件资源管理器很好地到达该位置

Screenshot of error

收到错误

Get-ChildItem : Illegal characters in path.
At C:\Users\Administrator\Desktop\MapNetworkDrives2.ps1:17 char:1
+ Get-ChildItem -Path $location | Copy-Item -Destination $dest -Recurse -Container ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (\\WIN-7V7GI0R7C...             
:String) [Get-ChildItem], ArgumentException
    + FullyQualifiedErrorId : ItemExistsArgumentError,Microsoft.PowerShell.Commands.GetChildItemCommand

Get-ChildItem : Cannot find path '\\WIN-7V7GI0R7CFK\homedrives\Onetest$                                                     

' because it does not exist.
At C:\Users\Administrator\Desktop\MapNetworkDrives2.ps1:17 char:1
+ Get-ChildItem -Path $location | Copy-Item -Destination $dest -Recurse -Container ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (\\WIN-7V7GI0R7C...             
:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

【问题讨论】:

  • 你的变量得到了什么?命令后的 $location 和 $dest 有什么?写入 $location = Get-Content C:\Users\Administrator\Desktop\here\drive4.txt | Out-String 然后 $location 检查它是否是你想要的路径。另一个错误最后有个$,是系统目录吗?可能是导致错误的 $ 符号。
  • 您好,我的变量位置正确 -$Location 指向 \\WIN-7V7GI0R7CFK\homedrives\Onetest$,$dest 指向 C:\Users\Administrator\Desktop\here .我试图访问的目录是一个共享驱动器,我们所有用户的 homedrives 都有一个 $ 结束
  • 尝试使用-Force 开关Get-ChildItem

标签: powershell powershell-3.0


【解决方案1】:

除非我误解了你 - 你只是想根据一个列表将文件复制到不同的位置。如果是这样,您只需要遍历您的列表。这对你有用吗?

$location = Get-Content "C:\Users\Administrator\Desktop\here\drive4.txt"
$dest = "C:\Users\Administrator\Desktop\here"

foreach ($loc in $location){
    $vbs = (gci $loc -Filter "peruser.vbs").FullName
    Copy-Item $vbs $dest -Force
}

【讨论】:

  • 这到底是什么脚本?您可以只使用 Windows RoboCopy.exe 来完成这项工作。这就是它存在的原因。如果没有必要,不要编写脚本。您甚至可以在 PowerShell 脚本中使用 Robocopy。我不明白您为什么要这样做 --- Get-Content 'C:\Users\Administrator\Desktop\here\drive4.txt' | Out-String --- 它只是一个正在读取的文本文件,实际上没有理由在变量赋值中将它传送到屏幕。此外,您可以使用此动态获取驱动器列表... --- Get-PSDrive -PSProvider FileSystem 并根据需要进行管道/操作。
  • 只是试图修复提问者脚本。像大多数事情一样 - 您可以采取多种方法
  • 非常感谢!那是一种享受。我编写脚本的原因是因为我工作的组织有大量共享驱动器,其中一些具有相同的驱动器号,而我们的服务台人员中的一些人只是兼职工作并且没有那么多知识正在做帐户管理员(添加权限)他们正在添加用户已经分配的驱动器号,这导致了他们的问题。这样做意味着他们可以简单地输入用户名,它会给他们一个不分配的驱动器号列表,这对他们来说只是一个快速的短期解决方案
  • Itchydon --- 对帮助没有异议,因为我们都是自愿提供这些东西的。此外,100% 同意多重方法,因为我们都在我们的样本中显示。然而,只是指出了一个未被考虑的潜在选择。在这个行业多年后,我坚信这句格言,如果核心平台提供了人们可能需要的东西,就不要不必要地增加你的工作量。如果您确实有创造力,那意味着您必须永远照顾好它,文档,维护等等。
  • 同意。只是有时当您查看代码几个小时时,您想知道自己的代码哪里出错了。我认为 OP 将从循环技术中学到更多,而不是 robocopy/copy-item 辩论
【解决方案2】:

您没有显示文本文件中的内容,迫使我们猜测,相对于尝试帮助您而言,这并不是一件好事。所以,我将假设它只是一个驱动器号或路径 UNC 的列表,这真的没有实际意义,因为您可以动态地提取它们,因此不需要文件。

我不明白你为什么要这样做......

Get-Content 'C:\Users\Administrator\Desktop\here\drive4.txt' | 
Out-String

如果它只是一个用于阅读的文本文件,你为什么要在任何地方管道呢?

你不需要双引号。单引号表示简单字符串,双引号表示变量扩展或其他特定格式要求

$dest = 'C:\Users\Adminstrator\Desktop\here'

直接传读就行了

Get-Content 'C:\Users\Administrator\Desktop\here\drive4.txt' | 
ForEach {
    "Processing location $($PSItem.FullName)"
    Copy-Item -Path $PSItem.FullName -Destination $dest -Filter 'peruser.vbs' -Recurse -WhatIf
} 

注意事项: 您不需要 Write-Host 来输出到屏幕,因为这是 PowerShell 默认设置,我将在接下来的示例中展示。真的,除了用颜色写屏幕文本,你根本不需要使用 Write-Host/echo,好吧,还有其他一些特定的时间可以使用它。

另外值得注意的是,regarding Write-Host from the inventor of Monad/PowerShell Jeffery Snover

您也不一定需要 Get-ChildItem 和 Copy-Item,因为两者都会递归地读取文件夹树。如下所示。我正在使用 splatting 来收紧代码块以提高可读性。

所以,如果我只使用我系统上的驱动器和文件夹来演示这个。并逐步构建一个脚本,以确保在进行下一步之前,我在每一步都得到了我期望的结果。

Get-PSDrive -PSProvider FileSystem | 
Format-Table -AutoSize
<#
# Results

Name Used (GB) Free (GB) Provider   Root  CurrentLocation
---- --------- --------- --------   ----  ---------------
C       357.48    118.83 FileSystem C:\  Windows\system32
D       114.10    362.71 FileSystem D:\           Scripts
E      1194.00    668.89 FileSystem E:\                  
F      3537.07    188.83 FileSystem F:\                  
G                        FileSystem G:\  
#>

# Validate if there is any content in the destination
Try 
{
    Get-PSDrive -PSProvider FileSystem | 
    Where Name -eq 'D' | 
    ForEach {
        "Processing location $($PSItem.Root) and the contents are as listed."
        (Get-ChildItem -Path 'D:\Temp\here' -Recurse).FullName
    }
}
Catch {Write-Warning -Message 'No content in the destination folder'}
<#
# Results

Processing location D:\ and the contents are as listed.
WARNING: No content in the destination folder
#>

# Show what is on the drive for the source files
Get-PSDrive -PSProvider FileSystem | 
Where Name -eq 'D' | 
ForEach{
    "Processing the location $($PSItem.Root)"
    (Get-ChildItem -Path "$($PSItem.Root)\Temp\book1.csv" -Recurse).FullName
}
<#
# Results

Processing the location D:\
D:\Temp\Source\book1.csv
D:\Temp\book1.csv
#>

<#
# Show what will happen if a Copy files from the source to the destination occurs
Using splatting for readability
#>

Get-PSDrive -PSProvider FileSystem | 
Where Name -eq 'D' | 
ForEach{
    "Processing the location $($PSItem.Root)"
    $CopyItemSplat = @{
        Path        = "$($PSItem.Root)\Temp\book1.csv"  
        Destination = "$($PSItem.Root)\Temp\here" 
        Recurse     = $true
        WhatIf      = $true
    }
}
Copy-Item @CopyItemSplat
<#
# Results

Processing the location D:\
What if: Performing the operation "Copy File" on target "Item: D:\Temp\book1.csv Destination: D:\Temp\here\book1.csv".

If the results are as expected, execute the action
Using splatting for readability
#>

Get-PSDrive -PSProvider FileSystem | 
Where Name -eq 'D' | 
ForEach{
    "Processing the location $($PSItem.Root)"
    $CopyItemSplat = @{
        Path        = "$($PSItem.Root)\Temp\book1.csv"  
        Destination = "$($PSItem.Root)\Temp\here" 
        Recurse     = $true
    }
}
Copy-Item @CopyItemSplat
<#
# Results

Processing the location D:\
#>

# Validate if there is any content in the destination
Try 
{
    Get-PSDrive -PSProvider FileSystem | 
    Where Name -eq 'D' | 
    ForEach {
        "Processing location $($PSItem.Root) and the contents are as listed."
        (Get-ChildItem -Path 'D:\Temp\here' -Recurse).FullName
    }
}
Catch {Write-Warning -Message 'No content in the destination folder'}
<#
# Results

Processing location D:\ and the contents are as listed.
D:\Temp\here\book1.csv
#>

【讨论】:

  • 您好,谢谢您的回复,我回家后会好好看看。这是我唯一一次真正体验过 powershell,所以对我所犯的其他错误的反馈将非常有用
  • 不用担心。我们都在我们力所能及的时间和地点提供帮助。但是,如果您是新人,请在 Youtube 上跳起来,获得一些提升。只需搜索“开始 PowerShell”、“中级 PowerShell”、“高级 PowerShell”、“PowerShell 文件和文件夹管理”、“PowerShell 复制文件”、“PowerShell 移动文件”等。还可以查看 techcommunity.microsoft.com/t5/powershell/ct-p/…techsnips.io/?query=powershell以及此处的资源列表:reddit.com/r/PowerShell/comments/fhsxbe/learning_powershell
  • 今晚我留了几个小时,所以我一定会跳进去看看,再次感谢
猜你喜欢
  • 1970-01-01
  • 2015-03-08
  • 2019-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多