Skip to content

הפילוסופיה של PowerShell. חלק 3: ניווט וניהול מערכת קבצים. אופרטורים לוגיים. מבוא לפונקציות.

  • hypo69 

בחלק הקודם חקרנו צינורות ואובייקטים מופשטים של תהליכים. כעת בואו ניישם את הידע שלנו על צינורות ואובייקטים לאחת המשימות הנפוצות של משתמש או מנהל מערכת — עבודה עם מערכת הקבצים. ב-PowerShell, עבודה זו בנויה על אותם עקרונות: פקודות מחזירות אובייקטים שניתן להעביר בצינור לעיבוד נוסף.


1. מושג ה-PowerShell Drives (PSDrives)

לפני שתתחיל לעבוד עם קבצים, חשוב להבין את מושג הכונני PowerShell (PSDrives). בניגוד ל-cmd.exe, שבו כוננים הם רק אותיות C:, D: וכן הלאה, ב-PowerShell "כונן" הוא הפשטה לגישה לכל מאגר נתונים היררכי.

Get-PSDrive

התוצאה תציג לא רק כוננים פיזיים, אלא גם כונני פסאודו:

שםספקשורשתיאור
AliasAliasAlias:\כינויי פקודות
CFileSystemC:\כונן מקומי C
CertCertificateCert:\מאגר אישורים
EnvEnvironmentEnv:\משתני סביבה
FunctionFunctionFunction:\פונקציות טעונות
HKCURegistryHKEY_CURRENT_USERענף רישום
HKLMRegistryHKEY_LOCAL_MACHINEענף רישום
VariableVariableVariable:\משתני סשן
WSManWSManWSMan:\תצורת WinRM

איחוד זה אומר שאתה יכול "להיכנס" לרישום (Set-Location HKLM:) ולקבל רשימה של המפתחות שלו עם אותה פקודה Get-ChildItem שבה אתה משתמש כדי לקבל רשימה של קבצים בכונן C:. זהו מושג חזק להפליא.

דוגמאות לעבודה עם ספקים שונים

  • מאגר אישורים (Cert:) מאפשר לך לעבוד עם אישורים דיגיטליים כאילו היו קבצים בתיקיות. משימה: מצא את כל אישורי ה-SSL במחשב המקומי שתוקפם יפוג ב-30 הימים הקרובים. # נווט למאגר האישורים של המחשב המקומי Set-Location Cert:\LocalMachine\My # מצא אישורים שבהם תאריך הסיום קטן מהיום + 30 יום Get-ChildItem | Where-Object { $_.NotAfter -lt (Get-Date).AddDays(30) } | Select-Object Subject, NotAfter, Thumbprint
  • משתני סביבה (Env:) מספק גישה למשתני סביבה של Windows (%PATH%, %windir% וכו') כאילו היו קבצים. משימה: קבל את הנתיב לתיקיית המערכת של Windows והוסף אליו את הנתיב ל-System32. # קבל את הערך של המשתנה windir $windowsPath = (Get-Item Env:windir).Value # או פשוט יותר: $windowsPath = $env:windir # בנה בבטחה את הנתיב המלא $system32Path = Join-Path -Path $windowsPath -ChildPath "System32" Write-Host $system32Path # תוצאה: C:\WINDOWS\System32
  • רישום Windows (HKCU: ו-HKLM:) דמיין שהרישום הוא רק עוד מערכת קבצים. ענפים הם תיקיות, ופרמטרים הם מאפיינים של תיקיות אלה. משימה: גלה את השם המלא של גרסת Windows המותקנת מהרישום. # נווט לענף הרישום הרצוי Set-Location "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" # קבל את המאפיין (פרמטר רישום) בשם "ProductName" Get-ItemProperty -Path . -Name "ProductName" # תוצאה: ProductName : Windows 11 Pro
  • פונקציות טעונות (Function:) מציג את כל הפונקציות הזמינות בסשן PowerShell הנוכחי, כאילו היו קבצים. משימה: מצא את כל הפונקציות הטעונות ששמן מכיל את המילה "Help" והצג את הקוד של אחת מהן. # חפש פונקציות לפי מסכה Get-ChildItem Function: | Where-Object { $_.Name -like "*Help*" } # קבל את הקוד המלא (הגדרה) של הפונקציה Get-Help (Get-Item Function:Get-Help).Definition
  • משתני סשן (Variable:) מאפשר לך לנהל את כל המשתנים ($myVar, $PROFILE, $Error וכו') המוגדרים בסשן הנוכחי. משימה: מצא את כל המשתנים הקשורים לגרסת PowerShell ($PSVersionTable, $PSHOME וכו'). # מצא את כל המשתנים המתחילים ב-"PS" Get-ChildItem Variable:PS* # קבל את הערך של משתנה ספציפי Get-Variable -Name "PSVersionTable"

2. ניווט וניתוח

יסודות הניווט

# גלה היכן אנו נמצאים (מחזיר אובייקט PathInfo)
Get-Location          # כינויים: gl, pwd

# מעבר לשורש כונן C:\
Set-Location C:\      # כינויים: sl, cd

# מעבר לתיקיית הבית של המשתמש הנוכחי
Set-Location ~

# הצג את תוכן התיקייה הנוכחית (מחזיר אוסף של אובייקטים)
Get-ChildItem         # כינויים: gci, ls, dir
# **חיפוש רקורסיבי**
# מצא את קובץ ה-hosts במערכת, תוך התעלמות משגיאות "גישה נדחתה"
Get-ChildItem C:\ -Filter "hosts" -Recurse -ErrorAction SilentlyContinue

המתג -Recurse (רקורסיבי): גורם ל-cmdlet לעבוד לא רק עם הפריט שצוין, אלא גם עם כל תוכנו.

המתג -ErrorAction SilentlyContinue: הוראה להתעלם משגיאות ולהמשיך בשקט.

ניתוח שטח דיסק

דוגמה קלאסית לעוצמת הצינור: מצא, מיין, עצב ובחר.

Get-ChildItem C:\Users -File -Recurse -ErrorAction SilentlyContinue |
    Sort-Object Length -Descending |
    Select-Object FullName, @{Name="Size(MB)"; Expression={[math]::Round($_.Length/1MB,2)}} |
    Select-Object -First 20
טיפ כיצד להזין פקודות ארוכות.

PowerShell מאפשר לך לפצל אותן למספר שורות לנוחות הקריאה.

  • לאחר אופרטור הצינור (|): זו הדרך הנפוצה והנוחה ביותר. פשוט לחץ Enter לאחר הסמל |. PowerShell יראה שהפקודה לא הושלמה, ויחכה להמשך בשורה הבאה.
  • בכל מקום אחר: השתמש בתו הגרש ההפוך (`) בסוף השורה, ולאחר מכן לחץ Enter. תו זה אומר ל-PowerShell: "הפקודה תימשך בשורה הבאה".
  • בעורכים (ISE, VS Code): צירוף המקשים Shift+Enter בדרך כלל מכניס אוטומטית מעבר שורה, מבלי להריץ את הפקודה.

סינון תוכן ואופרטורים לוגיים

# מצא את כל קבצי ה-.exe. הפרמטר -Filter עובד מהר מאוד.
Get-ChildItem C:\Windows -Filter "*.exe"

Get-ChildItem מחזיר אוסף של אובייקטים. אנו יכולים להעביר אותו בצינור ל-Where-Object לסינון נוסף.

# הצג רק קבצים
Get-ChildItem C:\Windows | Where-Object { $_.PSIsContainer -eq $false }

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

אופרטורי השוואה ולוגיקה

אלו מילות מפתח מיוחדות להשוואת ערכים. הן תמיד מתחילות במקף (-) ומהוות את הבסיס לסינון נתונים ב-Where-Object ולבניית לוגיקה ב-if.

אופרטורתיאורדוגמה בצינור
-eqשווה (EQual)$_.Name -eq "svchost.exe"
-neלא שווה (Not Equal)$_.Status -ne "Running"
-gtגדול מ- (Greater Than)$_.Length -gt 1MB
-geגדול או שווה ל- (Greater or Equal)$_.Handles -ge 500
-ltקטן מ- (Less Than)$_.LastWriteTime -lt (Get-Date).AddDays(-30)
-leקטן או שווה ל- (Less or Equal)$_.Count -le 1
-likeדומה ל- (עם תווים כלליים *, ?)$_.Name -like "win*"
-notlikeלא דומה ל-$_.Name -notlike "*.tmp"
-inהערך כלול באוסף$_.Extension -in ".log", ".txt"
-andו-לוגי (שני התנאים נכונים)
-orאו-לוגי (לפחות תנאי אחד נכון)
-notלא-לוגי (הופך את התנאי)

נושא האופרטורים הלוגיים הוא נרחב מאוד ואני אקדיש לו חלק נפרד (או אפילו שניים). בינתיים, חמושים באופרטורים אלה, אנו יכולים לסנן, למיין ולבחור את הקבצים והתיקיות שאנו צריכים, תוך שימוש בכל עוצמת צינור האובייקטים.

דוגמאות לשימוש במערכת הקבצים

  • מצא קובץ לפי שם מדויק (תלוי רישיות): Get-ChildItem C:\Windows\System32 -Recurse | Where-Object { $_.Name -eq "kernel32.dll" }
  • מצא את כל קבצי ה-.exe. הפרמטר -Filter עובד מהר מאוד: Get-ChildItem C:\Windows -Filter "*.exe"
  • הצג רק קבצים: Get-ChildItem C:\Windows | Where-Object { $_.PSIsContainer -eq $false }
  • מצא את כל הקבצים המתחילים ב-"host", אך אינם תיקיות: Get-ChildItem C:\Windows\System32\drivers\etc | Where-Object { ($_.Name -like "host*") -and (-not $_.PSIsContainer) }
  • מצא את כל קבצי היומן (.log) שגודלם עולה על 50 מגה-בייט: Get-ChildItem C:\Windows\Logs -Filter "*.log" -Recurse | Where-Object { $_.Length -gt 50MB }
  • מצא את כל קבצי הטמפ (.tmp) וקבצי הגיבוי (.bak) לניקוי: האופרטור -in כאן אלגנטי הרבה יותר מכמה תנאים עם -or. $extensionsToDelete = ".tmp", ".bak", ".old" Get-ChildItem C:\Temp -Recurse | Where-Object { $_.Extension -in $extensionsToDelete }
  • מצא את כל קבצי ה-Word (.docx) שנוצרו בשבוע האחרון: $oneWeekAgo = (Get-Date).AddDays(-7) Get-ChildItem C:\Users\MyUser\Documents -Filter "*.docx" -Recurse | Where-Object { $_.CreationTime -ge $oneWeekAgo }
  • מצא קבצים ריקים (0 בתים) שאינם תיקיות: Get-ChildItem C:\Downloads -Recurse | Where-Object { ($_.Length -eq 0) -and (-not $_.PSIsContainer) }
  • מצא את כל קבצי ההפעלה (.exe) ששונו השנה, אך לא בחודש זה: דוגמה מורכבת זו מדגימה את עוצמת השילוב של אופרטורים. Get-ChildItem "C:\Program Files" -Filter "*.exe" -Recurse | Where-Object { ($_.LastWriteTime.Year -eq (Get-Date).Year) -and ($_.LastWriteTime.Month -ne (Get-Date).Month) }

(הערה: סוגריים () סביב כל תנאי משמשים לקיבוץ ולשיפור הקריאות, במיוחד במקרים מורכבים).

היזהר עם רקורסיה: יותר מדי קבצים/תיקיות — -Recurse יכול להיכנס רקורסיבית לעשרות אלפי פריטים. קישורים סימבוליים / קישורים מעגליים — יכולים לגרום לרקורסיה אינסופית. קבצים ללא הרשאות גישה — יכולים לחסום את הביצוע.

4. יצירה, ניהול ומחיקה בטוחה

יצירה, העתקה והעברה

New-Item -Path "C:\Temp\MyFolder" -ItemType Directory
Add-Content -Path "C:\Temp\MyFolder\MyFile.txt" -Value "שורה ראשונה"
Copy-Item -Path "C:\Temp\MyFolder" -Destination "C:\Temp\MyFolder_Copy" -Recurse

מחיקה בטוחה

Remove-Item הוא cmdlet שעלול להיות מסוכן, ולכן ל-PowerShell יש מנגנוני הגנה מובנים.

המתג -WhatIf (מה אם?): החבר הטוב ביותר שלך. הוא אינו מבצע את הפקודה, אלא רק מציג הודעה בקונסולה על מה היה קורה.

# בדיקה בטוחה לפני מחיקה
Remove-Item C:\Temp\MyFolder -Recurse -Force -WhatIf
# תוצאה: What if: Performing the operation "Remove Directory" on target "C:\Temp\MyFolder".

# רק לאחר שווידאת שהכל תקין, הסר את -WhatIf ובצע את הפקודה
Remove-Item C:\Temp\MyFolder -Recurse -Force

מבוא לפונקציות

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

כיצד להשתמש ולשמור פונקציות

ישנן שלוש דרכים עיקריות להפוך את הפונקציות שלך לזמינות:

שיטה 1: זמנית (לצורך בדיקות) אתה יכול להקליד בקונסולה או פשוט להעתיק ולהדביק את כל קוד הפונקציה לקונסולת PowerShell. הפונקציה תהיה זמינה עד לסגירת חלון זה.

שיטה 2: קבועה, אך ידנית (באמצעות קובץ .ps1) זו הדרך הנפוצה ביותר לארגון ושיתוף כלים. אתה שומר את הפונקציה בקובץ .ps1 וטוען אותה לסשן כאשר אתה זקוק לה.

Dot Sourcing (. . est.ps1): פקודה מיוחדת זו מבצעת את הסקריפט בהקשר הנוכחי, מה שהופך את כל הפונקציות והמשתנים שלה לזמינים בקונסולה שלך.

שיטה 3: אוטומטית (באמצעות פרופיל PowerShell) זו הדרך החזקה ביותר עבור הכלים האישיים שלך, הנפוצים בשימוש.

מהו פרופיל PowerShell? זהו סקריפט .ps1 מיוחד ש-PowerShell מריץ אוטומטית בכל פעם שהוא מופעל. כל מה שתשים בקובץ זה — כינויים, משתנים וכמובן, פונקציות — יהיה זמין בכל סשן כברירת מחדל.

  1. מצא את הנתיב לקובץ הפרופיל. PowerShell שומר אותו במשתנה $PROFILE. $PROFILE
  2. צור את קובץ הפרופיל אם הוא אינו קיים. if (-not (Test-Path $PROFILE)) { New-Item -Path $PROFILE -Type File -Force }
  3. הוסף את קוד הפונקציה שלנו לסוף קובץ הפרופיל. Add-Content -Path $PROFILE -Value $functionCode
  4. הפעל מחדש את PowerShell (או הרץ . $PROFILE), וכעת הפקודה Find-DuplicateFiles שלך תהיה זמינה תמיד, בדיוק כמו Get-ChildItem.
דוגמה 1: מציאת קבצים כפולים

בואו נעבור על כל השלבים באמצעות הפונקציה Find-DuplicateFiles כדוגמה.

שלב 1: הגדר את קוד הפונקציה

$functionCode = @'
function Find-DuplicateFiles {
    param(
        [Parameter(Mandatory=$true)]
        [string]$Path
    )

    Get-ChildItem $Path -File -Recurse -ErrorAction SilentlyContinue |
        Group-Object Name, Length |
        Where-Object { $_.Count -gt 1 } |
        ForEach-Object {
            # זו השורה המתוקנת:
            # בתוך אופרטור $() משתנים אינם מוצפנים.
            Write-Host "נמצאו כפילויות: $($_.Name)" -ForegroundColor Yellow
            $_.Group | Select-Object FullName, Length, LastWriteTime
        }
}
'@

שלב 2 (אפשרות א'): שמור בקובץ נפרד לטעינה ידנית

# שמור
Set-Content -Path ".\Find-DuplicateFiles.ps1" -Value $functionCode
# טען 
. .\Find-DuplicateFiles.ps1

Dot Sourcing (. . est.ps1): פקודה מיוחדת זו מבצעת את הסקריפט בהקשר הנוכחי, מה שהופך את כל הפונקציות והמשתנים שלה לזמינים בקונסולה שלך.

# קרא
Find-DuplicateFiles -Path "C:\Users\$env:USERNAME\Downloads"

שלב 2 (אפשרות ב'): הוסף לפרופיל לטעינה אוטומטית בואו נהפוך את הפונקציה הזו לזמינה תמיד.

מהו פרופיל PowerShell? זהו סקריפט .ps1 מיוחד ש-PowerShell מריץ אוטומטית בכל פעם שהוא מופעל. כל מה שתשים בקובץ זה — כינויים, משתנים ופונקציות — יהיה זמין בכל סשן כברירת מחדל.

  1. מצא את הנתיב לקובץ הפרופיל. PowerShell שומר אותו במשתנה $PROFILE. $PROFILE
  2. צור את קובץ הפרופיל אם הוא אינו קיים. if (-not (Test-Path $PROFILE)) { New-Item -Path $PROFILE -Type File -Force }
  3. הוסף את קוד הפונקציה שלנו לסוף קובץ הפרופיל. Add-Content -Path $PROFILE -Value $functionCode
  4. הפעל מחדש את PowerShell (או הרץ . $PROFILE), וכעת הפקודה Find-DuplicateFiles שלך תהיה זמינה תמיד, בדיוק כמו Get-ChildItem.
דוגמה 2: יצירת ארכיון ZIP עם גיבוי

קוד עבור קובץ Backup-FolderToZip.ps1:

function Backup-FolderToZip {
    param([string]$SourcePath, [string]$DestinationPath)
    if (-not (Test-Path $SourcePath)) { Write-Error "Исходная папка не найдена."; return }
    $timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm"
    $archiveFileName = "Backup_{0}_{1}.zip" -f (Split-Path $SourcePath -Leaf), $timestamp
    $fullArchivePath = Join-Path $DestinationPath $archiveFileName
    if (-not (Test-Path $DestinationPath)) { New-Item -Path $DestinationPath -ItemType Directory -Force | Out-Null }
    Compress-Archive -Path "$SourcePath\*" -DestinationPath $fullArchivePath -Force
    Write-Host "גיבוי הושלם: $fullArchivePath" -ForegroundColor Green
}

אני אספק פירוט מפורט של פונקציות בחלקים הבאים.


מדריך Cmdlet לפעולות מערכת קבצים

1. Cmdlets בסיסיים

רשימה זו כוללת 12 cmdlets חיוניים המכסים 90% מהמשימות היומיומיות.

Cmdletמטרה עיקריתדוגמה לשימוש
Get-ChildItemקבל רשימה של קבצים ותיקיות.Get-ChildItem C:\Windows
Set-Locationעבור לתיקייה אחרת.Set-Location C:\Temp
Get-Locationהצג את התיקייה הנוכחית.Get-Location
New-Itemצור קובץ או תיקייה חדשים.New-Item "report.docx" -Type File
Remove-Itemמחק קובץ או תיקייה.Remove-Item "old_log.txt"
Copy-Itemהעתק קובץ או תיקייה.Copy-Item "file.txt" -Dest "D:\"
Move-Itemהעבר קובץ או תיקייה.Move-Item "report.docx" -Dest "C:\Archive"
Rename-Itemשנה שם קובץ או תיקייה.Rename-Item "old.txt" -NewName "new.txt"
Get-Contentקרא את תוכן הקובץ.Get-Content "config.ini"
Set-Contentכתוב/החלף את תוכן הקובץ."data" | Set-Content "file.txt"
Add-Contentהוסף תוכן לסוף הקובץ.Get-Date | Add-Content "log.txt"
Test-Pathבדוק אם קובץ או תיקייה קיימים.Test-Path "C:\Temp"

צריך לקרוא את תוכן קובץ טקסט? השתמש ב-Get-Content. צריך להחליף לחלוטין קובץ בתוכן חדש? השתמש ב-Set-Content. צריך להוסיף שורה לקובץ יומן מבלי למחוק נתונים ישנים? השתמש ב-Add-Content. צריך לבדוק אם קובץ קיים לפני כתיבה? השתמש ב-Test-Path.

2. Cmdlets מיוחדים למשימות מתקדמות

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

  • עבודה עם נתיבים (Path)
    • Join-Path: מאחד בבטחה חלקי נתיב, תוך הוספה אוטומטית של \.
    • Split-Path: מפצל נתיב לחלקים (תיקייה, שם קובץ, סיומת).
    • Resolve-Path: ממיר נתיב יחסי (למשל, . או ..\files) לנתיב מלא, מוחלט.
  • עבודה עם מאפיינים ותוכן (Item Properties and Content)
    • Get-ItemProperty: מקבל את המאפיינים של קובץ ספציפי (למשל, IsReadOnly, CreationTime).
    • Set-ItemProperty: משנה את המאפיינים של קובץ או תיקייה.
    • Clear-Content: מוחק את כל התוכן מקובץ, אך משאיר את הקובץ עצמו ריק.
  • ניווט מתקדם (Location Stack)
    • Push-Location: "זוכר" את התיקייה הנוכחית ועובר לחדשה.
    • Pop-Location: חוזר לתיקייה ש-Push-Location "זכר".
  • ניהול הרשאות גישה (ACL)
    • Get-Acl: מקבל רשימה של הרשאות גישה (ACL) עבור קובץ או תיקייה.
    • Set-Acl: מגדיר הרשאות גישה עבור קובץ או תיקייה (פעולה מורכבת).

צריך לשנות מאפיין קובץ, למשל, להפוך אותו ל"קריאה בלבד"? השתמש ב-Set-ItemProperty. צריך לנקות לחלוטין קובץ יומן מבלי למחוק אותו? השתמש ב-Clear-Content. צריך לעבור זמנית לתיקייה אחרת בסקריפט, ואז לחזור בבטחה? השתמש ב-Push-Location ו-Pop-Location. צריך לגלות למי יש גישה לתיקייה? השתמש ב-Get-Acl.

בחלק הבא נלמד כיצד לעבוד עם מאגרי נתונים אחרים, כגון רישום Windows, באמצעות אותן גישות, נתעמק במושג הפונקציות, נבחן אופרטורים לוגיים ונלמד כיצד לתקשר באופן אינטראקטיבי עם המעטפת.

פילוסופיה של PowerShell ב-github: היסטוריה ו-cmdlet ראשון

חלק 2: צינור (Pipeline), משתנים, Get-Member, קובץ .ps1 וייצוא תוצאות. דוגמאות לחלק השני: system_monitor.ps1

חלק 3: ניווט וניהול מערכת קבצים.

דוגמאות לחלק השלישי: Find-DuplicateFiles.ps1 Backup-FolderToZip

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *