我正在尝试使用CSV文件将目录 - 文件夹和子文件夹复制到另一个位置,该文件列出了要复制的每个目录或文件夹的来源和目标。
我引用了这个帖子:
https://serverfault.com/questions/399325/copying-list-of-files-through-powershell
Import-CSV C:\Users\WP\Desktop\a.csv | foreach{Copy-item "$_.Source" "$_.Destination"}
收到错误
CategoryInfo : ObjectNotFound: (@{Source=C:String) [Copy-Item], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
我遇到的另一个问题是,如果在CSV中我要复制到目标中不存在的文件夹 - 我可以使用CSV来命令powershell创建文件夹吗?
感谢您的建议。
答案 0 :(得分:1)
对于像这样的csv:
Source,Destination
D:\junk\test1,D:\junk\test3
D:\junk\test2,D:\junk\test4
您可以使用以下代码:
$csv = Import-Csv D:\junk\test.csv
$csv | ForEach-Object {
if (-not (Test-Path $_.Destination)) {
New-Item -Name $_.Destination -ItemType Directory -Force -WhatIf
}
Copy-Item $_.Source $_.Destination -Recurse -Force -WhatIf
}
有关了解有关PowerShell的更多信息的建议:
使用WhatIf
进行测试。
研究这段代码的每一行。
尝试使用代码查看其功能。
学习并使用调试器(PowerShell ISE)来帮助您编写更好的代码。
从代码中删除WhatIf
参数,使其执行真实...
答案 1 :(得分:1)
如果默认情况下将PowerShe放在双引号中,PowerShell将不会展开变量并访问变量内对象的属性。只有'$ _'被扩展并且'.source'被添加到字符串的末尾,所以从shell的视图来看,你的命令看起来像Copy-item "{source=C:\Users\WP\Desktop\a;Destination=C:\Users\WP\Desktop\a}.Source" "{source=C:\Users\WP\Desktop\a;Destination=C:\Users\WP\Desktop\a}.Destination"
,这可能不是你的的意思。
这是应该有效的语法(我还包括-Recurse
,以便它也会复制目录中的项目)
Import-CSV C:\Users\WP\Desktop\a.csv | foreach{Copy-item -Path $_.Source -Destination $_.Destination -Recurse}
注意:如果要访问双引号内对象的属性,请使用以下语法"$($_.source)"
。
答案 2 :(得分:0)
如果你有很多问题都涉及对列表的每个元素做同样的事情,你可能想要考虑获取或编写一个通用的CSV模板扩展工具,比如Expand-csv。使用此工具,您可以从CSV文件和模板开始,并生成包含所有命令的脚本。
Sample.csv如下所示:
Source,Destination
C:\Users\WP\Desktop\a,C:\Users\WP\Desktop\c
C:\Users\WP\Desktop\b,C:\Users\WP\Desktop\d
Sample.tmplt看起来像这样:
Copy-Item -Path $Source -Destination $Destination -Recurse
调用Expand-csv的命令如下所示:
Expand-csv Sample.csv Sample.tmplt > Sample.ps1
输出文件Sample.ps1包含CSV文件中每个条目的一个复制命令
以下是Expand-csv的定义:
<# This function is a table driven template tool.
It's a refinement of an earlier attempt.
It generates output from a template and
a driver table. The template file contains plain
text and embedded variables. The driver table
(in a csv file) has one column for each variable,
and one row for each expansion to be generated.
5/13/2015
#>
function Expand-csv {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string] $driver,
[Parameter(Mandatory=$true)]
[string] $template
)
Process
{
$OFS = "`r`n"
$list = Import-Csv $driver
[string]$pattern = Get-Content $template
foreach ($item in $list) {
foreach ($key in $item.psobject.properties) {
Set-variable -name $key.name -value $key.value
}
$ExecutionContext.InvokeCommand.ExpandString($pattern)
}
}
}