كيف تحذف بشكل متكرر دليل كامل مع PowerShell 2.0؟
-
20-09-2019 - |
سؤال
ما هي أبسط طريقة لحذف الدليل بقوة وجميع الدلائل الفرعية في PowerShell؟ أنا أستخدم PowerShell V2 في Windows 7.
لقد تعلمت من عدة مصادر أن الأمر الأكثر وضوحًا ، Remove-Item $targetDir -Recurse -Force
, ، لا يعمل بشكل صحيح. يتضمن ذلك بيانًا في مساعدة PowerShell V2 عبر الإنترنت (تم العثور عليها باستخدام Get-Help Remove-Item -Examples
) أن ينص على:
... نظرًا لأن المعلمة RECURSE في هذا CMDLET معيبة ، فإن الأمر يستخدم CMDLET Get-Childitem للحصول على الملفات المطلوبة ، ويستخدم مشغل خط الأنابيب لتمريرها إلى CMDLET الإزالة ...
لقد رأيت العديد من الأمثلة التي تستخدم Get-Childitem وأنبوبها إلى إزالة بند, ، ولكن الأمثلة عادة ما تزيل بعض مجموعة الملفات بناءً على مرشح ، وليس الدليل بأكمله.
أنا أبحث عن أنظف طريقة لتفجير دليل وملفات وأدلة أطفال كاملة ، دون إنشاء أي رسائل تحذير من المستخدمين باستخدام أقل كمية من التعليمات البرمجية. سيكون خط واحد لطيفًا إذا كان من السهل فهمه.
المحلول
Remove-Item -Recurse -Force some_dir
لا يعمل بالفعل كما هو معلن هنا.
rm -r -fo some_dir
هي الأسماء المستعارة المختصرة التي تعمل أيضا.
بقدر ما فهمت ذلك ، -Recurse
المعلمة فقط لا تعمل بشكل صحيح عند محاولة حذف مجموعة من الملفات التي تمت تصفيتها بشكل متكرر. لقتل دير واحد وكل شيء أدناه يبدو أنه يعمل بشكل جيد.
نصائح أخرى
انا إستعملت:
rm -r folderToDelete
هذا يعمل بالنسبة لي مثل سحر (سرقته من أوبونتو).
عند حذف الملفات بشكل متكرر باستخدام بسيط Remove-Item "folder" -Recurse
أرى أحيانًا خطأ متقطعًا: [folder] cannot be removed because it is not empty.
تحاول هذه الإجابة منع هذا الخطأ عن طريق حذف الملفات بشكل فردي.
function Get-Tree($Path,$Include='*') {
@(Get-Item $Path -Include $Include -Force) +
(Get-ChildItem $Path -Recurse -Include $Include -Force) |
sort pspath -Descending -unique
}
function Remove-Tree($Path,$Include='*') {
Get-Tree $Path $Include | Remove-Item -force -recurse
}
Remove-Tree some_dir
التفاصيل المهمة هي فرز جميع العناصر مع pspath -Descending
بحيث يتم حذف الأوراق قبل الجذور. يتم الفرز على pspath
المعلمة لأن ذلك لديه فرصة أكبر للعمل لمقدمي الخدمات بخلاف نظام الملفات. ال -Include
المعلمة هي مجرد راحة إذا كنت ترغب في تصفية العناصر لحذفها.
تم تقسيمها إلى وظيفتين لأنني أجد أنه من المفيد رؤية ما أنا على وشك حذفه عن طريق التشغيل
Get-Tree some_dir | select fullname
rm -r ./folder -Force
... عملت بالنسبة لي
جرب هذا المثال. إذا لم يكن الدليل موجودًا ، فلن يتم رفع أي خطأ. قد تحتاج PowerShell v3.0.
remove-item -path "c:\Test Temp\Test Folder" -Force -Recurse -ErrorAction SilentlyContinue
استخدم أمر DOS في المدرسة القديمة:
rd /s <dir>
لتجنب أخطاء "الدليل ليست فارغة" من الإجابة المقبولة ، ما عليك سوى استخدام أمر DOS القديم الجيد كما هو مقترح من قبل. بناء جملة PS الكامل جاهز للنسخ هو:
& cmd.exe /c rd /S /Q $folderToDelete
لسبب ما ، لم تنجح إجابة جون ريس في بعض الأحيان في حالتي. لكنه قادني في الاتجاه التالي. أولاً ، أحاول حذف الدليل بشكل متكرر مع خيار عربات التي تجرها الدواب. بعد ذلك ، أنزل إلى كل فرعي يتبقى وحذف جميع الملفات.
function Remove-Tree($Path)
{
Remove-Item $Path -force -Recurse -ErrorAction silentlycontinue
if (Test-Path "$Path\" -ErrorAction silentlycontinue)
{
$folders = Get-ChildItem -Path $Path –Directory -Force
ForEach ($folder in $folders)
{
Remove-Tree $folder.FullName
}
$files = Get-ChildItem -Path $Path -File -Force
ForEach ($file in $files)
{
Remove-Item $file.FullName -force
}
if (Test-Path "$Path\" -ErrorAction silentlycontinue)
{
Remove-Item $Path -force
}
}
}
لقد اتبعت نهجًا آخر مستوحى من @John -Rees أعلاه - خاصةً عندما بدأ نهجه في الفشل بالنسبة لي في مرحلة ما. تكرر بشكل أساسي الملفات الفرعية وفرز الملفات بطول المسار - حذف من الأطول إلى أقصر
Get-ChildItem $tfsLocalPath -Recurse | #Find all children
Select-Object FullName,@{Name='PathLength';Expression={($_.FullName.Length)}} | #Calculate the length of their path
Sort-Object PathLength -Descending | #sort by path length descending
%{ Get-Item -LiteralPath $_.FullName } |
Remove-Item -Force
فيما يتعلق بالسحر -المنزلي ، إليك مسكات أخرى قد تضربك: https://superuser.com/q/212808
حقا بسيطة:
remove-item -path <type in file or directory name>, press Enter
خدعة أخرى مفيدة:
إذا وجدت الكثير من الملفات ذات الاتفاقية ذات الاسم نفسه أو مشابه (مثل ملف MAC مع اسم بادئة DOT ... هذا سحب الملف الشهير) ، يمكنك بسهولة إزالتها بخط واحد من PowerShell مثل هذا:
ls -r .* | rm
سيقوم هذا الخط بإزالة جميع الملفات بنقطة في بداية الاسم داخل الدليل الحالي ، وجميع الملفات التي لها نفس الظروف داخل مجلدات أخرى داخل هذا الدليل أيضًا. كن على دراية به عند استخدامه. :د
يعمل حذف شجرة مجلد بأكملها في بعض الأحيان ويفشل في بعض الأحيان مع أخطاء "الدليل غير فارغ". بعد ذلك ، محاولة التحقق مما إذا كان المجلد لا يزال موجودًا يمكن أن يؤدي إلى "إمكانية الوصول" أو "الوصول غير المصرح به". لا أعرف لماذا يحدث هذا ، على الرغم من أنه قد يتم الحصول على بعض الأفكار هذا النشر stackoverflow.
لقد تمكنت من الالتفاف على هذه المشكلات من خلال تحديد الترتيب الذي يتم به حذف العناصر الموجودة داخل المجلد ، وإضافة التأخير. ما يلي يعمل بشكل جيد بالنسبة لي:
# First remove any files in the folder tree
Get-ChildItem -LiteralPath $FolderToDelete -Recurse -Force | Where-Object { -not ($_.psiscontainer) } | Remove-Item –Force
# Then remove any sub-folders (deepest ones first). The -Recurse switch may be needed despite the deepest items being deleted first.
ForEach ($Subfolder in Get-ChildItem -LiteralPath $FolderToDelete -Recurse -Force | Select-Object FullName, @{Name="Depth";Expression={($_.FullName -split "\\").Count}} | Sort-Object -Property @{Expression="Depth";Descending=$true}) { Remove-Item -LiteralPath $Subfolder.FullName -Recurse -Force }
# Then remove the folder itself. The -Recurse switch is sometimes needed despite the previous statements.
Remove-Item -LiteralPath $FolderToDelete -Recurse -Force
# Finally, give Windows some time to finish deleting the folder (try not to hurl)
Start-Sleep -Seconds 4
مقالة Microsoft Technet باستخدام الخصائص المحسوبة في PowerShell كان مفيدًا بالنسبة لي في الحصول على قائمة من اللاعبين الفرعيين الذين تم فرزهم بالعمق.
مشكلات موثوقية مماثلة مع RD /S /Q يمكن حلها عن طريق الجري RD /S /Q مرتين - من الناحية المثالية مع توقف بينهما (أي استخدام بينغ كما هو مبين أدناه).
RD /S /Q "C:\Some\Folder\to\Delete" > nul
if exist "C:\Some\Folder\to\Delete" ping -4 -n 4 127.0.0.1 > nul
if exist "C:\Some\Folder\to\Delete" RD /S /Q "C:\Some\Folder\to\Delete" > nul
لحذف المحتويات الكاملة بما في ذلك استخدام بنية المجلد
get-childitem $dest -recurse | foreach ($_) {remove-item $_.fullname -recurse}
ال -recurse
مضاف إلى remove-item
يضمن تعطيل المطالبات التفاعلية.
del <dir> -Recurse -Force # I prefer this, short & sweet
أو
remove-item <dir> -Recurse -Force
إذا كان لديك دليل ضخم ، فإن ما أفعله عادة هو
while (dir | where name -match <dir>) {write-host deleting; sleep -s 3}
قم بتشغيل هذا على محطة PowerShell أخرى وسيتوقف عند الانتهاء.
$users = get-childitem \\ServerName\c$\users\ | select -ExpandProperty name
foreach ($user in $users)
{
remove-item -path "\\Servername\c$\Users\$user\AppData\Local\Microsoft\Office365\PowerShell\*" -Force -Recurse
Write-Warning "$user Cleaned"
}
كتب ما سبق لتنظيف بعض ملفات تسجيل الدخول دون حذف الدليل الأصل وهذا يعمل بشكل مثالي!
rm -r <folder_name>
c:\>rm -r "my photos"