Kopieer Bestanden Efficiënt met PowerShell Copy-Item: Een Uitgebreide Gids

Bestanden kopiëren. Het is niet sexy maar moet gedaan worden. In de GUI kopiëren en plakken we met het klembord, maar in PowerShell hebben we een cmdlet genaamd Copy-Item.

Opdrachten voor het kopiëren van bestanden bestaan al eeuwen in alle shell-talen. In de PowerShell-wereld is de meest populaire manier om een kopie van een bestand of map te krijgen in je PowerShell-script van punt A naar punt B door gebruik te maken van de PowerShell Copy-Item cmdlet. Deze cmdlet stelt ons in staat om een bestand en map te kopiëren terwijl we de mogelijkheid hebben om bestanden in een map recursief te kopiëren, wildcards te gebruiken om de bestanden te selecteren die we nodig hebben om te kopiëren en zelfs gebruik te maken van PowerShell Remoting voor een bestandskopiëring!

Deze cmdlet maakt deel uit van de PowerShell-provider cmdlets. Het is een generieke cmdlet die wordt herkend aan zijn zelfstandig naamwoord Item. De meeste van deze provider-cmdlets kunnen worden gebruikt met verschillende providers, maar in mijn bijna 10 jaar ervaring met PowerShell heb ik alleen Copy-Item gezien die wordt gebruikt met de bestandssysteemprovider.

Door gebruik te maken van deze cmdlet stelt PowerShell een ontwikkelaar in staat om bestanden en mappen op verschillende manieren te kopiëren.

Basisgebruik

Op zijn meest eenvoudig kopieert de Copy-Item cmdlet een enkel bestand van punt A naar punt B met behulp van de Path parameter als het bronbestandspad en de Destination parameter als het doelmap-pad.

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 

Deze cmdlet kan ook lege mappen kopiëren. Ik zal items in de map C:\EmptyFolder vermelden en deze dan kopiëren.

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 

Misschien staat er een alleen-lezen bestand in de map. Standaard zal Copy-Item het niet overschrijven. Om de overschrijving af te dwingen, voegt u gewoon de parameter Force toe.

Selectief kopiëren met Copy-Item

Naast het kopiëren van een enkel bestand of map, kunnen we ook de volledige inhoud van een map kopiëren. De parameter Path van Copy-Item accepteert wildcardtekens zoals het asterisk om één of meer tekens te matchen of het vraagteken om slechts één teken te matchen.

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

Meerdere mappen samenvoegen

Nog een handige functie van Copy-Item is het vermogen om meerdere mappen tegelijkertijd te kopiëren. Door meerdere paden door te geven aan de parameter Path, zal Copy-Item naar elk ervan kijken, ofwel de map of het bestand(ken) kopiëren afhankelijk van het pad en ze allemaal samenvoegen in de enkele bestemming.

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

Bestanden recursief kopiëren

De kans is klein dat je geluk hebt en alle bestanden in één map hebt zonder ook mappen erin. We komen meestal situaties tegen waarin we veel submappen hebben in de hoofdmap waar ook bestanden in staan die we willen kopiëren. Door de parameter Recurse te gebruiken bij Copy-Item, zal het graag in elke submap kijken en alle bestanden en mappen recursief kopiëren.

Let hier op dat ik bestanden en mappen rechtstreeks van Get-ChildItem naar Copy-Item leid. Copy-Item ondersteunt pijplijnwerking!

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

Voordelen van het gebruik van de PassThru-parameter

Veel cmdlets in PowerShell hebben een PassThru-parameter. Cmdlets die typisch niets teruggeven, kunnen de objecten die ze manipuleren teruggeven met behulp van de PassThru-parameter. Deze cmdlet is niet anders. Toen ik voor het eerst begon met scripten, gebruikte ik deze parameter nooit omdat ik dacht dat ik het niet nodig had.

Bijvoorbeeld, als ik een bestand naar een externe locatie wilde kopiëren en later in mijn script naar dat bestand wilde verwijzen, zou ik iets als dit doen:

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

Deze methode werkt, maar het kan beter. In plaats van een variabele te definiëren voor het externe pad, waarom dan niet gewoon het object vastleggen dat wordt geretourneerd door de Copy-Item cmdlet bij gebruik van de PassThru-parameter? De geretourneerde objecten zullen altijd het bestemmingsbestandspad hebben.

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

Bestanden kopiëren met behulp van een PowerShell-verbinding op afstand

Een coole functie die werd geïntroduceerd met PowerShell v5 is de mogelijkheid van deze cmdlet om niet het standaard SMB-protocol te gebruiken voor het overbrengen van een bestand, maar in plaats daarvan WinRM en een PowerShell-verbinding op afstand te gebruiken. Door de Session-parameter te gebruiken, gebruikt Copy-Item een bestaande PowerShell-sessie en worden de bestanden op die manier overgebracht. Dit is een geweldige manier om firewalls te omzeilen en wanneer de sessiecommunicatie is versleuteld, ook een extra beveiligingslaag.

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

We konden het bestand File.txt via SMB hebben gekopieerd en gehoopt hebben dat de C$ admin-share beschikbaar was en het bestemmingspad van \\WEBSRV1\c$ had gebruikt. Aangezien we echter de ToSession-parameter hebben gebruikt, zal het bestemmingspad altijd het pad zijn dat lokaal is voor de computer waarop de externe sessie wordt uitgevoerd.

Samenvatting

De cmdlet Copy-Item is een van die kern-PowerShell-cmdlets die je keer op keer zult gebruiken. In PowerShell kun je bestanden en mappen op verschillende manieren kopiëren met deze eenvoudige maar krachtige cmdlet, vooral met zijn vermogen om wildcards te gebruiken, meerdere mappen met bestanden samen te voegen en bestaande PowerShell Remoting-sessies te gebruiken!

Verder lezen

Copy-item

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