إذا كنت تكتب نصوصًا بواسطة PowerShell التي تقوم بأي شيء معنوي، فإنك بحاجة إلى تسجيل. سواء كنت تقوم بنشر برنامج، أو إدارة خدمات، أو أتمتة المهام، فإن وجود سجل لما فعله النص الخاص بك (أو لم يفعل) أمر حاسم. في هذا البرنامج التعليمي، ستتعلم كيفية إنشاء وظيفة تسجيل PowerShell بسيطة وفعالة.
المتطلبات المسبقة
إذا كنت ترغب في متابعة هذا البرنامج التعليمي، تأكد من أن لديك:
- نظام Windows 10 أو Windows Server مع PowerShell 5.1 أو PowerShell 7+
- محرر نصوص (يُوصى باستخدام VSCode)
- فهم أساسي لوظائف PowerShell
المشكلة مع تسجيل البيانات الأساسي
فلنقل أنك تكتب نصًا لتثبيت بعض البرامج بصمت. قد تبدو الطريقة الأساسية كما يلي:
Add-Content -Path "C:\\Scripts\\install.log" -Value "Starting install..." Start-Process -FilePath 'installer.exe' -ArgumentList '/i /s' -Wait -NoNewWindow Add-Content -Path "C:\\Scripts\\install.log" -Value "Finished install."
هذا يعمل، ولكن به بعض المشاكل:
- لا يوجد الطوابع الزمنية
- رمز متكرر
- تنسيق تسجيل غير متسق
- مسار تسجيل مُشفر
دعونا نُصلح هذه المشكلات من خلال بناء وظيفة تسجيل مناسبة.
بناء وظيفة كتابة السجلات الأساسية
أولاً، دعنا ننشئ وظيفة بسيطة تضيف الطوابع الزمنية إلى إدخالات السجل الخاصة بنا:
function Write-Log { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$Message ) $timeGenerated = Get-Date -Format HH:mm:ss Add-Content -Path "C:\\Scripts\\script.log" -Value "$timeGenerated - $Message" }
الآن يمكنك استخدامها بهذه الطريقة:
Write-Log -Message "Starting install..." Start-Process -FilePath 'installer.exe' -ArgumentList '/i /s' -Wait -NoNewWindow Write-Log -Message "Finished install."
سيحتوي ملف السجل (C:\Scripts\script.log) على إدخالات تبدو مثل:
09:42:15 - Starting install... 09:43:22 - Finished install.
أنظف بكثير! ولكن يمكننا أن نفعل أفضل.
إضافة المزيد من الوظائف
لنعزز وظيفة تسجيلنا ببعض الميزات المفيدة:
- مسارات تسجيل مخصصة
- مستويات السجل المختلفة (معلومات، تحذير، خطأ)
- تاريخ في اسم الملف
- التعامل مع الأخطاء
إليك النسخة المحسنة:
function Write-Log { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Message, [Parameter()] [ValidateNotNullOrEmpty()] [string]$LogFilePath = "C:\\Scripts\\Logs", [Parameter()] [ValidateSet('Information','Warning','Error')] [string]$Level = "Information" ) # Create the log directory if it doesn't exist if (!(Test-Path $LogFilePath)) { New-Item -Path $LogFilePath -ItemType Directory -Force | Out-Null } # Build the log file path with date $date = Get-Date -Format "MM-dd-yyyy" $logFile = Join-Path $LogFilePath "log-$date.txt" # Get the current timestamp $timeStamp = Get-Date -Format "HH:mm:ss" # Create the log entry $logEntry = "$timeStamp [$Level] - $Message" try { Add-Content -Path $logFile -Value $logEntry -ErrorAction Stop } catch { Write-Error "Failed to write to log file: $_" } }
تمنحك هذه النسخة المعززة مزيدًا من المرونة. إليك كيفية استخدامها:
# Basic information logging Write-Log -Message "Starting software installation" # Warning about a non-critical issue Write-Log -Message "Config file not found, using defaults" -Level Warning # Log an error Write-Log -Message "Installation failed!" -Level Error # Use a custom log path Write-Log -Message "Custom path log" -LogFilePath "D:\\CustomLogs"
سيبدو ملف السجل الناتج (log-03-12-2024.txt) كالتالي:
10:15:22 [Information] - Starting software installation 10:15:23 [Warning] - Config file not found, using defaults 10:15:25 [Error] - Installation failed!
وفي D:\CustomLogs\log-03-12-2024.txt:
10:15:26 [Information] - Custom path log
لاحظ كيف يتضمن كل إدخال الطابع الزمني، مستوى السجل بين الأقواس، والرسالة. هذه الصيغة المنظمة تجعل من السهل تحليل السجلات وتحديد المشكلات بسرعة.
مثال من العالم الحقيقي: برنامج تثبيت البرمجيات
دعنا نستخدم وظيفة التسجيل لدينا في برنامج حقيقي يقوم بتثبيت البرمجيات بصمت:
# First, dot-source the logging function . .\\Write-Log.ps1 # Script variables $installer = "C:\\Installers\\software.exe" $logPath = "C:\\Scripts\\InstallLogs" # Start logging Write-Log -Message "Beginning installation process" -LogFilePath $logPath # Check if installer exists if (Test-Path $installer) { Write-Log -Message "Found installer at: $installer" try { # Attempt installation Write-Log -Message "Starting installation..." $process = Start-Process -FilePath $installer -ArgumentList '/i /s' -Wait -NoNewWindow -PassThru # Check the exit code if ($process.ExitCode -eq 0) { Write-Log -Message "Installation completed successfully" } else { Write-Log -Message "Installation failed with exit code: $($process.ExitCode)" -Level Error } } catch { Write-Log -Message "Installation failed with error: $_" -Level Error } } else { Write-Log -Message "Installer not found at: $installer" -Level Error } Write-Log -Message "Installation script completed"
سيبدو ملف السجل الناتج شيئًا مثل هذا:
09:15:22 [Information] - Beginning installation process 09:15:22 [Information] - Found installer at: C:\\Installers\\software.exe 09:15:22 [Information] - Starting installation... 09:16:45 [Information] - Installation completed successfully 09:16:45 [Information] - Installation script completed
نصائح مفيدة
إليك بعض الممارسات الجيدة عند استخدام هذه الوظيفة للتسجيل:
-
قم دائمًا بتسجيل بداية ونهاية البرنامج النصي الخاص بك – يساعد ذلك في تتبع وقت تنفيذ البرنامج النصي وحالة الانتهاء.
-
استخدم مستويات السجل المناسبة – لا تصنف كل شيء كخطأ؛ استخدم المستوى المناسب للموقف:
- معلومات: العمليات العادية
- تحذير: مشكلات غير حرجة
- خطأ: مشكلات حرجة تحتاج إلى اهتمام
-
تضمين التفاصيل ذات الصلة – سجل معلومات كافية لفهم ما حدث:
# سيء Write-Log "فشل الاتصال" # جيد Write-Log "فشل الاتصال بالخادم 'SQL01' - انتهاء الوقت بعد 30 ثانية" -Level Error
-
تنظيف السجلات القديمة – اعتبر إضافة تدوير للسجلات لمنع امتلاء مساحة القرص:
# حذف السجلات الأقدم من 30 يومًا Get-ChildItem -Path $LogFilePath -Filter "*.txt" | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } | Remove-Item
استنتاج
وظيفة تسجيل جيدة ضرورية لأي نص PowerShell جاد. مع وظيفة Write-Log
التي أنشأناها، لديك الآن طريقة مرنة وقابلة لإعادة الاستخدام لإضافة تسجيل صحيح إلى جميع نصوصك. تذكر أن تعدل الوظيفة وفقًا لاحتياجاتك المحددة – قد ترغب في إضافة ميزات مثل:
تدوير السجلات
function Write-Log { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Message, [Parameter()] [int]$MaxLogFiles = 30 # Keep last 30 days of logs ) # Remove old log files Get-ChildItem -Path $LogFilePath -Filter "*.txt" | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$MaxLogFiles) } | Remove-Item -Force # Continue with normal logging... }
أشكال إخراج مختلفة (CSV، JSON)
function Write-Log { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Message, [Parameter()] [ValidateSet('TXT','CSV','JSON')] [string]$Format = 'TXT' ) $logEntry = [PSCustomObject]@{ Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" Level = $Level Message = $Message } switch ($Format) { 'CSV' { $logEntry | Export-Csv -Path "$LogFilePath\\log.csv" -Append -NoTypeInformation } 'JSON' { $logEntry | ConvertTo-Json | Add-Content -Path "$LogFilePath\\log.json" } 'TXT' { "$($logEntry.Timestamp) [$($logEntry.Level)] - $($logEntry.Message)" | Add-Content -Path "$LogFilePath\\log.txt" } } }
دعم المسار الشبكي
function Write-Log { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Message, [Parameter()] [string]$NetworkPath = "\\\\server\\logs" ) # Test network path connectivity if (!(Test-Path $NetworkPath)) { # Fallback to local logging if network is unavailable $NetworkPath = "C:\\Scripts\\Logs" Write-Warning "Network path unavailable. Using local path: $NetworkPath" } # Continue with normal logging... }
إشعارات بريد إلكتروني للأخطاء
function Write-Log { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Message, [Parameter()] [string]$SmtpServer = "smtp.company.com", [Parameter()] [string[]]$NotifyOnError = "[email protected]" ) # Normal logging first... # Send email if this is an error if ($Level -eq 'Error' -and $NotifyOnError) { $emailParams = @{ From = "[email protected]" To = $NotifyOnError Subject = "PowerShell Script Error" Body = "Error occurred at $timeStamp`n`nMessage: $Message" SmtpServer = $SmtpServer } try { Send-MailMessage @emailParams } catch { Write-Warning "Failed to send error notification: $_" } } }
المفتاح هو البدء بأساس قوي والبناء من هناك بناءً على احتياجاتك المحددة. يجب أن تعطيك هذه الأمثلة نقطة انطلاق جيدة لتوسيع وظيفة التسجيل الأساسية مع ميزات أكثر تقدمًا.
على سبيل المثال، يمكنك دمج العديد من هذه الميزات في حل تسجيل شامل واحد:
Write-Log -Message "Critical error in payment processing" ` -Level Error ` -Format CSV ` -NetworkPath "\\\\server\\logs" ` -NotifyOnError "[email protected]","[email protected]" ` -MaxLogFiles 90
سيقوم هذا ب:
- تسجيل الخطأ بتنسيق CSV
- تخزينه على مشاركة شبكية
- إرساله إلى عدة مستلمين عبر البريد الإلكتروني
- الاحتفاظ بتاريخ تسجيل لمدة 90 يومًا
تذكر أن تقوم بإجراء اختبار شامل، خاصة عند تنفيذ مسارات الشبكة أو إشعارات البريد الإلكتروني، حيث يمكن أن تؤثر هذه التبعيات الخارجية على موثوقية سيناريو البرنامج الخاص بك. نتمنى لك تجربة سعيدة!
Source:
https://adamtheautomator.com/powershell-write-log-tutorial/