使用PowerShell Copy-Item高效地复制文件:全面指南

複製文件。這並不性感,但必須完成。在圖形用戶界面中,我們使用剪貼板複製和粘貼,但在PowerShell中,我們有一個名為Copy-Item的cmdlet。

複製文件的命令在所有shell語言中一直存在。在PowerShell中,將文件或文件夾從點A複製到點B的最常用方法是使用PowerShell的Copy-Item cmdlet。此cmdlet允許我們複製文件和文件夾,同時還可以遞歸文件夾中的文件,使用通配符選擇要複製的文件,甚至還可以使用PowerShell Remoting進行文件複製!

這個cmdlet是PowerShell提供者(cmdlet)的一部分。它是一個通用的cmdlet,通過其Item名稱來識別。這些提供者(cmdlet)中的大部分都可以在不同的提供者之間使用,但在我使用PowerShell的近10年中,我只見過Copy-Item與文件系統提供者一起使用。

通過使用this cmdlet,PowerShell允許開發人員以多種不同的方式複製文件和文件夾。

基本用法

在最基本的情況下,Copy-Item cmdlet使用Path參數作為源文件路徑,Destination參數作為目標文件夾路徑,將單個文件從點A複製到點B。

PS> Test-Path -Path C:\PointB\1.txt
False
PS> Copy-Item -Path C:\PointA\1.txt -Destination C:\PointB\
PS> Test-Path -Path C:\PointB\1.txt
True 

這個 cmdlet 也可以複製空的資料夾。我將列出 C:\EmptyFolder 資料夾中的項目,然後將它們複製出來。

PS> Get-ChildItem -Path C:\EmptyFolder\
PS> Test-Path -Path C:\PointB\EmptyFolder -PathType Container
False
PS> Copy-Item -Path C:\EmptyFolder\ -Destination C:\PointB\
PS> Test-Path -Path C:\PointB\EmptyFolder -PathType Container
True 

也許資料夾中有一個唯讀檔案。預設情況下,Copy-Item 不會覆蓋它。要強制覆蓋,只需添加 Force 參數。

使用 Copy-Item 的選擇性功能

除了複製單個檔案或資料夾外,我們還可以複製整個資料夾的所有內容。Copy-Item 的 Path 參數接受萬用字元,如星號匹配一個或多個字元,或問號只匹配一個字元。

PS> @(Get-ChildItem -Path C:\PointB).Count
0
PS> @(Get-ChildItem -Path C:\PointA).Count
10000
PS> @(Get-ChildItem -Path C:\PointB).Count
0
PS> Copy-Item -Path C:\PointA\* -Destination C:\PointB\
PS> @(Get-ChildItem -Path C:\PointB).Count
10000
PS> @(Get-ChildItem -Path C:\PointB).Count
0
PS> Copy-Item -Path 'C:\PointA\26?0.txt' -Destination C:\PointB\
PS> Get-ChildItem -Path C:\PointB\

Directory: C:\PointB
Mode                LastWriteTime         Length Name
-a----        8/11/2017   8:59 AM              5 2600.txt
-a----        8/11/2017   8:59 AM              5 2610.txt
-a----        8/11/2017   8:59 AM              5 2620.txt
-a----        8/11/2017   8:59 AM              5 2630.txt
-a----        8/11/2017   8:59 AM              5 2640.txt
-a----        8/11/2017   8:59 AM              5 2650.txt
-a----        8/11/2017   8:59 AM              5 2660.txt
-a----        8/11/2017   8:59 AM              5 2670.txt
-a----        8/11/2017   8:59 AM              5 2680.txt
-a----        8/11/2017   8:59 AM              5 2690.txt

合併多個資料夾

Copy-Item 的另一個很酷的功能是能夠同時複製多個資料夾。通過將多個路徑傳遞給 Path 參數,Copy-Item 將檢查每個路徑,根據路徑複製資料夾或檔案,並將它們全部合併到單一目的地。

PS> Copy-Item -Path C:\PointB\*,C:\PointC\*,C:\PointD\* -Destination C:\PointE
PS> Get-ChildItem -Path C:\PointE

Directory: C:\PointE
Mode                LastWriteTime         Length Name
-a----       11/11/2017  12:15 PM              2 PointBFile.txt
-a----       11/11/2017  12:15 PM              2 PointCFile.txt
-a----       11/11/2017  12:16 PM              4 PointDFile.txt

遞迴複製檔案

很有可能你不會那麼幸運,所有檔案都在一個資料夾中,而沒有其他資料夾。我們通常遇到的情況是在父資料夾中有許多子資料夾,我們也想複製其中的檔案。通過在 Copy-Item 上使用 Recurse 參數,它會很樂意查看每個子資料夾,並遞迴地複製所有檔案和資料夾。

注意這裡我正在直接將檔案和資料夾從 Get-ChildItem 連接到 Copy-Item。Copy-Item 支援管線功能!

PS> (Get-ChildItem -Path C:\PointB\ -Recurse).Count
5
PS> Get-ChildItem -Path C:\PointB\ | Copy-Item -Destination C:\PointC -Recurse
PS> (Get-ChildItem -Path C:\PointC\ -Recurse).Count
5

使用PassThru參數的優點

PowerShell中的許多cmdlet都有PassThru參數。通常不返回任何內容的cmdlet可以使用PassThru參數返回它們正在操作的對象。這個cmdlet也不例外。當我剛開始編寫腳本時,我從來不使用這個參數,因為我覺得我不需要。

例如,如果我想將文件複製到遠程位置,然後在腳本的其他地方引用該文件,我會這樣做:

$remoteFilePath = '\WEBSRV1\c$\File.txt'
Copy-Item -Path C:\File.txt -Destination $remoteFilePath
Write-Host "I've just copied the file to $remoteFilePath"

這種方法可以工作,但可以更好。不必為遠程路徑定義變量,而是使用PassThru參數捕獲從Copy-Item cmdlet返回的對象,返回的對象始終包含目標文件路徑。

$copiedFile = Copy-Item -Path C:\File.txt -Destination '\WEBSRV1\c$'

使用PowerShell遠程會話複製文件

PowerShell v5帶來的一個很酷的功能是,這個cmdlet可以不使用默認的SMB協議來傳輸文件,而是使用WinRM和PowerShell遠程會話。通過使用Session參數,Copy-Item使用現有的PowerShell會話來傳輸文件。這是繞過防火牆的好方法,並且在會話通信被加密時,還具有額外的安全層級。

PS> $session = New-PSSession -ComputerName WEBSRV1
PS> Invoke-Command -Session $session -ScriptBlock { Test-Path -Path C:\File.txt }
False
PS> Copy-Item -Path C:\File.txt -ToSession $session -Destination 'C:\'
PS> Invoke-Command -Session $session -ScriptBlock { Test-Path -Path C:\File.txt }
True

我們本來可以通過SMB複製File.txt文件,希望C$管理共享可用,並使用目標路徑\\WEBSRV1\c$。由於我們改用了ToSession參數,目標路徑始終是遠程會話運行所在計算機的本地路徑。

摘要

Copy-Item cmdlet 是 PowerShell 中的核心 cmdlet 之一,您將一次又一次地使用它。在 PowerShell 中,使用它可以以多種不同的方式複製文件和文件夾,它的簡單而強大,特別是可以使用通配符,將多個文件夾的文件合併在一起,並使用現有的 PowerShell Remoting 會話!

進一步閱讀

Copy-item

Source:
https://adamtheautomator.com/copy-item/