Powershell 如何复制文件,然后将目标路径保存到CSV

Powershell 如何复制文件,然后将目标路径保存到CSV,powershell,powershell-2.0,export-to-csv,Powershell,Powershell 2.0,Export To Csv,我正在尝试将文件名以6位数字开头的一批文件从临时文件夹复制到一个永久位置,不包括新位置中已经存在的文件 复制完成后,我想将复制文件的文件名和新路径导出到CSV中 获取旧文件位置并导出到CSV非常容易,我只是不太确定如何获取新文件位置 我的脚本如下所示: # Prompt for file origin $file_location = Read-Host -Prompt "Where do you want your files to come from?" # Prompt for file

我正在尝试将文件名以6位数字开头的一批文件从临时文件夹复制到一个永久位置,不包括新位置中已经存在的文件

复制完成后,我想将复制文件的文件名和新路径导出到CSV中

获取旧文件位置并导出到CSV非常容易,我只是不太确定如何获取新文件位置

我的脚本如下所示:

# Prompt for file origin
$file_location = Read-Host -Prompt "Where do you want your files to come from?"
# Prompt for file destination 
$file_destination = Read-Host -Prompt "Where do you want your files to go? `n(They won't be copied if they're already there)"

# Save contents of file destination - used to check for duplicates
$dest_contents = Get-ChildItem $file_destination

<# For all of the files of interest (those whose names begin with 6 digits) in $file_location, 
     determine whether that filename already exists in the target directory ($file_destination)
     If it doesn't, copy the file to the destination
     Then save the filename and the new** filepath to a CSV #>

Get-ChildItem -Path $file_location |      
    Where-Object { $_.Name -match '^\d{6}' -And !($dest_contents -Match $_.Name ) } |
    Copy-Item -Destination $file_destination -PassThru | 
    Select-Object -Property Name, FullName |             # **Note: This saves the old filepath, not the new one
    Export-CSV -Path "$file_location\files_copied.csv" -NoClobber

您可以通过对代码进行一些更改来实现这一点

# Prompt for file origin
$file_location = Read-Host -Prompt "Where do you want your files to come from?"
# Prompt for file destination 
$file_destination = Read-Host -Prompt "Where do you want your files to go? `n(They won't be copied if they're already there)"

# Save contents of file destination - used to check for duplicates
$dest_contents = Get-ChildItem $file_destination | Select-Object -ExpandProperty Name

<# For all of the files of interest (those whose names begin with 6 digits) in $file_location, 
     determine whether that filename already exists in the target directory ($file_destination)
     If it doesn't, copy the file to the destination
     Then save the filename and the new** filepath to a CSV #>

Get-ChildItem -Path $file_location |      
    Where-Object { $_.Name -match '^\d{6}' -and ($dest_contents -notcontains $_.Name ) } |
    ForEach-Object { 
        Copy-Item -Path $_.FullName -Destination $file_destination 
        # emit a PSObject storing the Name and (destination) FullName of the file that has been copied
        # This will be used to generate the output in the 'files_copied.csv'
        New-Object -TypeName PSObject -Property ([ordered]@{ Name = $_.Name; FullName = (Join-Path $file_destination $_.Name)})
    } | 
    Export-CSV -Path "$file_location\files_copied.csv" -NoTypeInformation -Force
另外,我在这里使用[ordered],因此输出的属性总是以相同的顺序。但是,这需要PowerShell v3或更高版本。 此外,如果需要确保代码只复制文件,而不复制目录,我建议查看getchilditem命令上的-File或-Attributes开关。如果您的PowerShell版本为2.0,则可以使用Where对象{!$\u0.PSIsContainer}构造仅筛选出文件

在迭代源文件时,我将使用另一种方法测试目标是否存在

要附加到当前csv日志文件,需要删除新文件的头

由于Get ChildItem允许范围[0-9],您可以直接选择前导号码
这也太棒了!西奥建议的解决方案对原始代码进行了最小的更改,并给出了问题的精确答案。但此解决方案允许附加到日志文件,而不是为每个副本创建新文件。这是我的下一个任务!尽管如此,当您使用-InputObject时,Export-CSV cmdlet会将副本摘要而不是文件名输出到日志文件。else语句适当地附加了现有的CSV,因此我将管道从:Export CSV-Path$LogFile-InputObject$CopiedFiles-NoTypeInformation更改为:$CopiedFiles | Export CSV-Path$LogFile
Export-CSV -Path ("{0}\files_copied_{1}.csv" -f $file_location, (Get-Date).ToString("yyyy-MM-dd")) -NoTypeInformation -Force 
## Q:\Test\2018\08\08\SO_51738853.ps1
# Prompt for file origin
$SrcDir = Read-Host -Prompt "Where do you want your files to come from?"

# Prompt for file destination 
$DstDir = Read-Host -Prompt "Where do you want your files to go? `n(They won't be copied if they're already there)"

$SrcFiles = Join-Path (Get-Item $SrcDir).Fullname [0-9][0-9][0-9][0-9][0-9][0-9]*

$CopiedFiles = ForEach ($SrcFile in (Get-ChildItem -Path $SrcFiles)){
    $DstFile = Join-Path $DstDir $SrcFile.Name
    If (!(Test-Path $DstFile)){
        $SrcFile | Copy-Item  -Destination $DstFile -PassThru | 
            Select-Object -Property Name, FullName
    }
}    

# Check if log file exists, if yes append, otherwise export.
$LogFile = Join-Path $SrcDir "files_copied.csv"
If ($CopiedFiles){
    If (!(Test-Path $LogFile)){
        Export-CSV -Path $LogFile -InputObject $CopiedFiles -NoTypeInformation
    } else {
        # We need to remove the Header appending to the present csv
        $CopiedFiles | ConvertTo-Csv -NoType | Select-Object -Skip 1 | Add-Content -Path $LogFile
    }
}