Event Log Management PowerShell Script
Event Log Management PowerShell Script
Table of Contents
1. PowerShell Practical Assessment 1
2. PowerShell Practical Assessment 2
3. Milestone Assessment PowerShell 1
4. Milestone Assessment PowerShell 2
5. PowerShell Practical Assessment 3
6. Advanced PowerShell Assessment
7. Calculator Menu Assessment
8. PowerShell Weekly Assessment
switch ($Choice) {
1 { $EventType = "Error" }
2 { $EventType = "Information" }
3 { $EventType = "Warning" }
default {
Write-Error "Invalid choice"
exit
}
}
if ($Events) {
Write-Host "Found $($[Link]) matching events:" -ForegroundColor Green
$Events | Select-Object TimeCreated, Id, LevelDisplayName, Message | Format-Table -Au
} else {
Write-Host "No matching events found." -ForegroundColor Red
}
function Convert-CelsiusToFahrenheit {
param([double]$Celsius)
return ($Celsius * 9/5) + 32
}
function Convert-FahrenheitToCelsius {
param([double]$Fahrenheit)
return ($Fahrenheit - 32) * 5/9
}
do {
Show-Menu
$Choice = Read-Host "Enter your choice (1-3)"
switch ($Choice) {
1 {
$Celsius = [double](Read-Host "Enter temperature in Celsius")
$Fahrenheit = Convert-CelsiusToFahrenheit -Celsius $Celsius
Write-Host "$Celsius°C = $([math]::Round($Fahrenheit, 2))°F" -ForegroundColor
Read-Host "Press Enter to continue"
}
2 {
$Fahrenheit = [double](Read-Host "Enter temperature in Fahrenheit")
$Celsius = Convert-FahrenheitToCelsius -Fahrenheit $Fahrenheit
Write-Host "$Fahrenheit°F = $([math]::Round($Celsius, 2))°C" -ForegroundColor
Read-Host "Press Enter to continue"
}
3 {
Write-Host "Goodbye!" -ForegroundColor Green
break
}
default {
Write-Host "Invalid choice. Please try again." -ForegroundColor Red
Start-Sleep 2
}
}
} while ($Choice -ne 3)
try {
Get-ADOrganizationalUnit -Identity $OUPath -ErrorAction Stop
Write-Host "OU $OUName already exists." -ForegroundColor Yellow
}
catch {
New-ADOrganizationalUnit -Name $OUName -Path "DC=yourdomain,DC=com"
Write-Host "OU $OUName created successfully." -ForegroundColor Green
}
# Create username
$Username = ($[Link](0,1) + $LastName).ToLower()
# Create AD User
$UserParams = @{
Name = "$FirstName $LastName"
GivenName = $FirstName
Surname = $LastName
DisplayName = $DisplayName
SamAccountName = $Username
UserPrincipalName = "$Username@[Link]"
Path = $OUPath
AccountPassword = $Password
ChangePasswordAtLogon = ($ChangePasswordAtNextLogon -eq 'Y')
Enabled = ($AccountEnabled -eq 'Y')
}
try {
New-ADUser @UserParams
Write-Host "User $Username created successfully in $OUName OU." -ForegroundColor Gree
}
catch {
Write-Error "Failed to create user: $($_.[Link])"
}
$OUPath = "OU=CISPSTraining,DC=yourdomain,DC=com"
# Create AD Group
try {
New-ADGroup -Name $GroupName -GroupScope $GroupScope -Path $OUPath
Write-Host "Group $GroupName created successfully." -ForegroundColor Green
}
catch {
Write-Error "Failed to create group: $($_.[Link])"
exit
}
# Create directories
if (-not (Test-Path $MainFolder)) {
New-Item -Path $MainFolder -ItemType Directory -Force
Write-Host "Created main folder: $MainFolder" -ForegroundColor Green
}
try {
$ACL = Get-Acl $Path
$AccessRule = New-Object [Link]($Grou
$[Link]($AccessRule)
Set-Acl -Path $Path -AclObject $ACL
Write-Host "Set $Permission permission for $Group on $Path" -ForegroundColor Gree
}
catch {
Write-Error "Failed to set permission: $($_.[Link])"
}
}
# Apply permissions
Set-NTFSPermission -Path "$MainFolder\HR" -Group "HRGroup" -Permission "FullControl"
Set-NTFSPermission -Path "$MainFolder\IT" -Group "ITGroup" -Permission "Modify"
Set-NTFSPermission -Path "$MainFolder\Sales" -Group "SalesGroup" -Permission "Read"
$UserParams = @{
Name = "$($[Link]) $($[Link])"
GivenName = $[Link]
Surname = $[Link]
SamAccountName = $[Link]
UserPrincipalName = "$($[Link])@[Link]"
Department = $[Link]
AccountPassword = $SecurePassword
Enabled = $true
ChangePasswordAtLogon = $true
}
try {
New-ADUser @UserParams
Add-ADGroupMember -Identity $GroupName -Members $[Link]
Write-Host "User $($[Link]) created and added to $GroupName" -Foregrou
Write-Host "Password: $Password" -ForegroundColor Cyan
}
catch {
Write-Error "Failed to process user $($[Link]): $($_.[Link]
}
}
}
catch {
Write-Error "Error processing CSV: $($_.[Link])"
}
# Export to CSV
$ReportPath = "SystemInfo_$(Get-Date -Format 'yyyyMMdd_HHmm').csv"
$SystemReport | Export-Csv -Path $ReportPath -NoTypeInformation
Write-Host "Report exported to: $ReportPath" -ForegroundColor Green
# Create subdirectories
foreach ($Folder in $SubFolders) {
$FolderPath = Join-Path $MainPath $Folder
if (-not (Test-Path $FolderPath)) {
New-Item -Path $FolderPath -ItemType Directory -Force
Write-Host "Created: $FolderPath" -ForegroundColor Green
}
}
# Display results
if ($[Link] -gt 0) {
Write-Host "`nDrives with more than $MinFreeSpaceGB GB free space:" -ForegroundColor
$DrivesWithSpace | Format-Table -AutoSize
# Export results
$ExportPath = "DriveSpace_$(Get-Date -Format 'yyyyMMdd_HHmm').csv"
$DrivesWithSpace | Export-Csv -Path $ExportPath -NoTypeInformation
Write-Host "Results exported to: $ExportPath" -ForegroundColor Green
# Create FinanceDept OU
$OUName = "FinanceDept"
$OUPath = "OU=$OUName,DC=yourdomain,DC=com"
$DomainPath = "DC=yourdomain,DC=com"
try {
Get-ADOrganizationalUnit -Identity $OUPath -ErrorAction Stop
Write-Host "OU $OUName already exists." -ForegroundColor Yellow
}
catch {
New-ADOrganizationalUnit -Name $OUName -Path $DomainPath
Write-Host "Created OU: $OUName" -ForegroundColor Green
}
Write-Host "Searching for Event ID 4625 (Failed Logins) from $StartTime to $EndTime" -For
try {
# Query for failed login attempts (Event ID 4625)
$FailedLogins = Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 4625
StartTime = $StartTime
EndTime = $EndTime
} -ErrorAction SilentlyContinue
if ($FailedLogins) {
Write-Host "Found $($[Link]) failed login attempts in the last 24 hou
[PSCustomObject]@{
'Time' = $[Link]
'User' = if ($TargetUserName) { "$TargetDomainName\$TargetUserName" } els
'Workstation' = $WorkstationName
'Source IP' = $IpAddress
'Logon Type' = $LogonType
'Event ID' = $[Link]
}
}
# Display results
$Results | Sort-Object Time -Descending | Format-Table -AutoSize
# Export to CSV
$ExportPath = "FailedLogins_$(Get-Date -Format 'yyyyMMdd_HHmm').csv"
$Results | Export-Csv -Path $ExportPath -NoTypeInformation
Write-Host "Results exported to: $ExportPath" -ForegroundColor Green
# Summary statistics
Write-Host "`nSummary:" -ForegroundColor Yellow
Write-Host "Total failed logins: $($[Link])"
Write-Host "Unique users: $(($Results | Group-Object User).Count)"
Write-Host "Unique workstations: $(($Results | Where-Object {$_.Workstation -ne '
} else {
Write-Host "No failed login attempts found in the last 24 hours." -ForegroundColo
}
}
catch {
Write-Error "Error querying Security log: $($_.[Link])"
Write-Host "Note: You may need to run this script as Administrator to access Security
}
Write-Host "========================================="
Write-Host "Daily Backup Script Started at `$Date"
Write-Host "========================================="
# Example backup operations
try {
# Add your actual backup commands here
Write-Host "Backing up user documents..."
# robocopy "C:\Users" "D:\Backup\Users" /MIR /R:3 /W:10 /LOG+:C:\Scripts\RobocopyLog.
Stop-Transcript
"@
$BackupScript | Out-File -FilePath $ScriptPath -Encoding UTF8
Write-Host "Created backup script: $ScriptPath" -ForegroundColor Green
}
function Manage-Services {
Write-Host "`n=== Service Management ===" -ForegroundColor Yellow
$ServiceChoice = Read-Host "Enter service name to check (or 'list' for all services)"
if ($Service) {
Write-Host "Service: $($[Link])" -ForegroundColor Cyan
Write-Host "Status: $($[Link])" -ForegroundColor $(if($[Link]
Write-Host "Start Type: $($[Link])" -ForegroundColor Yellow
function Manage-Processes {
Write-Host "`n=== Process Management ===" -ForegroundColor Yellow
$ProcessChoice = Read-Host "Enter process name to check (or 'top' for top CPU process
if ($Processes) {
Write-Host "Found $($[Link]) process(es) named '$ProcessChoice':" -F
$Processes | Select-Object Name, Id, CPU, @{Name='Memory(MB)';Expression={[ma
if ($[Link] -eq 1) {
$KillProcess = Read-Host "Kill this process? (Y/N)"
if ($[Link]() -eq 'Y') {
try {
Stop-Process -Id $Processes[0].Id -Force
Write-Host "Process terminated successfully!" -ForegroundColor Gr
}
catch {
Write-Error "Failed to terminate process: $($_.[Link])
}
}
}
}
else {
Write-Host "No processes found with name '$ProcessChoice'." -ForegroundColor
}
}
}
function Get-SystemInfo {
Write-Host "`n=== System Information ===" -ForegroundColor Yellow
[PSCustomObject]@{
'Computer Name' = $[Link]
'OS' = $[Link]
'Version' = $[Link]
'Architecture' = $[Link]
'Total Memory (GB)' = [math]::Round($[Link]/1GB, 2)
'CPU' = $[Link]
'CPU Cores' = $[Link]
'Last Boot' = $[Link]
'Uptime (Days)' = [math]::Round((New-TimeSpan -Start $[Link] -End (Get
} | Format-List
}
# Processor Information
Write-Host "Processor Information:" -ForegroundColor Cyan
$ProcessorInfo = Get-CimInstance -ClassName Win32_Processor | Select-Object -First 1
[PSCustomObject]@{
'Processor' = $[Link]
'Cores' = $[Link]
'Logical Processors' = $[Link]
'Max Clock Speed (MHz)' = $[Link]
'Architecture' = switch ($[Link]) {
0 { 'x86' }
1 { 'MIPS' }
2 { 'Alpha' }
3 { 'PowerPC' }
6 { 'Intel Itanium' }
9 { 'x64' }
default { 'Unknown' }
}
} | Format-List
# Disk Information
Write-Host "Disk Information:" -ForegroundColor Cyan
Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object {$_.DriveType -eq 3} |
Select-Object DeviceID,
@{Name='Size (GB)';Expression={[math]::Round($_.Size/1GB, 2)}},
@{Name='Free Space (GB)';Expression={[math]::Round($_.FreeSpace/1GB, 2)}},
@{Name='% Free';Expression={[math]::Round(($_.FreeSpace/$_.Size)*100, 1)}},
VolumeName | Format-Table -AutoSize
function Get-Numbers {
do {
try {
$Num1 = [double](Read-Host "Enter first number")
$ValidNum1 = $true
}
catch {
Write-Host "Invalid input. Please enter a valid number." -ForegroundColor Red
$ValidNum1 = $false
}
} while (-not $ValidNum1)
do {
try {
$Num2 = [double](Read-Host "Enter second number")
$ValidNum2 = $true
}
catch {
Write-Host "Invalid input. Please enter a valid number." -ForegroundColor Red
$ValidNum2 = $false
}
} while (-not $ValidNum2)
function Perform-Addition {
param($Num1, $Num2)
$Result = $Num1 + $Num2
Write-Host "$Num1 + $Num2 = $Result" -ForegroundColor Green
return $Result
}
function Perform-Subtraction {
param($Num1, $Num2)
$Result = $Num1 - $Num2
Write-Host "$Num1 - $Num2 = $Result" -ForegroundColor Green
return $Result
}
function Perform-Division {
param($Num1, $Num2)
if ($Num2 -eq 0) {
Write-Host "Error: Division by zero is not allowed!" -ForegroundColor Red
return $null
}
else {
$Result = $Num1 / $Num2
Write-Host "$Num1 ÷ $Num2 = $Result" -ForegroundColor Green
return $Result
}
}
function Perform-Multiplication {
param($Num1, $Num2)
$Result = $Num1 * $Num2
Write-Host "$Num1 × $Num2 = $Result" -ForegroundColor Green
return $Result
}
do {
Show-CalculatorMenu
do {
$Choice = Read-Host "Enter your choice (1-5)"
$ValidChoice = $Choice -match '^[1-5]$'
if (-not $ValidChoice) {
Write-Host "Invalid choice. Please enter a number between 1 and 5." -Foregrou
}
} while (-not $ValidChoice)
switch ($Choice) {
'1' {
Write-Host "`nAddition Selected" -ForegroundColor Yellow
$Num1, $Num2 = Get-Numbers
$Result = Perform-Addition -Num1 $Num1 -Num2 $Num2
$CalculationHistory += [PSCustomObject]@{
'Operation' = 'Addition'
'Expression' = "$Num1 + $Num2"
'Result' = $Result
'Timestamp' = Get-Date
}
}
'2' {
Write-Host "`nSubtraction Selected" -ForegroundColor Yellow
$Num1, $Num2 = Get-Numbers
$Result = Perform-Subtraction -Num1 $Num1 -Num2 $Num2
$CalculationHistory += [PSCustomObject]@{
'Operation' = 'Subtraction'
'Expression' = "$Num1 - $Num2"
'Result' = $Result
'Timestamp' = Get-Date
}
}
'3' {
Write-Host "`nDivision Selected" -ForegroundColor Yellow
$Num1, $Num2 = Get-Numbers
$Result = Perform-Division -Num1 $Num1 -Num2 $Num2
if ($Result -ne $null) {
$CalculationHistory += [PSCustomObject]@{
'Operation' = 'Division'
'Expression' = "$Num1 ÷ $Num2"
'Result' = $Result
'Timestamp' = Get-Date
}
}
}
'4' {
Write-Host "`nMultiplication Selected" -ForegroundColor Yellow
$Num1, $Num2 = Get-Numbers
$Result = Perform-Multiplication -Num1 $Num1 -Num2 $Num2
$CalculationHistory += [PSCustomObject]@{
'Operation' = 'Multiplication'
'Expression' = "$Num1 × $Num2"
'Result' = $Result
'Timestamp' = Get-Date
}
}
'5' {
# Show calculation history before exiting
if ($[Link] -gt 0) {
Write-Host "`nCalculation History:" -ForegroundColor Yellow
$CalculationHistory | Format-Table -AutoSize
return $SamAccount
}
try {
Get-ADOrganizationalUnit -Identity $OUPath -ErrorAction Stop
Write-Host "OU $OUName already exists." -ForegroundColor Yellow
}
catch {
New-ADOrganizationalUnit -Name $OUName -Path $DomainPath
Write-Host "Created OU: $OUName" -ForegroundColor Green
}
$PasswordValid = $true
$ValidationMessage = ""
if ($[Link] -lt 8) {
$PasswordValid = $false
$ValidationMessage += "Password must be at least 8 characters. "
}
if (-not $PasswordValid) {
Write-Host $ValidationMessage -ForegroundColor Red
}
# Create AD User
$UserParams = @{
Name = $DisplayName
GivenName = $FirstName
Surname = $LastName
DisplayName = $DisplayName
SamAccountName = $SamAccountName
UserPrincipalName = "$SamAccountName@[Link]"
Department = $Department
Title = $Title
Path = $OUPath
AccountPassword = $Password
Enabled = $true
ChangePasswordAtLogon = $false
PasswordNeverExpires = $false
CannotChangePassword = $false
}
try {
New-ADUser @UserParams
Write-Host "User created successfully!" -ForegroundColor Green
# Export to CSV
$ExportPath = "NewUser_$SamAccountName`_$(Get-Date -Format 'yyyyMMdd_HHmm').csv"
$UserReport | Export-Csv -Path $ExportPath -NoTypeInformation
Write-Host "User details exported to: $ExportPath" -ForegroundColor Green
}
catch {
Write-Error "Failed to create user: $($_.[Link])"
}
# Test connectivity
Write-Log "Testing connectivity to $ComputerName..."
try {
$PingResult = Test-Connection -ComputerName $ComputerName -Count 2 -Quiet
if ($PingResult) {
Write-Log "Server $ComputerName is reachable" "SUCCESS"
} else {
Write-Log "Server $ComputerName is not reachable" "ERROR"
Write-Log "Health check terminated due to connectivity issues" "ERROR"
return
}
}
catch {
Write-Log "Error testing connectivity: $($_.[Link])" "ERROR"
return
}
if ($Services) {
Write-Log "Found $($[Link]) stopped services:" "WARNING"
foreach ($Service in $Services) {
Write-Log " - $($[Link]): $($[Link])" "WARNING"
}
} else {
Write-Log "All services are running" "SUCCESS"
}
}
catch {
Write-Log "Error retrieving services: $($_.[Link])" "ERROR"
}
if ($Credential) {
$HighCPUProcesses = Invoke-Command -ComputerName $ComputerName -ScriptBlock $Proc
} else {
$HighCPUProcesses = Invoke-Command -ComputerName $ComputerName -ScriptBlock $Proc
}
if ($HighCPUProcesses) {
Write-Log "Found $($[Link]) processes with high CPU usage:" "WARN
foreach ($Process in $HighCPUProcesses) {
Write-Log " - $($[Link]) (PID: $($[Link])): CPU=$($[Link]), M
}
} else {
Write-Log "No processes found with CPU usage >10%" "SUCCESS"
}
}
catch {
Write-Log "Error retrieving process information: $($_.[Link])" "ERROR"
}
[PSCustomObject]@{
ComputerName = $[Link]
OS = $[Link]
TotalMemoryGB = [math]::Round($[Link]/1GB, 2)
FreeMemoryGB = [math]::Round($[Link]/1KB/1MB, 2)
CPUName = $[Link]
LastBootTime = $[Link]
UptimeHours = [math]::Round((New-TimeSpan -Start $[Link] -End (Get
Disks = $Disk | Select-Object DeviceID, @{Name='SizeGB';Expression={[math]::R
}
}
if ($Credential) {
$SystemInfo = Invoke-Command -ComputerName $ComputerName -ScriptBlock $SystemInfo
} else {
$SystemInfo = Invoke-Command -ComputerName $ComputerName -ScriptBlock $SystemInfo
}
# Summary
Write-Log "Health check completed for server: $ComputerName" "SUCCESS"
Write-Log "Log file saved as: $LogFileName" "SUCCESS"
Write-Host "`nHealth check completed. Log saved to: $LogFileName" -ForegroundColor Green
Write-Host "Opening log file..." -ForegroundColor Yellow
notepad $LogPath
try {
# Query WMI for last boot time
Write-Host "`nQuerying WMI for system boot information..." -ForegroundColor Cyan
# Calculate uptime
$Uptime = New-TimeSpan -Start $LastBootTime -End $CurrentTime
$UptimeHours = [math]::Round($[Link], 2)
if ($BootEvents) {
Write-Host "Found $($[Link]) boot-related events:"
$BootEvents | Sort-Object TimeCreated | ForEach-Object {
$EventMessage = switch ($_.Id) {
6005 { "Event Log Service Started" }
6006 { "Event Log Service Stopped" }
6009 { "System Boot Detected" }
6013 { "System Uptime Information" }
default { $_.LevelDisplayName }
}
Write-Host " $($_.[Link]('HH:mm:ss')): $EventMessage"
}
} else {
Write-Host "No boot events found in the specified timeframe."
}
}
catch {
Write-Warning "Could not retrieve boot events: $($_.[Link])"
}
# Uptime recommendations
Write-Host "`n=== Uptime Recommendations ===" -ForegroundColor Yellow
# Export report
$ReportPath = "BootAnalysis_$(Get-Date -Format 'yyyyMMdd_HHmm').csv"
$BootReport | Export-Csv -Path $ReportPath -NoTypeInformation
Write-Host "Boot analysis report exported to: $ReportPath" -ForegroundColor Green
}
catch {
Write-Error "Error during boot time analysis: $($_.[Link])"
}
finally {
# Stop transcript
Write-Host "`nStopping transcript..." -ForegroundColor Yellow
Stop-Transcript
Write-Host "Transcript saved to: $TranscriptPath" -ForegroundColor Green
function Get-ValidNumber {
param([string]$Prompt)
do {
try {
$Input = Read-Host $Prompt
if ([string]::IsNullOrWhiteSpace($Input)) {
throw "Input cannot be empty"
}
$Number = [double]$Input
return $Number
}
catch {
Write-Host "❌ Invalid input. Please enter a valid number." -ForegroundColor R
}
} while ($true)
}
function Get-ValidMenuChoice {
do {
$Choice = Read-Host "Enter your choice (1-4)"
if ($Choice -match '^[1-4]$') {
return $Choice
} else {
Write-Host "❌ Invalid choice. Please enter a number between 1 and 4." -Foregr
}
} while ($true)
}
function Perform-Addition {
Write-Host "`n➕ ADDITION OPERATION" -ForegroundColor Yellow
try {
$Num1 = Get-ValidNumber "Enter first number"
$Num2 = Get-ValidNumber "Enter second number"
return $Operation
}
catch {
Write-Host "❌ Error during addition: $($_.[Link])" -ForegroundColor Re
return $null
}
}
function Perform-Subtraction {
Write-Host "`n➖ SUBTRACTION OPERATION" -ForegroundColor Yellow
try {
$Num1 = Get-ValidNumber "Enter first number (minuend)"
$Num2 = Get-ValidNumber "Enter second number (subtrahend)"
return $Operation
}
catch {
Write-Host "❌ Error during subtraction: $($_.[Link])" -ForegroundColor
return $null
}
}
function Perform-Division {
Write-Host "`n➗ DIVISION OPERATION" -ForegroundColor Yellow
try {
$Num1 = Get-ValidNumber "Enter dividend (number to be divided)"
if ($Num2 -eq 0) {
Write-Host "❌ Error: Division by zero is not allowed!" -ForegroundColor R
Write-Host " Please enter a non-zero divisor." -ForegroundColor Yellow
$DivisionByZero = $true
} else {
$DivisionByZero = $false
}
} while ($DivisionByZero)
return $Operation
}
catch {
Write-Host "❌ Error during division: $($_.[Link])" -ForegroundColor Re
return $null
}
}
do {
try {
Show-AdvancedCalculatorMenu
$Choice = Get-ValidMenuChoice
$OperationResult = $null
switch ($Choice) {
'1' {
$OperationResult = Perform-Addition
}
'2' {
$OperationResult = Perform-Subtraction
}
'3' {
$OperationResult = Perform-Division
}
'4' {
# Exit handling
Write-Host "`n🏁 EXITING CALCULATOR" -ForegroundColor Yellow
if ($[Link] -gt 0) {
Write-Host "`n📋 SESSION SUMMARY:" -ForegroundColor Cyan
Write-Host " Total calculations: $($[Link])"
Write-Host " Session duration: $((New-TimeSpan -Start $SessionStart
Write-Host "`n👋 Thank you for using Advanced PowerShell Calculator!" -For
Write-Host "🔚 Session ended at: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
}
}
}
catch {
Write-Host "❌ Unexpected error: $($_.[Link])" -ForegroundColor Red
Write-Host "🔄 Returning to main menu..." -ForegroundColor Yellow
Start-Sleep 2
}
do {
$LogName = Read-Host "Enter Log Name (or 'list' to see available logs again)"
function Get-ValidDateTime {
param([string]$Prompt)
do {
try {
$DateTimeInput = Read-Host $Prompt
$DateTime = [DateTime]::Parse($DateTimeInput)
return $DateTime
}
catch {
Write-Host "❌ Invalid date/time format. Please use format like: MM/dd/yyyy HH
}
} while ($true)
}
function Get-ValidEventType {
Write-Host "`nAvailable Event Types:" -ForegroundColor Yellow
Write-Host "1. Critical (Level 1)"
Write-Host "2. Error (Level 2)"
Write-Host "3. Warning (Level 3)"
Write-Host "4. Information (Level 4)"
Write-Host "5. Verbose (Level 5)"
Write-Host "6. All Events"
do {
$Choice = Read-Host "Select Event Type (1-6)"
switch ($Choice) {
'1' { return @{Name='Critical'; Level=1} }
'2' { return @{Name='Error'; Level=2} }
'3' { return @{Name='Warning'; Level=3} }
'4' { return @{Name='Information'; Level=4} }
'5' { return @{Name='Verbose'; Level=5} }
'6' { return @{Name='All'; Level=$null} }
default { Write-Host "❌ Invalid choice. Please enter 1-6." -ForegroundColor R
}
} while ($true)
}
try {
# Get audit parameters
$LogName = Get-ValidLogName
Write-Host "✅ Selected Log: $LogName" -ForegroundColor Green
$StartDateTime = Get-ValidDateTime "Enter Start Date & Time (e.g., 09/20/2025 00:
Write-Host "✅ Start Time: $($[Link]('yyyy-MM-dd HH:mm:ss'))" -Foregro
$EndDateTime = Get-ValidDateTime "Enter End Date & Time (e.g., 09/22/2025 23:59)"
Write-Host "✅ End Time: $($[Link]('yyyy-MM-dd HH:mm:ss'))" -ForegroundC
$EventType = Get-ValidEventType
Write-Host "✅ Event Type: $($[Link])" -ForegroundColor Green
if ($[Link] -gt 0) {
Write-Host "`n📊 AUDIT RESULTS:" -ForegroundColor Cyan
Write-Host " Total Events Found: $($[Link])" -ForegroundColor Green
$ProcessedEvents = @()
$Counter = 0
foreach ($Event in $Events) {
$Counter++
if ($Counter % 100 -eq 0) {
Write-Progress -Activity "Processing Events" -Status "$Counter of $($Even
}
try {
$ProcessedEvent = [PSCustomObject]@{
'TimeCreated' = $[Link]
'Id' = $[Link]
'Level' = $[Link]
'LogName' = $[Link]
'ProviderName' = $[Link]
'MachineName' = $[Link]
'UserId' = if ($[Link]) { $[Link]() } else { 'N/
'Message' = $[Link] -replace '`n', ' ' -replace '`r', '' # Cl
}
$ProcessedEvents += $ProcessedEvent
}
catch {
Write-Warning "Error processing event $($[Link]): $($_.[Link]
}
}
# Export to CSV
$ExportFileName = "EventLogAudit_$($[Link]('/','-'))_$($[Link])_
try {
$ProcessedEvents | Export-Csv -Path $ExportFileName -NoTypeInformation
Write-Host "✅ Events exported to: $ExportFileName" -ForegroundColor Green
Write-Host " File size: $([math]::Round((Get-Item $ExportFileName).Length/1
}
catch {
Write-Host "❌ Error exporting to CSV: $($_.[Link])" -ForegroundCol
}
} else {
Write-Host "`n❌ No events found matching the specified criteria." -ForegroundColo
Write-Host " Try expanding the date range or selecting a different event type."
}
}
catch {
Write-Host "❌ Error during event log audit: $($_.[Link])" -ForegroundColor
Write-Host " Please check your inputs and try again." -ForegroundColor Yellow
}
if ([string]::IsNullOrWhiteSpace($ServiceInput)) {
Write-Host "❌ Please enter at least one service name." -ForegroundColor Red
continue
}
if ($[Link] -eq 0) {
Write-Host "❌ No valid service names provided." -ForegroundColor Red
continue
}
return $ServiceNames
} while ($true)
}
function Test-ServiceExists {
param([string]$ServiceName)
try {
$Service = Get-Service -Name $ServiceName -ErrorAction Stop
return $true
}
catch {
return $false
}
}
function Get-ServiceStatus {
param([string]$ServiceName)
try {
$Service = Get-Service -Name $ServiceName -ErrorAction Stop
$ServiceDetails = Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'
$StatusInfo = [PSCustomObject]@{
'ServiceName' = $[Link]
'DisplayName' = $[Link]
'Status' = $[Link]
'StartType' = $[Link]
'ProcessId' = if ($ServiceDetails) { $[Link] } else { 'N/A'
'StartName' = if ($ServiceDetails) { $[Link] } else { 'N/A'
'Description' = if ($ServiceDetails) { $[Link] } else { '
'CheckTime' = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
'Success' = $true
'ErrorMessage' = $null
}
return $StatusInfo
}
catch {
$StatusInfo = [PSCustomObject]@{
'ServiceName' = $ServiceName
'DisplayName' = 'N/A'
'Status' = 'Error'
'StartType' = 'N/A'
'ProcessId' = 'N/A'
'StartName' = 'N/A'
'Description' = 'N/A'
'CheckTime' = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
'Success' = $false
'ErrorMessage' = $_.[Link]
}
return $StatusInfo
}
}
function Write-ServiceLog {
param(
[Parameter(Mandatory)]
[string]$LogFile,
[Parameter(Mandatory)]
[string]$Message,
[Parameter(Mandatory)]
[string]$Level = 'INFO'
)
try {
Add-Content -Path $LogFile -Value $LogEntry -ErrorAction Stop
}
catch {
Write-Warning "Failed to write to log file: $($_.[Link])"
}
}
# Setup logging
$LogFileName = "ServiceMonitor_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
$LogFilePath = Join-Path $PWD $LogFileName
Write-ServiceLog -LogFile $LogFilePath -Message "Service Status Monitor started" -Level '
Write-Host "📁 Log file: $LogFileName" -ForegroundColor Cyan
try {
# Get service names from user
$ServiceNames = Get-ServiceNames
Write-Host "✅ Services to monitor: $($ServiceNames -join ', ')" -ForegroundColor Gree
if ($[Link] -gt 0) {
Write-ServiceLog -LogFile $LogFilePath -Message "Invalid services found: $($Inval
$Continue = Read-Host "`nInvalid services found. Continue with valid services onl
if ($[Link]() -ne 'Y') {
Write-Host "Operation cancelled by user." -ForegroundColor Yellow
return
}
}
if ($[Link] -eq 0) {
Write-Host "❌ No valid services to monitor. Exiting." -ForegroundColor Red
return
}
# Monitor services
Write-Host "`n📊 Monitoring Service Status..." -ForegroundColor Yellow
$ServiceResults = @()
try {
$ServiceStatus = Get-ServiceStatus -ServiceName $ServiceName
$ServiceResults += $ServiceStatus
if ($[Link]) {
$StatusColor = switch ($[Link]) {
'Running' { 'Green' }
'Stopped' { 'Red' }
'StartPending' { 'Yellow' }
'StopPending' { 'Yellow' }
'Paused' { 'Yellow' }
default { 'White' }
}
# Generate statistics
$RunningServices = ($ServiceResults | Where-Object {$_.Status -eq 'Running'}).Count
$StoppedServices = ($ServiceResults | Where-Object {$_.Status -eq 'Stopped'}).Count
$ErrorServices = ($ServiceResults | Where-Object {$_.Success -eq $false}).Count
# Log statistics
Write-ServiceLog -LogFile $LogFilePath -Message "Summary - Total: $($ServiceResults.C
try {
$ServiceResults | Export-Csv -Path $ExportFileName -NoTypeInformation
Write-Host "✅ Results exported to: $ExportFileName" -ForegroundColor Green
Write-ServiceLog -LogFile $LogFilePath -Message "Results exported to: $ExportFile
}
catch {
Write-Host "❌ Error exporting results: $($_.[Link])" -ForegroundColor
Write-ServiceLog -LogFile $LogFilePath -Message "Export error: $($_.[Link]
}
# Service recommendations
Write-Host "`n💡 RECOMMENDATIONS:" -ForegroundColor Cyan
}
catch {
Write-Host "❌ Critical error in Service Status Monitor: $($_.[Link])" -For
Write-ServiceLog -LogFile $LogFilePath -Message "Critical error: $($_.[Link]
}
finally {
Write-ServiceLog -LogFile $LogFilePath -Message "Service Status Monitor completed" -L
Write-Host "`n🏁 Service monitoring completed!" -ForegroundColor Green
Write-Host "📄 Full log available in: $LogFileName" -ForegroundColor Cyan
# Q1: Service Query - Find service with Name WinRM using Where-Object
Write-Host "`nQ1: Finding WinRM Service using Where-Object" -ForegroundColor Yellow
Write-Host "Command: Get-Service | Where-Object {`$_.Name -eq 'WinRM'}" -ForegroundColor
try {
$WinRMService = Get-Service | Where-Object {$_.Name -eq 'WinRM'}
if ($WinRMService) {
Write-Host "✅ WinRM Service Found:" -ForegroundColor Green
$WinRMService | Select-Object Name, DisplayName, Status, StartType | Format-Table
# Additional details
Write-Host "Service Details:" -ForegroundColor Yellow
Write-Host " Name: $($[Link])"
Write-Host " Display Name: $($[Link])"
Write-Host " Status: $($[Link])" -ForegroundColor $(if($WinRMServic
Write-Host " Start Type: $($[Link])"
Write-Host " Can Pause and Continue: $($[Link])"
Write-Host " Can Shutdown: $($[Link])"
Write-Host " Can Stop: $($[Link])"
} else {
Write-Host "❌ WinRM Service not found" -ForegroundColor Red
}
}
catch {
Write-Host "❌ Error querying WinRM service: $($_.[Link])" -ForegroundColor
}
# Q2: Application Log Filtering - Find latest 50 Application logs, filter only Error even
Write-Host "`nQ2: Finding Latest 50 Application Log Error Events" -ForegroundColor Yellow
Write-Host "Command: Get-EventLog -LogName Application -Newest 50 | Where-Object {`$_.Ent
try {
$ApplicationErrors = Get-EventLog -LogName Application -Newest 50 | Where-Object {$_.
if ($ApplicationErrors) {
Write-Host "✅ Found $($[Link]) Error events in latest 50 Applica
# Display summary
$ApplicationErrors | Select-Object TimeGenerated, Source, EventID, Message |
Format-Table -Property TimeGenerated, Source, EventID, @{Name='Message (First 100
# Group by source
Write-Host "`nError Events by Source:" -ForegroundColor Yellow
$ApplicationErrors | Group-Object Source | Sort-Object Count -Descending |
Select-Object Name, Count | Format-Table -AutoSize
# Q3: Hotfix Search 1 - Find hotfixes with HotfixID starting with KB5
Write-Host "`nQ3: Finding Hotfixes with HotfixID starting with KB5" -ForegroundColor Yell
Write-Host "Command: Get-HotFix | Where-Object {`$_.HotFixID -like 'KB5*'}" -ForegroundCo
try {
$KB5Hotfixes = Get-HotFix | Where-Object {$_.HotFixID -like 'KB5*'}
if ($KB5Hotfixes) {
Write-Host "✅ Found $($[Link]) hotfixes with HotfixID starting with K
$KB5Hotfixes | Select-Object HotFixID, Description, InstalledBy, InstalledOn |
Sort-Object InstalledOn -Descending | Format-Table -AutoSize
# Statistics
Write-Host "Hotfix Statistics:" -ForegroundColor Yellow
Write-Host " Total KB5 hotfixes: $($[Link])"
Write-Host " Most recent: $($KB5Hotfixes | Sort-Object InstalledOn -Descending |
Write-Host " Oldest: $($KB5Hotfixes | Sort-Object InstalledOn | Select-Object -F
# Group by description
Write-Host "`nHotfixes by Type:" -ForegroundColor Yellow
$KB5Hotfixes | Group-Object Description | Sort-Object Count -Descending |
Select-Object Name, Count | Format-Table -AutoSize
} else {
Write-Host "❌ No hotfixes found with HotfixID starting with KB5" -ForegroundColor
}
}
catch {
Write-Host "❌ Error querying hotfixes: $($_.[Link])" -ForegroundColor Red
}
# Q4: Hotfix Search 2 - Find hotfixes with Description "Update" installed between July 16
Write-Host "`nQ4: Finding 'Update' Hotfixes installed between July 16, 2025 - August 1, 2
Write-Host "Command: Get-HotFix | Where-Object {`$_.Description -eq 'Update' -and `$_.Ins
try {
$StartDate = Get-Date "2025-07-16"
$EndDate = Get-Date "2025-08-01"
if ($UpdateHotfixes) {
Write-Host "✅ Found $($[Link]) 'Update' hotfixes installed between
$UpdateHotfixes | Select-Object HotFixID, Description, InstalledBy, InstalledOn |
Sort-Object InstalledOn | Format-Table -AutoSize
# Additional analysis
Write-Host "Installation Timeline:" -ForegroundColor Yellow
$UpdateHotfixes | Sort-Object InstalledOn | ForEach-Object {
Write-Host " $($_.[Link]('yyyy-MM-dd')): $($_.HotFixID)" -Fore
}
} else {
Write-Host "❌ No 'Update' hotfixes found in the specified date range (July 16 - A
try {
$RemoteServices = Get-Service | Where-Object {$_.Status -eq 'Running' -and $_.Display
if ($RemoteServices) {
Write-Host "✅ Found $($[Link]) running services with DisplayName st
$RemoteServices | Select-Object Name, DisplayName, Status, StartType | Format-Tab
} else {
Write-Host "❌ No running services found with DisplayName starting with 'Remote'"
# Assessment Summary
Write-Host "`n" + "="*50 -ForegroundColor Cyan
Write-Host "WEEKLY ASSESSMENT COMPLETED!" -ForegroundColor Green
Write-Host "="*50 -ForegroundColor Cyan
$CompletedQuestions = @(
"Q1: WinRM Service Query with Where-Object",
"Q2: Latest 50 Application Log Errors",
"Q3: Hotfixes starting with KB5",
"Q4: Update hotfixes in July 16-Aug 1, 2025 range",
"Q5: Running services with DisplayName starting with 'Remote'"
)
Write-Host "`nAll weekly assessment questions have been successfully executed!" -Foregrou
Write-Host "Review the output above for detailed results of each query." -ForegroundColor
Implementation Notes
Prerequisites
Windows PowerShell 5.1 or PowerShell 7+
Administrator privileges for certain operations (Event Logs, Services, AD operations)
Active Directory module for AD-related scripts
Proper execution policy set (Set-ExecutionPolicy RemoteSigned or similar)
Best Practices
1. Error Handling: All scripts include comprehensive try-catch blocks
2. Input Validation: User inputs are validated before processing
3. Logging: Critical operations are logged for audit trails
4. Documentation: Each script includes detailed comments
5. Modularity: Functions are used for reusable code components
Execution Tips
1. Run PowerShell as Administrator when required
2. Test scripts in a safe environment first
3. Review and modify domain names, paths, and server names as needed
4. Ensure required modules are installed and imported
5. Check execution policies before running scripts
Customization
Modify domain names ([Link]) to match your environment
Adjust file paths and directory structures as needed
Customize logging formats and locations
Adapt error handling based on your requirements
Modify output formats (CSV, HTML, etc.) as preferred
The script uses loops and conditional structures to maintain operation flow without interruption, alongside embedded try-catch setups for error management . For feedback, concise messages guide the user through the task, whether it’s calculation result output or system query reports. When operations complete, reports are written to files like CSV or presented in tables for clarity, meeting both operational continuity and reporting needs .
Best practices are evident through structured error handling using try-catch blocks for operations like user creation and scheduled task setting, thus minimizing script interruptions and ensuring issues are logged with descriptive messages . User prompts employ Read-Host for input acquisition, affording control over flow and data intake, while script actions are documented to reflect overall activity, aiding auditing and future troubleshooting .
The bulk creation script first verifies the existence of a CSV containing user details. It imports this data using Import-Csv, and for each user entry, it ensures the account doesn't already exist by trying to retrieve it with Get-ADUser. New accounts are provisioned with parameters specified in the CSV, secure passwords are created, and the New-ADUser cmdlet is used to finalize account creation . This process is surrounded by error handling to address issues like CSV read errors and user creation failures .
In these scripts, modularity is achieved through discrete functions like Set-NTFSPermission and Perform-Addition, each tasked with handling specific operations . This approach promotes code reuse, as common tasks like arithmetic operations or permission settings are encapsulated and can be invoked repeatedly. Modular functions also provide clean error handling and isolation, minimizing impact on overall script function when issues arise .
The script deploys input validation loops using try-catch constructs to manage user input errors effectively . For instance, during group additions, it checks for valid usernames; in calculator operations, inputs are validated as numbers before proceeding. When invalid input is detected, user prompts are reiterated, ensuring only correct data progresses the script .
The script facilitates new Active Directory user account creation by gathering input for the user's personal details and credentials, constructing a user object with specified parameters like Name, GivenName, and Surname, and executing the New-ADUser cmdlet to create the account . Error handling is embedded via try-catch blocks, where failures in user creation, such as invalid inputs or duplication, result in error messages being logged .
The script manages Active Directory group memberships by allowing a user to specify group names and their scopes. New groups are created using New-ADGroup, and user memberships are added with Add-ADGroupMember . Verification is done by listing current group members using Get-ADGroupMember, providing a method to confirm membership changes .
The script employs error handling via try-catch blocks when creating scheduled tasks, catching potential registration errors . It validates necessary paths and existing frameworks by ensuring the directory for scripts exists and setting up initial backup scripts if missing. By using parameters like New-ScheduledTaskAction, validation ensures tasks have valid actions, triggers, and principals, reducing potential run-time issues .
The script begins by creating a primary directory and subdirectories, checking for their existence first. If directories do not exist, New-Item is used to create them . NTFS permissions for these folders are set through a custom function that adjusts ACLs using objects like System.Security.AccessControl.FileSystemAccessRule and Set-Acl. Permissions vary based on group needs, using settings like 'FullControl' for HR and 'Read' for Sales, demonstrating a tailored permissions strategy .
The script retrieves system information using Get-CimInstance for computer and processor details, obtaining data such as computer name, manufacturer, and processor architecture . It calculates RAM in GB and displays it alongside other specs. Presentation is formatted for readability using hash tables in [PSCustomObject], ensuring organized display of information like logical processors and max clock speed .