عندما تبدأ في كتابة نصوص PowerShell للمرة الأولى، ستصل في نهاية المطاف إلى مكان حيث ستحتاج إلى معالجة عدة عناصر من مجموعة. في هذا الوقت، ستحتاج إلى العمل على حلقات foreach في PowerShell وتعلم ماهيتها.
تقريبًا جميع لغات البرمجة لديها هيكل يسمى الحلقات؛ وPowerShell ليست استثناءً. واحدة من أنواع الحلقات الأكثر شيوعًا في PowerShell هي حلقة foreach. في أبسط حالاتها، تقرأ حلقة foreach مجموعة كاملة من العناصر وتقوم بتشغيل بعض نوع من الكود لكل عنصر.
واحدة من أكثر الجوانب الخلاطة لحلقة foreach في PowerShell للمبتدئين هي جميع الخيارات المتاحة. ليس هناك طريقة واحدة فقط لمعالجة كل عنصر في المجموعة؛ بل هناك ثلاثة!
في هذه المقالة، ستتعلم كيف تعمل كل نوع من حلقة foreach ومتى يجب استخدام أحدها على الآخر. بحلول نهاية هذه المقالة، ستكون لديك فهم جيد لكل نوع من حلقات foreach.
أساسيات حلقة ForEach في PowerShell
واحدة من أنواع الحلقات الأكثر شيوعًا التي ستستخدمها في PowerShell هي نوع حلقة foreach. تقوم حلقة foreach بقراءة مجموعة من الكائنات (تكرار) وتكتمل عندما تنتهي من الكائن الأخير. المجموعة من الكائنات التي يتم قراءتها عادة ما تكون ممثلة بمصفوفة أو جدول مفاتيح.
ملاحظة: مصطلح التكرار هو مصطلح برمجي يشير إلى كل تشغيلة لحلقة. في كل مرة يكتمل فيها الدورة لحلقة، يُعرف هذا بالتكرار. ويُشار عادة إلى تشغيل حلقة على مجموعة من الكائنات بأنه “التكرار على المجموعة”.
ربما تحتاج إلى إنشاء ملف نصي عبر بعض المجلدات المنتشرة عبر نظام الملفات. لنفترض أن مسارات المجلدات هي C:\Folder
، C:\Program Files\Folder2
و C:\Folder3
. بدون حلقة، سيكون علينا الإشارة إلى الأمر Add-Content
ثلاث مرات.
ما هو الفرق الوحيد بين كل من هذه الإشارات إلى الأمر؟ إنه قيمة Path
. القيمة المرتبطة بـ Path
هي القيمة الوحيدة التي تتغير بين كل من هذه الحالات.
أنت تكرر الكثير من الشفرة. أنت تضيع الوقت بالكتابة وتفتح نفسك للمشاكل فيما بعد. بدلاً من ذلك، يجب عليك إنشاء “مجموعة” تشمل جميع العناصر التي يتغير معها. لهذا المثال، سنستخدم مصفوفة.
الآن لديك كل هذه المسارات مخزنة في “مجموعة” أو مصفوفة واحدة. أنت الآن جاهز لاستخدام حلقة للتكرار عبر كل من هذه العناصر. قبل القيام بذلك، من الجيد أن نذكر موضوعًا يعترض غالبًا على الجدد في PowerShell. على عكس أنواع الحلقات الأخرى، حلقات الـ foreach
ليست جميعها متشابهة.
تقنياً، هناك ثلاثة أنواع من حلقات الـ foreach
في PowerShell. على الرغم من أن كل نوع مشابه في الاستخدام، فمن المهم فهم الفرق بينها.
البيان foreach
النوع الأول من حلقات الـ foreach
هو بيان. foreach
هو كلمة مفتاحية داخلية في PowerShell ليست cmdlet ولا دالة. يُستخدم بيان الـ foreach
دائمًا بهذا الشكل: foreach ($i in $array)
.
$i
المتغير يُمثل المكرر أو قيمة كل عنصر في $path
أثناء تكراره على كل عنصر في المصفوفة.
يرجى ملاحظة أن متغير المكرر لا يجب أن يكون
$i
. يمكن أن يكون اسم المتغير أي شيء آخر.
في المثال أدناه، يمكنك تحقيق نفس المهمة كتكرار لمرجع Add-Content
بفعل ذلك:
الـ foreach
بيان معروف بأنه بديل أسرع من استخدام ForEach-Object
الأمر.
أمر ForEach-Object
إذا كان foreach
بيان ويمكن استخدامه بطريقة واحدة فقط، فإن ForEach-Object
هو أمر يحمل معه معلمات يمكن استخدامها بطرق متعددة. مثل foreach
بيان، يمكن لأمر ForEach-Object
التكرار على مجموعة من الكائنات. لكن هذه المرة، يمرر مجموعة تلك الكائنات والإجراء الذي يجب اتخاذه على كل كائن كمعلمة كما هو موضح أدناه.
ملحوظة: لتعقيد الأمور، يحمل أمر
ForEach-Object
اسمًا بديلاً يسمىforeach
. اعتمادًا على كيفية استدعاء مصطلح “foreach”، يتم تشغيل الـforeach
بيان أو يتم تشغيلForEach-Object
.A good way to differentiate these situations is to notice if the term “foreach” is followed by
($someVariable in $someSet)
. Otherwise, in any other context, the code author is probably using the alias forForEach-Object
.
الطريقة foreach()
واحدة من أحدث حلقات الـ foreach
تم تقديمها في PowerShell v4 وتسمى طريقة foreach()
. توجد هذه الطريقة على كائن مصفوفة أو مجموعة. تحتوي طريقة foreach()
على معلمة كتلة نصية قياسية تحتوي على الإجراءات التي يجب أخذها خلال كل تكرار، تمامًا كما في الحالات الأخرى.
أكبر فارق مع طريقة foreach()
هو كيفية عملها تحت الغطاء.
استخدام طريقة
foreach()
هو أسرع بشكل كبير ويظهر ذلك بوضوح عند التعامل مع مجموعات كبيرة. من المفضل استخدام هذه الطريقة على الطرق الأخرى إذا كان ذلك ممكنًا.
مشروع صغير: التكرار عبر مجموعة من أسماء الخوادم
أحد أكثر الاستخدامات شيوعًا للحلقة في PowerShell هو قراءة مجموعة من الخوادم من مصدر ما والقيام ببعض الإجراءات على كل منها. لمشروعنا الصغير الأول، دعونا نبني بعض الشيفرة التي تسمح لنا بقراءة أسماء الخوادم (واحدة في كل سطر) من ملف نصي وعمل عملية ping على كل خادم لتحديد ما إذا كانوا متصلين أم لا.

بالنسبة لهذه السيناريو، أي نوع من الحلقات تعتقد أنه سيعمل بشكل أفضل؟
لاحظ أنني ذكرت كلمة “مجموعة” كما في “مجموعة من الخوادم”. هذا مؤشر هنا. لديك بالفعل عدد محدد من أسماء الخوادم، وترغب في القيام ببعض الإجراءات على كل منها. يبدو أن هذه هي فرصة رائعة لتجربة الحلقة الأكثر شيوعًا المستخدمة في PowerShell؛ حلقة foreach
.
المهمة الأولى هي إنشاء مجموعة من أسماء الخوادم في الشيفرة. وسيلة الأكثر شيوعًا للقيام بذلك هي عن طريق إنشاء مصفوفة. لدينا الحظ السعيد أن Get-Content
تعيد افتراضيًا مصفوفة مع كل عنصر في المصفوفة يُمثل بسطر واحد في ملف النص.
أولاً، قم بإنشاء مصفوفة تحتوي على جميع أسماء الخوادم وسمِّها $servers
.
الآن بعد أن قمت بإنشاء المصفوفة، ستحتاج الآن إلى تأكيد ما إذا كانت كل خادم متصل على الإنترنت أم لا. الأمر الرائع لاختبار اتصال الخادم هو الأمر المسمى Test-Connection
. يقوم هذا الأمر بإجراء بعض اختبارات الاتصال على جهاز الكمبيوتر لمعرفة ما إذا كان متصلاً أم لا.
عن طريق تنفيذ Test-Connection
داخل حلقة foreach
لقراءة كل سطر من الملف، يمكنك تمرير كل اسم خادم يُمثل بالمتغير $server
إلى Test-Connection
. هكذا يمكنك استخدام PowerShell لتكرار ملف نصي. يمكنك رؤية مثال على كيفية عمل ذلك أدناه.
عند تنفيذ حلقة foreach
، ستبدو الأمور على النحو التالي:

لقد اختبرت بنجاح اتصال ملف نصي مليء بأسماء الخوادم! في هذه المرحلة، يمكنك الآن إضافة أو إزالة أسماء الخوادم داخل ملف النص بمرونة دون تغيير في الشيفرة.
لقد قمت بتطبيق بنجاح ما كنا ندعو إليه، الطريقة DRY.
أمثلة PowerShell لحلقة ForEach
لنلقي نظرة على بعض الأمثلة حول كيفية استخدام حلقة ForEach. تستند هذه إلى حالات استخدام في العالم الحقيقي تظهر الفكرة التي يمكنك تعديلها لتناسب متطلباتك.
المثال 1: إنشاء ملف في كل مجلد فرعي في دليل باستخدام بيان ForEach
يوضح هذا المثال الاستخدام الشائع لحلقة التكرار في باورشيل على المجلد في الدليل.
لنفترض أن هناك عشرة مجلدات فرعية داخل مجلد C:\ARCHIVE_VOLUMES
. يمثل كل مجلد فرعي حجم أرشيف يتم نسخه يوميًا. بعد اكتمال كل نسخة احتياطية ، يتم إنشاء ملف يحمل اسم BackupState.txt
داخل كل مجلد يحتوي على التاريخ الذي تم فيه النسخة الاحتياطية.
يمكنك أن ترى مثالًا على كيفية ذلك أدناه.

يقوم النص أدناه بأربعة إجراءات:
- يحصل على قائمة جميع المجلدات الفرعية داخل
C:\ARCHIVE_VOLUMES
- يكرر كل مجلد
- ينشئ ملف نصي باسم
BackupState.txt
يحتوي على التاريخ والوقت الحالي كقيمة
يستخدم المثال أدناه بيان foreach
.
باستخدام cmdlet Get-ChildItem
، يمكنك تأكيد أن الملفات تم إنشاؤها أو تحديثها داخل كل من المجلدات الفرعية.
الصورة أدناه تُظهر نتيجة البرنامج عند عرض جميع ملفات BackupState.txt
الموجودة في كل مجلد فرعي.

مثال ٢: قراءة محتويات كل ملف نصي في المجلدات الفرعية
بعد ذلك، لتوضيح استخدام حلقة الـ PowerShell لكل ملف في دليل، سيقرأ البرنامج أدناه كل ملف BackupState.txt
الذي تم إنشاؤه في المثال ١.
- البحث بشكل متكرر عن جميع ملفات
BackupState.txt
داخل كل مجلد فرعي. - باستخدام تعليمة
foreach
، قراءة كل ملف نصي للحصول على قيمة “وقت النسخ الاحتياطي الأخير”. - عرض النتيجة على الشاشة.
بمجرد تنفيذ البرنامج في جلسة PowerShell الخاصة بك، يجب أن ترى نتيجة مماثلة للصورة أدناه. يظهر هذا أن حلقة PowerShell تمر عبر الملفات، وتقرأ المحتويات وتعرض النتيجة.

مثال ٣: الحصول على الخدمات وبدء تشغيلها باستخدام ForEach-Object CmdLet
غالبًا ما يحتاج مسؤولو النظام إلى الحصول على حالة الخدمات وتشغيل سير عمل يدوي أو تلقائي لإصلاح أي خدمات فشلت. دعنا نلقي نظرة على البرنامج النموذجي باستخدام تعليمة ForEach-Object
.
لهذا المثال، سيقوم البرنامج أدناه بما يلي:
- الحصول على قائمة الخدمات التي تم تكوينها للبدء التلقائي ولكنها غير مشغلة حاليًا.
- ثم، يتم تمرير العناصر في القائمة إلى cmdlet
ForEach-Object
لمحاولة بدء كل خدمة. - A message of either success or failed is displayed depending on the result of the
Start-Service
command.
عند تنفيذ النص البرمجي، سيظهر مخرجات مشابهة للشاشة أدناه. كما يمكنك أن ترى، تم إصدار أمر ببدء كل خدمة. بعضها تم بدؤها بنجاح في حين فشل بعضها في البدء.

المثال ٤: قراءة البيانات من CSV باستخدام طريقة ForEach()
استخدام البيانات من ملفات CSV شائع بين مسؤولي النظام. توضع السجلات داخل ملف CSV لجعل تشغيل العمليات الجماعية سهل باستخدام الجمع بين Import-CSV
و ForEach
. يستخدم هذا الجمع عادةً لـ إنشاء مستخدمين متعددين في Active Directory.
في المثال التالي، يفترض أن لديك ملف CSV يحتوي على عمودين – الاسم الأول و الاسم الأخير. يجب ثم ملء هذا الملف CSV بأسماء المستخدمين الجدد الذين يجب إنشاؤهم. يبدو ملف CSV مثل ما يلي.
الآن للكتلة البرمجية التالية. أولاً، استورد ملف CSV عن طريق تمرير مسار المحتوى إلى cmdlet Import-CSV
. ثم، باستخدام الطريقة foreach()
، قم بتكرار الأسماء وإنشاء مستخدمين جدد في Active Directory.
عند التشغيل، يجب أن يكون لديك الآن مستخدم AD مُنشأ لكل صف في ملف CSV!
ملخص
المنطق وراء حلقة foreach في PowerShell ليس مختلفًا عن ذلك في لغات البرمجة الأخرى. يتغير فقط باستخدامه واختيار نسخة من حلقة foreach لمهمة معينة.
في هذه المقالة، تعلمت أنواع الحلقات foreach المختلفة المتوفرة في PowerShell، وما يجب مراعاته لاختيار النوع المناسب للاستخدام. كما رأيت الأنواع الثلاثة من حلقات foreach في العمل باستخدام سيناريوهات عينية مختلفة.