העתק קבצים ביעילות עם Copy-Item של PowerShell: מדריך מקיף

העתקת קבצים. זה לא מרתק אבל זה חייב להיעשות. בממשק הגרפי, אנו מעתיקים ומדביקים עם הלוח האחסון אך ב-PowerShell יש לנו כלי שנקרא Copy-Item.

פקודות להעתקת קבצים קיימות מאז ומתמיד בכל שפות השילוש. בעולם PowerShell, הדרך הפופולרית ביותר להעתיק קובץ או תיקייה בתסריט PowerShell שלך מנקודה A לנקודה B היא על ידי שימוש בפקודת PowerShell Copy-Item. פקודה זו מאפשרת לנו להעתיק קובץ ותיקייה תוך הענקת היכולת לגלוש קבצים בתיקייה, להשתמש בתוויות כוכבית כדי לבחור את הקבצים שאנו צריכים להעתיק ואפילו להשתמש PowerShell Remoting להעתקת קובץ!

הפקודה זו היא חלק מפקודות ספק ה-PowerShell. זו פקודה גנרית המוכרת לפי שם העצם Item. רוב פקודות ספק אלו יכולות להיות בשימוש בספקים שונים אך בעשור האחרון של שימוש ב-PowerShell, רק Copy-Item נראית לי להיות בשימוש עם ספק מערכת הקבצים.

על ידי שימוש בפקודה זו PowerShell מאפשר למפתח להעתיק קבצים ותיקיות במספר דרכים שונות.

שימוש בסיסי

בסיס השימוש בפקודת Copy-Item מעתיקה קובץ יחיד מנקודה A לנקודה B באמצעות הפרמטר Path כנתיב הקובץ המקורי והפרמטר Destination כנתיב התיקייה היעד.

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 

הפקודה הזו יכולה גם להעתיק תיקיות ריקות. אני אציין פריט בתיקייה 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

בנוסף להעתקת קובץ או תיקייה בודדת, אנו יכולים גם להעתיק את כל תוכן התיקייה. הפרמטר Path של Copy-Item מקבל תווים כמו הכוכבית להתאמה לתו או יותר או השאלה להתאמה לתו יחיד.

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

העתקת קבצים באופן רקורסיבי

יש סיכוי שלא תזכה למזל ויהיו לך כל הקבצים בתיקייה אחת ללא תתי תיקיות שם. נתקלים רגילות במצבים בהם יש לנו המון תיקיות משנה בתוך התיקייה האב שיש בה גם קבצים שברצוננו להעתיק. באמצעות הפרמטר Recurse ב- Copy-Item, הוא בטח יבדוק בכל תת-תיקייה ויעתיק את כל הקבצים והתיקיות בהן באופן רקורסיבי.

שים לב שכאן אני מייבא קבצים ותיקיות ישירות מ- 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

המון cmdlets ב-PowerShell מציעים את הפרמטר PassThru. Cmdlets שבדרך כלל לא מחזירים דבר יכולים להחזיר את האובייקטים שהם עובדים עליהם באמצעות הפרמטר 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"

השיטה הזו עובדת, אך אפשר לעשות זאת יותר טוב. במקום להגדיר משתנה עבור הנתיב המרוחק, למה לא פשוט לכוד את האובייקט שחוזר מקובץ ה-cmdlet Copy-Item כאשר משתמשים בפרמטר PassThru? האובייקטים שיחזרו יכילו תמיד את נתיב הקובץ היעד.

$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

אנו יכולים היינו יכולים להעתיק את הקובץ File.txt דרך SMB ולסמוך שהשיתוף המזדמן C$ זמין ולהשתמש בנתיב היעד \\WEBSRV1\c$. מאחר שהשתמשנו בפרמטר ToSession במקום, נתיב היעד יהיה תמיד הנתיב המקומי למחשב שבו רץ הישיבה הרחוקה.

סיכום

ה-\( \text{Copy-Item} \) cmdlet הוא אחד מה-\( \text{cmdlets} \) היסודיים של PowerShell שתשתמש בהם שוב ושוב. ב-PowerShell, ניתן להעתיק קבצים ותיקיות בכמה דרכים שונות בעזרתו הפשוט עם כוחו העצום במיוחד ביכולתו להשתמש ב-\( \text{wildcards} \), למזג מספר תיקיות של קבצים יחד ולהשתמש בסשני PowerShell Remoting קיימים!\

קריאה נוספת

Copy-item

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