كيفية إدارة مقابض الملفات المفتوحة باستخدام PowerShell

أحد الأخطاء الأكثر إحباطًا التي يمكن للمستخدم النهائي أو مسؤول تكنولوجيا المعلومات التعامل معها هو خطأ الملفات المقفلة داخل Windows. عندما تقوم بحذف مجلد أو نقل ملف أو تحرير تكوين وتواجه رسالة خطأ ملف مقفل، فمن الأفضل التعامل مع ذلك بسرعة وكفاءة.




قدمت Microsoft PowerShell كواجهة بديلة، ولكنها تحتوي على وظائف أكثر بكثير من ذلك وهي لغة معقدة وقادرة. دعونا نلقي نظرة في هذه المقالة على كيفية استخدام PowerShell للتعامل مع الملفات المقفلة.


مشكلة الملف المقفل

كيف يتم قفل الملف بالضبط؟ أثناء الاستخدام العادي، تقوم العملية بإنشاء العديد من المقابض للموارد مثل الملف. ومن خلال القيام بذلك، غالبًا ما تقوم العمليات بقفل الملف لمنع حدوث تغييرات غير مقصودة في التكوين أو أي تلف آخر. المشكلة غالبًا هي أنه من الصعب تحديد العملية التي قامت بتأمين الملف، ومن ثم كيفية إزالة هذا القفل من الملف.

لسوء الحظ، لا يوجد أمر cmdlet مضمن لاختبار الملف ومعرفة ما إذا كان مقفلاً أو بأي عملية. لذلك، تحتاج إلى إنشاء وظائفك الخاصة أو تغليف الأدوات المفيدة الأخرى الموجودة للمساعدة في اكتشاف المزيد حول هذه الملفات.


اختبار الملفات المقفلة

في نظام التشغيل Windows، يمكنك الاختبار لمعرفة ما إذا كان الملف الفردي مقفلاً أم لا. باستخدام كتلة التعليمات البرمجية التالية، يمكنك اختبار لمعرفة ما إذا كان ملف معين مقفلاً. ال

$Item 

يجب تعيين المتغير على مسار الملف الكامل. عن طريق الاختبار لمعرفة ما إذا كان يمكن فتح الملف للكتابة، كما رأينا مع ملف

(System.IO.File)::Open($Item,'Open','Write') 

الأمر، يمكنك معرفة ما إذا كان الملف مقفلاً.

If ((System.IO.File)::Exists($Item)) {
  Try {
      $FileStream = (System.IO.File)::Open($Item,'Open','Write')

      $FileStream.Close()
      $FileStream.Dispose()

      $IsLocked = $False
  } Catch (System.UnauthorizedAccessException) {
      $IsLocked = 'AccessDenied'
  } Catch {
      $IsLocked = $True
  }
}

الحصول على SMBOpenFile

لقد قلت أن نظام التشغيل Windows لا يحتوي على وظيفة مضمنة، ولكن هناك حالة واحدة توجد بها وظيفة. إذا كان لديك مشاركة عن بعد أو حتى مشاركات إدارية (مثل c$)، ثم يمكنك استخدام Get-SMBOpenFile cmdlet للإبلاغ عن تلك الملفات المفتوحة.

PS C:> Get-SMBOpenFile

FileId SessionId Path ShareRelativePath
154618822665 154618822657 C:

PS C:>

الجانب السلبي هو أن هذا يعمل فقط مع الملفات التي يتم الوصول إليها عن بعد. لن يتم الإبلاغ عن أي ملفات مقفلة قيد الاستخدام على نظامك المحلي، لذلك لا يعد هذا حلاً قابلاً للتطبيق في معظم الحالات. للإغلاق، يمكنك توجيه الملفات المفتوحة التي تم إرجاعها إلى ملف Close-SMBOpenFile يأمر.

Get-SMBOpenFile | Close-SMBOpenFile


الأداة المساعدة للملفات المفتوحة

يحتوي Windows على أداة مساعدة مضمنة تسمى openfiles يمكن أن يساعد ذلك في سرد ​​الملفات المستخدمة وفصلها. للوهلة الأولى، يبدو مثاليًا لاحتياجاتك! يمكنك أيضًا تغليف هذا ضمن وظيفة PowerShell لتسهيل الاستعلام عن الملفات وفصلها.

افتح موجه PowerShell الإداري وقم بتشغيل الأمر openfiles /query. من المفترض أن تتلقى على الفور رسالة خطأ تفيد بضرورة تشغيل العلامة العامة “لقائمة الكائنات المحافظة”.

PS C:/> openfiles /query

INFO: The system global flag 'maintain objects list' needs
      to be enabled to see local opened files.
      See Openfiles /? for more information.

Files opened remotely via local share points:

INFO: No shared open files found.

قائمة الكائنات هذه هي التي تحافظ بالفعل على قائمة المقابض المستخدمة والتمكينية openfiles للاستعلام عن تلك المعلومات. لتشغيل هذا، أدخل openfiles /local on ثم قم بإعادة تشغيل جهاز الكمبيوتر الخاص بك. الجانب السلبي لتشغيل هذه الميزة هو أن هناك انخفاضًا طفيفًا في الأداء، والذي قد لا يستحق فائدة استخدام هذه الأداة، اعتمادًا على نظامك. ومع ذلك، دعونا نرى كيف يمكننا أن نجعل هذا العمل ضمن PowerShell.


PS C:> openfiles /Query /fo csv /nh

Files opened remotely via local share points:
"ID","Accessed By","Type","Open File (Pathexecutable)"
"608","user","Windows","C:"

PS C:> openfiles /Query /fo csv | Select-Object -Skip 4 | ConvertFrom-CSV

ID Accessed By Type Open File (Pathexecutable)
608 user Windows C:

PS C:> openfiles /disconnect /id 608

SUCCESS: The connection to the open file "C:" has been terminated.

باستخدام الأمثلة السابقة، يمكنك معرفة كيفية استيراد مخرجات ملف CSV openfiles في باورشيل. باستخدام هذه المعلومات، يمكنك بعد ذلك disconnect ملف لفتحه. نظرًا لنتائج الأداء التي قد تتحملها عند تمكين maintain objects list القدرة، قد لا يكون من المفيد لاحتياجاتك. ولهذا السبب، قد تكون هناك حاجة إلى حلول أخرى.

تطبيق المقبض

تشتهر Sysinternals بالعديد من أدوات تكنولوجيا المعلومات المفيدة والأكثر أهمية التي تصنعها. منذ بعض الوقت، استحوذت شركة Microsoft على Sysinternals، ويمكنك تنزيل هذه الأدوات المدعومة جيدًا واستخدامها بنفسك. من الملائم أن يكون هناك تطبيق اسمه handles الذي يوفر بالضبط ما تبحث عنه!

أولا، عليك أن تحميل التطبيق، وقم بفك ضغط الملفات، ووضع الملفات التنفيذية في موقع يتضمنه متغير المسار البيئي الخاص بك. ومن خلال القيام بذلك، يمكنك بسهولة الرجوع إلى التطبيق أينما كنت في حاجة إليه. باستخدام استعلام بسيط للملفات المفتوحة، يمكنك أن ترى أنك تحصل على الكثير من النتائج (يتم اقتطاعها لسهولة القراءة).


PS C:/> handle64 -NoBanner
...
RuntimeBroker.exe pid: 9860 User
   48: FileC:WindowsSystem32
  188: Section BaseNamedObjects__ComCatalogCache__
  1EC: Section BaseNamedObjects__ComCatalogCache__
chrome.exe pid: 4628 User
   78: FileC:Program Files (x86)GoogleChromeApplication78.0.3904.108
  1C4: Section Sessions1BaseNamedObjectswindows_shell_global_counters
...

يبدو أنك حصلت على ما تريد — على الأقل طريقة لمعرفة الملفات المستخدمة — ويمكنك اختبارها باستخدام رمز قفل الملف الخاص بك من قبل. ولكن كيف تجعل هذا أسهل في الاستخدام؟ يقرأ التعليمة البرمجية التالية كل عملية ويسترد الملفات المقفلة فقط. الجانب السلبي هو أن هذا يستغرق بعض الوقت للتشغيل نظرًا لوجود العديد من العمليات.

$Processes = Get-Process

$results = $Processes | Foreach-Object {
    $handles = (handle64 -p $_.ID -NoBanner) | Where-Object { $_ -Match " File " } | Foreach-Object {
            (PSCustomObject)@{
        "Hex" = ((($_ -Split " ").Where({ $_ -NE "" })(0)).Split(":")(0)).Trim()
        "File" = (($_ -Split " ")(-1)).Trim()
        }
    }

    If ( $handles ) {
        (PSCustomObject)@{
            "Name" = $_.Name
            "PID" = $_.ID
            "Handles" = $handles
        }
    }
}

ومع ذلك، فإن ما تحصل عليه في النهاية هو مجموعة من الملفات القابلة للتنفيذ، والمدرجة حسب العملية، والتي تعرف أنها قيد الاستخدام ويمكن تصفيتها بشكل أكبر. إذا اكتشفت أنك بحاجة إلى إغلاق أحدها، فيمكنك القيام بما يلي (كمسؤول):

PS C:> $results |
>> Where-Object Name -EQ 'Notepad' |
>> Where-Object { $_.Handles.File -Match "test.txt" }

Name PID Handles
Notepad 12028 {@{Hex=44; File=C:test.txt}

PS C:> handle64 -p 12028 -c 44 -y -nobanner

44: File (R-D) C:test.txt

Handle closed.

يمكنك أيضًا تغليف كل هذا في دالة لتسهيل التحليل والبحث حسب الضرورة. توجد العديد من الاحتمالات، خاصة في الجمع بين الطرق المختلفة في حل يناسب بيئتك.


خاتمة

يمكن أن يمثل التعامل مع الملفات المقفلة تحديًا، خاصة عندما يوقف ما تحتاج إلى إنجازه بسرعة. هناك عدد من الطرق للعثور على هذه الملفات وفتحها، ولكنها تتطلب القليل من العمل لأن Windows ليس لديه طريقة مدمجة وشاملة حقًا للتعامل مع تلك الملفات المقفلة. يجب أن تختصر الحلول الموضحة مهما كانت المشكلة وتتيح لك الانتقال إلى مهام أكثر أهمية بكثير!

(العلامات للترجمة)مايكروسوفت

أضف تعليق