0% found this document useful (0 votes)
20 views50 pages

Event Log Management PowerShell Script

Uploaded by

mrswayogi
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views50 pages

Event Log Management PowerShell Script

Uploaded by

mrswayogi
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

PowerShell Practical Assessment Solutions Guide

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

PowerShell Practical Assessment 1 {#assessment-1}

Q1: Event Log Management Script

# Event Log Management Script


Write-Host "=== Event Log Management Script ===" -ForegroundColor Green

# Get user input for date range


$StartDate = Read-Host "Enter Event Start Date & Time (MM/dd/yyyy HH:mm)"
$EndDate = Read-Host "Enter Event End Date & Time (MM/dd/yyyy HH:mm)"

# Convert strings to DateTime objects


try {
$StartDateTime = [DateTime]::Parse($StartDate)
$EndDateTime = [DateTime]::Parse($EndDate)
}
catch {
Write-Error "Invalid date format. Please use MM/dd/yyyy HH:mm format"
exit
}

# Get Event Type


Write-Host "Select Event Type:"
Write-Host "1. Error"
Write-Host "2. Information"
Write-Host "3. Warning"
$Choice = Read-Host "Enter your choice (1-3)"

switch ($Choice) {
1 { $EventType = "Error" }
2 { $EventType = "Information" }
3 { $EventType = "Warning" }
default {
Write-Error "Invalid choice"
exit
}
}

# Query System Event Log


Write-Host "Searching for $EventType events between $StartDateTime and $EndDateTime..." -

$Events = Get-WinEvent -FilterHashtable @{


LogName = 'System'
Level = switch ($EventType) {
"Error" { 2 }
"Warning" { 3 }
"Information" { 4 }
}
StartTime = $StartDateTime
EndTime = $EndDateTime
} -ErrorAction SilentlyContinue

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
}

Q2: Temperature Conversion Script

# Temperature Conversion Script


function Show-Menu {
Clear-Host
Write-Host "=== Temperature Conversion Menu ===" -ForegroundColor Green
Write-Host "1. Celsius to Fahrenheit"
Write-Host "2. Fahrenheit to Celsius"
Write-Host "3. Exit"
Write-Host "=========================="
}

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)

Q3: Active Directory User Management

# Active Directory User Management Script


Import-Module ActiveDirectory

# Check if OU exists, create if not


$OUName = "CISPSTraining"
$OUPath = "OU=$OUName,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 "DC=yourdomain,DC=com"
Write-Host "OU $OUName created successfully." -ForegroundColor Green
}

# Get user input


$FirstName = Read-Host "Enter First Name"
$LastName = Read-Host "Enter Last Name"
$DisplayName = Read-Host "Enter Display Name"
$Password = Read-Host "Enter Password" -AsSecureString
$ChangePasswordAtNextLogon = Read-Host "Change Password at Next Logon? (Y/N)"
$AccountEnabled = Read-Host "Enable Account? (Y/N)"

# 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])"
}

Q4: AD Group Management

# AD Group Management Script


Import-Module ActiveDirectory

$OUPath = "OU=CISPSTraining,DC=yourdomain,DC=com"

# Get group details


$GroupName = Read-Host "Enter Group Name"
Write-Host "Group Scope Options:"
Write-Host "1. Global"
Write-Host "2. Universal"
Write-Host "3. DomainLocal"
$ScopeChoice = Read-Host "Select Group Scope (1-3)"

$GroupScope = switch ($ScopeChoice) {


1 { "Global" }
2 { "Universal" }
3 { "DomainLocal" }
default { "Global" }
}

# 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
}

# Add members to group


do {
$Username = Read-Host "Enter username to add to group (or 'exit' to finish)"
if ($Username -ne 'exit') {
try {
Add-ADGroupMember -Identity $GroupName -Members $Username
Write-Host "User $Username added to group $GroupName." -ForegroundColor Green
}
catch {
Write-Warning "Failed to add user $Username: $($_.[Link])"
}
}
} while ($Username -ne 'exit')

# Show group members


Write-Host "`nGroup Members:" -ForegroundColor Yellow
Get-ADGroupMember -Identity $GroupName | Select-Object Name, SamAccountName | Format-Tabl

PowerShell Practical Assessment 2 {#assessment-2}

Q1: Temperature Conversion (Same as Assessment 1 Q2)

Q2: Bulk AD User Creation

# Bulk AD User Creation from CSV


Import-Module ActiveDirectory

# Check if CSV file exists


$CSVPath = Read-Host "Enter CSV file path"
if (-not (Test-Path $CSVPath)) {
Write-Error "CSV file not found!"
exit
}

# Sample CSV format


Write-Host "Expected CSV format: Username,FirstName,LastName,Password,OU,DisplayName" -Fo

# Read CSV file


try {
$Users = Import-Csv -Path $CSVPath
}
catch {
Write-Error "Error reading CSV file: $($_.[Link])"
exit
}

# Process each user


foreach ($User in $Users) {
Write-Host "Processing user: $($[Link])" -ForegroundColor Yellow

# Check if user already exists


try {
$ExistingUser = Get-ADUser -Identity $[Link] -ErrorAction Stop
Write-Warning "User $($[Link]) already exists. Skipping..."
continue
}
catch {
# User doesn't exist, proceed with creation
}

# Create secure password


$SecurePassword = ConvertTo-SecureString $[Link] -AsPlainText -Force

# Create user parameters


$UserParams = @{
Name = "$($[Link]) $($[Link])"
GivenName = $[Link]
Surname = $[Link]
SamAccountName = $[Link]
UserPrincipalName = "$($[Link])@[Link]"
DisplayName = $[Link]
Path = $[Link]
AccountPassword = $SecurePassword
Enabled = $true
ChangePasswordAtLogon = $true
}

# Create the user


try {
New-ADUser @UserParams
Write-Host "User $($[Link]) created successfully." -ForegroundColor Green
}
catch {
Write-Error "Failed to create user $($[Link]): $($_.[Link])"
}
}

Write-Host "`nBulk user creation completed." -ForegroundColor Green

Q3: File Share Management

# File Share Management Script


# Create main folder and subfolders
$MainFolder = "E:\TeamShare"
$SubFolders = @("HR", "IT", "Sales")

# Create directories
if (-not (Test-Path $MainFolder)) {
New-Item -Path $MainFolder -ItemType Directory -Force
Write-Host "Created main folder: $MainFolder" -ForegroundColor Green
}

foreach ($Folder in $SubFolders) {


$SubFolderPath = Join-Path $MainFolder $Folder
if (-not (Test-Path $SubFolderPath)) {
New-Item -Path $SubFolderPath -ItemType Directory -Force
Write-Host "Created subfolder: $SubFolderPath" -ForegroundColor Green
}
}

# Set NTFS Permissions


function Set-NTFSPermission {
param(
[string]$Path,
[string]$Group,
[string]$Permission
)

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"

Write-Host "File share setup completed successfully!" -ForegroundColor Green

Q4: Scheduled Task Creation

# Scheduled Task Creation Script


$ScriptPath = "C:\Scripts\DailyBackup.ps1"
$TaskName = "DailyBackup"

# Ensure Scripts directory exists


$ScriptsDir = "C:\Scripts"
if (-not (Test-Path $ScriptsDir)) {
New-Item -Path $ScriptsDir -ItemType Directory -Force
Write-Host "Created directory: $ScriptsDir" -ForegroundColor Green
}

# Create sample backup script if it doesn't exist


if (-not (Test-Path $ScriptPath)) {
$BackupScript = @"
# Daily Backup Script
`$Date = Get-Date -Format "yyyy-MM-dd_HH-mm"
Write-Host "Starting backup at `$Date"
# Add your backup commands here
Write-Host "Backup completed successfully!"
"@
$BackupScript | Out-File -FilePath $ScriptPath -Encoding UTF8
Write-Host "Created sample backup script: $ScriptPath" -ForegroundColor Green
}

# Create scheduled task


$Action = New-ScheduledTaskAction -Execute "[Link]" -Argument "-ExecutionPolicy B
$Trigger = New-ScheduledTaskTrigger -Daily -At "21:30"
$Principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount

# Register the task


try {
Register-ScheduledTask -TaskName $TaskName -Action $Action -Trigger $Trigger -Princip
Write-Host "Scheduled task '$TaskName' created successfully to run daily at 9:30 PM"
}
catch {
Write-Error "Failed to create scheduled task: $($_.[Link])"
}

# Verify task creation


$Task = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
if ($Task) {
Write-Host "Task verification successful:" -ForegroundColor Yellow
$Task | Select-Object TaskName, State, @{Name='NextRunTime';Expression={(Get-Schedule
}

Milestone Assessment PowerShell 1 {#milestone-1}

Q1: CSV User Management

# CSV User Management Script


Import-Module ActiveDirectory

# Get CSV file path


$CSVPath = Read-Host "Enter CSV file path"
if (-not (Test-Path $CSVPath)) {
Write-Error "CSV file not found!"
exit
}

Write-Host "Expected CSV format: FirstName,LastName,Username,Department" -ForegroundColor

# Read CSV and create users


try {
$Users = Import-Csv -Path $CSVPath

# Create NewHireGroup if it doesn't exist


$GroupName = "NewHireGroup"
try {
Get-ADGroup -Identity $GroupName -ErrorAction Stop
Write-Host "Group $GroupName already exists." -ForegroundColor Yellow
}
catch {
New-ADGroup -Name $GroupName -GroupScope Global -GroupCategory Security
Write-Host "Created group: $GroupName" -ForegroundColor Green
}

foreach ($User in $Users) {


Write-Host "Creating user: $($[Link])" -ForegroundColor Yellow

# Generate random password


$Password = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 12 | ForEa
$SecurePassword = ConvertTo-SecureString $Password -AsPlainText -Force

$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])"
}

Q2: System Information Report

# System Information Report Script


Write-Host "Generating System Information Report..." -ForegroundColor Green

# Get system information


$ComputerName = $env:COMPUTERNAME
$OS = Get-CimInstance -ClassName Win32_OperatingSystem
$NetworkAdapters = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration | Where-O

# Get primary IP address


$IPAddress = ($NetworkAdapters | Select-Object -First 1).IPAddress[0]

# Get last boot time


$LastBootTime = $[Link]

# Create report object


$SystemReport = [PSCustomObject]@{
'Computer Name' = $ComputerName
'Operating System' = $[Link]
'OS Version' = $[Link]
'IP Address' = $IPAddress
'Last Boot Time' = $LastBootTime
'Report Generated' = Get-Date
}
# Display report
Write-Host "`n=== System Information Report ===" -ForegroundColor Yellow
$SystemReport | Format-List

# 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

# Export to HTML for better formatting


$HTMLReport = $SystemReport | ConvertTo-Html -Title "System Information Report" -PreConte
$HTMLPath = "SystemInfo_$(Get-Date -Format 'yyyyMMdd_HHmm').html"
$HTMLReport | Out-File -FilePath $HTMLPath
Write-Host "HTML report exported to: $HTMLPath" -ForegroundColor Green

Q3: Directory Structure Creation

# Directory Structure Creation Script


$MainPath = "D:\ProjectData"
$SubFolders = @("2023", "2024", "Archive")
$ReportFiles = @("[Link]", "[Link]", "[Link]", "[Link]", "[Link]

Write-Host "Creating directory structure..." -ForegroundColor Green

# Create main directory


if (-not (Test-Path $MainPath)) {
New-Item -Path $MainPath -ItemType Directory -Force
Write-Host "Created: $MainPath" -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
}
}

# Create report files in 2023 folder


$ReportsPath = Join-Path $MainPath "2023"
foreach ($ReportFile in $ReportFiles) {
$FilePath = Join-Path $ReportsPath $ReportFile
if (-not (Test-Path $FilePath)) {
$Content = @"
Report: $ReportFile
Generated: $(Get-Date)
Project Data Report for 2023

This is a sample report file created by PowerShell script.


Content can be customized as needed.
"@
$Content | Out-File -FilePath $FilePath -Encoding UTF8
Write-Host "Created: $FilePath" -ForegroundColor Green
}
}

# Display directory structure


Write-Host "`nDirectory Structure Created:" -ForegroundColor Yellow
Get-ChildItem -Path $MainPath -Recurse | Select-Object FullName, @{Name='Type';Expression

Write-Host "Directory structure creation completed!" -ForegroundColor Green

Q4: Drive Space Check

# Drive Space Check Script


Write-Host "Checking drive space..." -ForegroundColor Green

# Get all drives


$Drives = Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object {$_.DriveType -eq 3

# Filter drives with more than 2 GB free space


$MinFreeSpaceGB = 2
$DrivesWithSpace = @()

foreach ($Drive in $Drives) {


$FreeSpaceGB = [math]::Round($[Link] / 1GB, 2)
$TotalSizeGB = [math]::Round($[Link] / 1GB, 2)
$UsedSpaceGB = [math]::Round(($[Link] - $[Link]) / 1GB, 2)
$PercentFree = [math]::Round(($[Link] / $[Link]) * 100, 1)

if ($FreeSpaceGB -gt $MinFreeSpaceGB) {


$DriveInfo = [PSCustomObject]@{
'Drive Letter' = $[Link]
'Total Size (GB)' = $TotalSizeGB
'Used Space (GB)' = $UsedSpaceGB
'Free Space (GB)' = $FreeSpaceGB
'Percent Free' = "$PercentFree%"
'Volume Label' = $[Link]
}
$DrivesWithSpace += $DriveInfo
}
}

# Display results
if ($[Link] -gt 0) {
Write-Host "`nDrives with more than $MinFreeSpaceGB GB free space:" -ForegroundColor
$DrivesWithSpace | Format-Table -AutoSize

Write-Host "Summary:" -ForegroundColor Green


Write-Host "Total drives checked: $($[Link])"
Write-Host "Drives with >$MinFreeSpaceGB GB free: $($[Link])"
} else {
Write-Host "No drives found with more than $MinFreeSpaceGB GB free space." -Foregroun
}

# Export results
$ExportPath = "DriveSpace_$(Get-Date -Format 'yyyyMMdd_HHmm').csv"
$DrivesWithSpace | Export-Csv -Path $ExportPath -NoTypeInformation
Write-Host "Results exported to: $ExportPath" -ForegroundColor Green

Milestone Assessment PowerShell 2 {#milestone-2}

Q1: Department Structure Creation

# Department Structure Creation Script


Import-Module ActiveDirectory

Write-Host "Creating Finance Department Structure..." -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
}

# Create Finance Groups


$Groups = @("FinanceUsers", "FinanceAdmins", "FinanceAuditors")

foreach ($GroupName in $Groups) {


try {
Get-ADGroup -Identity $GroupName -ErrorAction Stop
Write-Host "Group $GroupName already exists." -ForegroundColor Yellow
}
catch {
New-ADGroup -Name $GroupName -GroupScope Global -GroupCategory Security -Path $OU
Write-Host "Created group: $GroupName" -ForegroundColor Green
}
}

# Move users to FinanceDept OU


$UsersToMove = @("JohnF", "LisaM", "DavidR")

foreach ($Username in $UsersToMove) {


try {
$User = Get-ADUser -Identity $Username
Move-ADObject -Identity $[Link] -TargetPath $OUPath
Write-Host "Moved user $Username to $OUName OU" -ForegroundColor Green

# Add to FinanceUsers group


Add-ADGroupMember -Identity "FinanceUsers" -Members $Username
Write-Host "Added $Username to FinanceUsers group" -ForegroundColor Green
}
catch {
Write-Warning "Could not process user $Username : $($_.[Link])"
}
}

# Display final structure


Write-Host "`nFinance Department Structure:" -ForegroundColor Yellow
Write-Host "OU: $OUName" -ForegroundColor Cyan
Write-Host "Groups:" -ForegroundColor Cyan
$Groups | ForEach-Object { Write-Host " - $_" -ForegroundColor White }
Write-Host "Users moved:" -ForegroundColor Cyan
$UsersToMove | ForEach-Object { Write-Host " - $_" -ForegroundColor White }

Q2: File Share with NTFS Permissions (Same as Assessment 2 Q3)

Q3: Security Event Log Query

# Security Event Log Query Script


Write-Host "Querying Security Event Logs for Failed Logins..." -ForegroundColor Green

# Calculate time range (last 24 hours)


$EndTime = Get-Date
$StartTime = $[Link](-24)

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

# Process and display results


$Results = foreach ($Event in $FailedLogins) {
$EventXML = [xml]$[Link]()
$EventData = $[Link]

# Extract relevant information


$TargetUserName = ($EventData | Where-Object {$_.Name -eq 'TargetUserName'}).
$TargetDomainName = ($EventData | Where-Object {$_.Name -eq 'TargetDomainName
$WorkstationName = ($EventData | Where-Object {$_.Name -eq 'WorkstationName'}
$IpAddress = ($EventData | Where-Object {$_.Name -eq 'IpAddress'}).'#text'
$LogonType = ($EventData | Where-Object {$_.Name -eq 'LogonType'}).'#text'

[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
}

Q4: Scheduled Task (8:30 PM version)

# Scheduled Task Creation Script (8:30 PM)


$ScriptPath = "C:\Scripts\DailyBackup.ps1"
$TaskName = "DailyBackup_830PM"

# Ensure Scripts directory exists


$ScriptsDir = "C:\Scripts"
if (-not (Test-Path $ScriptsDir)) {
New-Item -Path $ScriptsDir -ItemType Directory -Force
Write-Host "Created directory: $ScriptsDir" -ForegroundColor Green
}

# Create sample backup script if it doesn't exist


if (-not (Test-Path $ScriptPath)) {
$BackupScript = @"
# Daily Backup Script - 8:30 PM Version
`$Date = Get-Date -Format "yyyy-MM-dd_HH-mm"
`$LogFile = "C:\Scripts\BackupLog_`$[Link]"

Start-Transcript -Path `$LogFile

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.

Write-Host "Backing up system configurations..."


# Additional backup commands

Write-Host "Backup completed successfully at `$(Get-Date)"


}
catch {
Write-Error "Backup failed: `$(`$_.[Link])"
}

Stop-Transcript
"@
$BackupScript | Out-File -FilePath $ScriptPath -Encoding UTF8
Write-Host "Created backup script: $ScriptPath" -ForegroundColor Green
}

# Delete existing task if it exists


$ExistingTask = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
if ($ExistingTask) {
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false
Write-Host "Removed existing task: $TaskName" -ForegroundColor Yellow
}

# Create scheduled task for 8:30 PM


$Action = New-ScheduledTaskAction -Execute "[Link]" -Argument "-ExecutionPolicy B
$Trigger = New-ScheduledTaskTrigger -Daily -At "20:30"
$Principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLe

$Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatte

# Register the task


try {
Register-ScheduledTask -TaskName $TaskName -Action $Action -Trigger $Trigger -Princip
Write-Host "Scheduled task '$TaskName' created successfully to run daily at 8:30 PM"
}
catch {
Write-Error "Failed to create scheduled task: $($_.[Link])"
}

# Verify and display task details


$Task = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
if ($Task) {
$TaskInfo = Get-ScheduledTaskInfo -TaskName $TaskName
Write-Host "`nTask Details:" -ForegroundColor Yellow
[PSCustomObject]@{
'Task Name' = $[Link]
'State' = $[Link]
'Next Run Time' = $[Link]
'Last Run Time' = $[Link]
'Last Result' = $[Link]
'Run As' = $[Link]
} | Format-List
}

PowerShell Practical Assessment 3 {#assessment-3}

Q1: Local System Administration

# Local System Administration Script


function Show-SystemMenu {
Clear-Host
Write-Host "=== System Administration Menu ===" -ForegroundColor Green
Write-Host "1. Manage Services"
Write-Host "2. Manage Processes"
Write-Host "3. System Information"
Write-Host "4. Exit"
Write-Host "================================="
}

function Manage-Services {
Write-Host "`n=== Service Management ===" -ForegroundColor Yellow

$ServiceChoice = Read-Host "Enter service name to check (or 'list' for all services)"

if ($[Link]() -eq 'list') {


Get-Service | Select-Object Name, Status, StartType | Format-Table -AutoSize
}
elseif ($ServiceChoice) {
$Service = Get-Service -Name $ServiceChoice -ErrorAction SilentlyContinue

if ($Service) {
Write-Host "Service: $($[Link])" -ForegroundColor Cyan
Write-Host "Status: $($[Link])" -ForegroundColor $(if($[Link]
Write-Host "Start Type: $($[Link])" -ForegroundColor Yellow

if ($[Link] -eq 'Stopped') {


$StartService = Read-Host "Service is stopped. Start it? (Y/N)"
if ($[Link]() -eq 'Y') {
try {
Start-Service -Name $ServiceChoice
Write-Host "Service started successfully!" -ForegroundColor Green
}
catch {
Write-Error "Failed to start service: $($_.[Link])"
}
}
}
elseif ($[Link] -eq 'Running') {
$StopService = Read-Host "Service is running. Stop it? (Y/N)"
if ($[Link]() -eq 'Y') {
try {
Stop-Service -Name $ServiceChoice
Write-Host "Service stopped successfully!" -ForegroundColor Green
}
catch {
Write-Error "Failed to stop service: $($_.[Link])"
}
}
}
}
else {
Write-Host "Service '$ServiceChoice' not found." -ForegroundColor Red
}
}
}

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 ($[Link]() -eq 'top') {


Write-Host "Top 10 processes by CPU usage:" -ForegroundColor Cyan
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 Name, Id, CPU
}
elseif ($ProcessChoice) {
$Processes = Get-Process -Name $ProcessChoice -ErrorAction SilentlyContinue

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

$OS = Get-CimInstance -ClassName Win32_OperatingSystem


$Computer = Get-CimInstance -ClassName Win32_ComputerSystem
$CPU = Get-CimInstance -ClassName Win32_Processor | Select-Object -First 1

[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
}

# Main script logic


do {
Show-SystemMenu
$Choice = Read-Host "Enter your choice (1-4)"

if ($Choice -eq '1') {


Manage-Services
}
elseif ($Choice -eq '2') {
Manage-Processes
}
elseif ($Choice -eq '3') {
Get-SystemInfo
}
elseif ($Choice -eq '4') {
Write-Host "Goodbye!" -ForegroundColor Green
break
}
else {
Write-Host "Invalid choice. Please try again." -ForegroundColor Red
}

if ($Choice -ne '4') {


Read-Host "Press Enter to continue"
}

} while ($Choice -ne '4')

Q2: WMI/CIM Operations

# WMI/CIM Operations Script


Write-Host "=== WMI/CIM Operations Demo ===" -ForegroundColor Green

# Retrieve OS information using WMI (Legacy)


Write-Host "`n1. Using WMI (Win32_OperatingSystem):" -ForegroundColor Yellow
try {
$OSInfo_WMI = Get-WmiObject -Class Win32_OperatingSystem
Write-Host "OS Name: $($OSInfo_WMI.Caption)"
Write-Host "Version: $($OSInfo_WMI.Version)"
Write-Host "Architecture: $($OSInfo_WMI.OSArchitecture)"
Write-Host "Install Date: $($OSInfo_WMI.InstallDate)"

# Store last boot time in variable as requested


$LastBootTime = $OSInfo_WMI.LastBootUpTime
Write-Host "Last Boot Time (WMI): $LastBootTime" -ForegroundColor Cyan
}
catch {
Write-Error "Error with WMI: $($_.[Link])"
}

# Retrieve OS information using CIM (Modern approach)


Write-Host "`n2. Using CIM (Win32_OperatingSystem):" -ForegroundColor Yellow
try {
$OSInfo_CIM = Get-CimInstance -ClassName Win32_OperatingSystem
Write-Host "OS Name: $($OSInfo_CIM.Caption)"
Write-Host "Version: $($OSInfo_CIM.Version)"
Write-Host "Architecture: $($OSInfo_CIM.OSArchitecture)"
Write-Host "Install Date: $($OSInfo_CIM.InstallDate)"

# Store last boot time in variable as requested


$LastBootTimeCIM = $OSInfo_CIM.LastBootUpTime
Write-Host "Last Boot Time (CIM): $LastBootTimeCIM" -ForegroundColor Cyan
}
catch {
Write-Error "Error with CIM: $($_.[Link])"
}

# Compare the two methods


Write-Host "`n3. Comparison of WMI vs CIM:" -ForegroundColor Yellow
Write-Host "WMI Last Boot Time: $LastBootTime"
Write-Host "CIM Last Boot Time: $LastBootTimeCIM"

if ($LastBootTime -and $LastBootTimeCIM) {


# Convert WMI datetime format if needed
if ($LastBootTime -is [string]) {
$LastBootTime = [[Link]]::ToDateTime($LastBootTim
}

Write-Host "Times Match: $(($LastBootTime -eq $LastBootTimeCIM))" -ForegroundColor $(


}

# Additional CIM examples


Write-Host "`n4. Additional CIM Operations:" -ForegroundColor Yellow

# Computer System Info


Write-Host "`nComputer System Information:" -ForegroundColor Cyan
$ComputerInfo = Get-CimInstance -ClassName Win32_ComputerSystem
[PSCustomObject]@{
'Computer Name' = $[Link]
'Manufacturer' = $[Link]
'Model' = $[Link]
'Total RAM (GB)' = [math]::Round($[Link]/1GB, 2)
'Domain' = $[Link]
'Workgroup' = $[Link]
} | 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

# Calculate and display uptime


$Uptime = New-TimeSpan -Start $LastBootTimeCIM -End (Get-Date)
Write-Host "`nSystem Uptime:" -ForegroundColor Yellow
Write-Host "Days: $($[Link])"
Write-Host "Hours: $($[Link])"
Write-Host "Minutes: $($[Link])"
Write-Host "Total Hours: $([math]::Round($[Link], 2))"

# Export information to file


$SystemReport = [PSCustomObject]@{
'Report Generated' = Get-Date
'Computer Name' = $[Link]
'OS' = $OSInfo_CIM.Caption
'Last Boot Time' = $LastBootTimeCIM
'Uptime (Hours)' = [math]::Round($[Link], 2)
'Total RAM (GB)' = [math]::Round($[Link]/1GB, 2)
'Processor' = $[Link]
}

$ReportPath = "SystemReport_$(Get-Date -Format 'yyyyMMdd_HHmm').csv"


$SystemReport | Export-Csv -Path $ReportPath -NoTypeInformation
Write-Host "`nSystem report exported to: $ReportPath" -ForegroundColor Green

Q3: Do-While Calculator

# Do-While Calculator Script


function Show-CalculatorMenu {
Clear-Host
Write-Host "=== PowerShell Calculator ===" -ForegroundColor Green
Write-Host "1. Addition"
Write-Host "2. Subtraction"
Write-Host "3. Division"
Write-Host "4. Multiplication (Bonus)"
Write-Host "5. Exit"
Write-Host "=========================="
}

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)

return $Num1, $Num2


}

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
}

# Main calculator logic using do-while loop


$CalculationHistory = @()

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

# Ask if user wants to save history


$SaveHistory = Read-Host "Save calculation history to file? (Y/N)"
if ($[Link]() -eq 'Y') {
$HistoryPath = "CalculatorHistory_$(Get-Date -Format 'yyyyMMdd_HHmm')
$CalculationHistory | Export-Csv -Path $HistoryPath -NoTypeInformatio
Write-Host "History saved to: $HistoryPath" -ForegroundColor Green
}
}
Write-Host "Thank you for using PowerShell Calculator!" -ForegroundColor Gree
}
}

if ($Choice -ne '5') {


# Show recent calculations
if ($[Link] -gt 0) {
Write-Host "`nRecent Calculations:" -ForegroundColor Cyan
$CalculationHistory | Select-Object -Last 3 Expression, Result | Format-Table
}

Read-Host "Press Enter to continue"


}

} while ($Choice -ne '5')

Q4: File Share Management (Same as Assessment 2 Q3)


Advanced PowerShell Assessment {#advanced-assessment}

Q1: Advanced AD User Creation

# Advanced AD User Creation Script


Import-Module ActiveDirectory

Write-Host "=== Advanced AD User Creation ===" -ForegroundColor Green

# Function to generate SamAccountName


function Generate-SamAccountName {
param(
[string]$FirstName,
[string]$LastName
)

# Create SamAccountName using first initial + last name


$SamAccount = ($[Link](0,1) + $LastName).ToLower()

# Check if account already exists and modify if needed


$Counter = 1
$OriginalSamAccount = $SamAccount

while (Get-ADUser -Filter "SamAccountName -eq '$SamAccount'" -ErrorAction SilentlyCon


$SamAccount = "$OriginalSamAccount$Counter"
$Counter++
}

return $SamAccount
}

# Create OU if it doesn't exist


$OUName = "Contoso-Staff-Users"
$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
}

# Get user input


$FirstName = Read-Host "Enter First Name"
$LastName = Read-Host "Enter Last Name"
$Department = Read-Host "Enter Department"
$Title = Read-Host "Enter Job Title"

# Auto-build Display Name and SamAccountName


$DisplayName = "$FirstName $LastName"
$SamAccountName = Generate-SamAccountName -FirstName $FirstName -LastName $LastName
Write-Host "`nAuto-generated values:" -ForegroundColor Yellow
Write-Host "Display Name: $DisplayName"
Write-Host "SamAccountName: $SamAccountName"

$Confirm = Read-Host "Proceed with these values? (Y/N)"


if ($[Link]() -ne 'Y') {
$DisplayName = Read-Host "Enter custom Display Name"
$SamAccountName = Read-Host "Enter custom SamAccountName"
}

# Get password with complexity validation


do {
$Password = Read-Host "Enter Password (min 8 chars, must contain upper, lower, number
$PlainPassword = [[Link]]::PtrToStringAuto([[Link]

$PasswordValid = $true
$ValidationMessage = ""

if ($[Link] -lt 8) {
$PasswordValid = $false
$ValidationMessage += "Password must be at least 8 characters. "
}

if ($PlainPassword -cnotmatch '[A-Z]') {


$PasswordValid = $false
$ValidationMessage += "Password must contain at least one uppercase letter. "
}

if ($PlainPassword -cnotmatch '[a-z]') {


$PasswordValid = $false
$ValidationMessage += "Password must contain at least one lowercase letter. "
}

if ($PlainPassword -notmatch '\d') {


$PasswordValid = $false
$ValidationMessage += "Password must contain at least one number. "
}

if (-not $PasswordValid) {
Write-Host $ValidationMessage -ForegroundColor Red
}

} while (-not $PasswordValid)

# 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

# Set additional password policies


Set-ADUser -Identity $SamAccountName -PasswordNotRequired $false

# Create user report object


$UserReport = [PSCustomObject]@{
'First Name' = $FirstName
'Last Name' = $LastName
'Display Name' = $DisplayName
'SamAccountName' = $SamAccountName
'Department' = $Department
'Title' = $Title
'OU Path' = $OUPath
'Created Date' = Get-Date
'Password Complexity' = 'Enforced'
'Account Status' = 'Enabled'
}

# Display created user info


Write-Host "`nUser Details:" -ForegroundColor Yellow
$UserReport | Format-List

# 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])"
}

Q2: Remote Server Monitoring

# Remote Server Monitoring Script


param(
[Parameter(Mandatory=$false)]
[string]$ComputerName = (Read-Host "Enter remote server name or IP")
)

Write-Host "=== Remote Server Monitoring Script ===" -ForegroundColor Green


Write-Host "Target Server: $ComputerName" -ForegroundColor Yellow

# Create log file


$LogFileName = "HealthCheck_$($[Link]('.','_'))_$(Get-Date -Format 'yyyyMMd
$LogPath = Join-Path $PWD $LogFileName
function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$LogEntry = "[$Timestamp] [$Level] $Message"
Write-Host $LogEntry -ForegroundColor $(
switch($Level) {
"ERROR" { "Red" }
"WARNING" { "Yellow" }
"SUCCESS" { "Green" }
default { "White" }
}
)
Add-Content -Path $LogPath -Value $LogEntry
}

Write-Log "Starting health check for server: $ComputerName"

# 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
}

# Get credentials for remote access


$Credential = $null
$UseCredentials = Read-Host "Use alternate credentials for remote access? (Y/N)"
if ($[Link]() -eq 'Y') {
$Credential = Get-Credential -Message "Enter credentials for remote server access"
}

# Monitor Windows Services


Write-Log "Checking Windows Services..."
try {
if ($Credential) {
$Services = Get-Service -ComputerName $ComputerName -ErrorAction Stop | Where-Obj
} else {
$Services = Invoke-Command -ComputerName $ComputerName -ScriptBlock {
Get-Service | Where-Object {$_.Status -eq 'Stopped'}
} -ErrorAction Stop
}

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"
}

# Monitor System Processes with high CPU


Write-Log "Checking processes with high CPU usage (>10%)..."
try {
$ProcessScript = {
Get-Process | Where-Object {$_.CPU -gt 0} |
Sort-Object CPU -Descending |
Select-Object Name, Id, CPU,
@{Name='CPUPercent';Expression={[math]::Round(($_.CPU / (Get-CimInstance -Cla
@{Name='Memory(MB)';Expression={[math]::Round($_.WorkingSet/1MB, 2)}} |
Where-Object {$_.CPU -gt 10}
}

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"
}

# Get system performance metrics


Write-Log "Collecting system performance metrics..."
try {
$SystemInfoScript = {
$OS = Get-CimInstance -ClassName Win32_OperatingSystem
$Computer = Get-CimInstance -ClassName Win32_ComputerSystem
$CPU = Get-CimInstance -ClassName Win32_Processor | Select-Object -First 1
$Disk = Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object {$_.DriveType

[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
}

Write-Log "System Information Retrieved:" "SUCCESS"


Write-Log " Computer: $($[Link])"
Write-Log " OS: $($[Link])"
Write-Log " Total Memory: $($[Link]) GB"
Write-Log " Free Memory: $($[Link]) GB"
Write-Log " Uptime: $($[Link]) hours"
Write-Log " Last Boot: $($[Link])"

foreach ($Disk in $[Link]) {


$FreePercent = [math]::Round(($[Link] / $[Link]) * 100, 1)
$Status = if ($FreePercent -lt 10) { "WARNING" } else { "SUCCESS" }
Write-Log " Disk $($[Link]): $($[Link])GB free of $($[Link])GB
}
}
catch {
Write-Log "Error retrieving system information: $($_.[Link])" "ERROR"
}

# 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

Q3: Boot Time Analysis

# Boot Time Analysis Script with Transcript


$TranscriptFileName = "BootTimeAnalysis_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt"
$TranscriptPath = Join-Path $PWD $TranscriptFileName

# Start PowerShell transcript with custom filename


Start-Transcript -Path $TranscriptPath

Write-Host "=== Boot Time Analysis Script ===" -ForegroundColor Green


Write-Host "Transcript started: $TranscriptPath" -ForegroundColor Yellow

try {
# Query WMI for last boot time
Write-Host "`nQuerying WMI for system boot information..." -ForegroundColor Cyan

# Method 1: Using Win32_OperatingSystem


$OS = Get-CimInstance -ClassName Win32_OperatingSystem
$LastBootTime = $[Link]
$CurrentTime = Get-Date

Write-Host "WMI Query Results:" -ForegroundColor Yellow


Write-Host " Class: Win32_OperatingSystem"
Write-Host " Property: LastBootUpTime"
Write-Host " Raw Value: $LastBootTime"

# Calculate uptime
$Uptime = New-TimeSpan -Start $LastBootTime -End $CurrentTime
$UptimeHours = [math]::Round($[Link], 2)

# Display boot time analysis


Write-Host "`n=== Boot Time Analysis Results ===" -ForegroundColor Green
Write-Host "Boot Time: $($[Link]('yyyy-MM-dd HH:mm:ss'))" -ForegroundC
Write-Host "Current Time: $($[Link]('yyyy-MM-dd HH:mm:ss'))" -Foregroun
Write-Host "System Uptime: $UptimeHours hours" -ForegroundColor Cyan

# Detailed uptime breakdown


Write-Host "`nDetailed Uptime Breakdown:" -ForegroundColor Yellow
Write-Host " Days: $($[Link])"
Write-Host " Hours: $($[Link])"
Write-Host " Minutes: $($[Link])"
Write-Host " Seconds: $($[Link])"
Write-Host " Total Days: $([math]::Round($[Link], 2))"
Write-Host " Total Hours: $UptimeHours"
Write-Host " Total Minutes: $([math]::Round($[Link], 2))"

# Additional system information


Write-Host "`n=== Additional System Information ===" -ForegroundColor Yellow
$ComputerInfo = Get-CimInstance -ClassName Win32_ComputerSystem

Write-Host "Computer Name: $($[Link])"


Write-Host "Operating System: $($[Link])"
Write-Host "OS Version: $($[Link])"
Write-Host "OS Architecture: $($[Link])"
Write-Host "Total Physical Memory: $([math]::Round($[Link]/
Write-Host "Available Physical Memory: $([math]::Round($[Link]/1MB, 2)

# Boot performance analysis


Write-Host "`n=== Boot Performance Analysis ===" -ForegroundColor Yellow

# Get boot events from System log


try {
Write-Host "Analyzing boot events from System log..." -ForegroundColor Cyan

$BootEvents = Get-WinEvent -FilterHashtable @{


LogName = 'System'
ID = 6005, 6006, 6009, 6013 # Boot/shutdown events
StartTime = $[Link](-5)
EndTime = $[Link](10)
} -ErrorAction SilentlyContinue

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

if ($UptimeHours -lt 24) {


Write-Host "✓ System recently rebooted (< 24 hours)" -ForegroundColor Green
Write-Host " This is good for applying updates and clearing memory."
}
elseif ($UptimeHours -lt 168) { # Less than 1 week
Write-Host "✓ System uptime is reasonable (< 1 week)" -ForegroundColor Green
Write-Host " Regular reboots help maintain system performance."
}
elseif ($UptimeHours -lt 720) { # Less than 30 days
Write-Host "⚠ System has been running for over a week" -ForegroundColor Yellow
Write-Host " Consider scheduling a reboot for maintenance."
}
else {
Write-Host "⚠ System has been running for over 30 days" -ForegroundColor Red
Write-Host " Extended uptime may impact performance. Schedule a maintenance rebo
}

# Create summary report


$BootReport = [PSCustomObject]@{
'Computer Name' = $[Link]
'Operating System' = $[Link]
'Boot Time' = $LastBootTime
'Current Time' = $CurrentTime
'Uptime (Hours)' = $UptimeHours
'Uptime (Days)' = [math]::Round($[Link], 2)
'Total Memory (GB)' = [math]::Round($[Link]/1GB, 2)
'Analysis Date' = Get-Date
}

Write-Host "`n=== Boot Time Summary Report ===" -ForegroundColor Green


$BootReport | Format-List

# 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

# Open transcript file


$OpenTranscript = Read-Host "Open transcript file? (Y/N)"
if ($[Link]() -eq 'Y') {
notepad $TranscriptPath
}
}

Calculator Menu Assessment {#calculator-assessment}

Q1: Advanced Calculator with Error Handling

# Advanced Calculator with Error Handling


function Show-AdvancedCalculatorMenu {
Clear-Host
Write-Host "=====================================" -ForegroundColor Cyan
Write-Host " ADVANCED POWERSHELL CALCULATOR" -ForegroundColor Green
Write-Host "=====================================" -ForegroundColor Cyan
Write-Host "1. Addition (+)"
Write-Host "2. Subtraction (-)"
Write-Host "3. Division (÷)"
Write-Host "4. Exit"
Write-Host "=====================================" -ForegroundColor Cyan
}

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"

$Result = $Num1 + $Num2

Write-Host "`n🔢 Calculation: $Num1 + $Num2 = $Result" -ForegroundColor Green

# Log the operation


$Operation = [PSCustomObject]@{
'Operation' = 'Addition'
'Number1' = $Num1
'Number2' = $Num2
'Result' = $Result
'Timestamp' = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
}

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)"

$Result = $Num1 - $Num2

Write-Host "`n🔢 Calculation: $Num1 - $Num2 = $Result" -ForegroundColor Green

# Log the operation


$Operation = [PSCustomObject]@{
'Operation' = 'Subtraction'
'Number1' = $Num1
'Number2' = $Num2
'Result' = $Result
'Timestamp' = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
}

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)"

# Special handling for division by zero


do {
$Num2 = Get-ValidNumber "Enter divisor (number to divide by)"

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)

$Result = $Num1 / $Num2

Write-Host "`n🔢 Calculation: $Num1 ÷ $Num2 = $Result" -ForegroundColor Green

# Additional division information


if ($Result % 1 -eq 0) {
Write-Host " ✓ Result is a whole number" -ForegroundColor Cyan
} else {
Write-Host " ℹ Result is a decimal number" -ForegroundColor Cyan
Write-Host " ℹ Rounded to 4 decimal places: $([math]::Round($Result, 4))" -
}

# Log the operation


$Operation = [PSCustomObject]@{
'Operation' = 'Division'
'Number1' = $Num1
'Number2' = $Num2
'Result' = $Result
'Timestamp' = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
}

return $Operation
}
catch {
Write-Host "❌ Error during division: $($_.[Link])" -ForegroundColor Re
return $null
}
}

# Main Calculator Logic with do-while loop


$CalculationHistory = @()
$SessionStartTime = Get-Date

Write-Host "🚀 Starting Advanced PowerShell Calculator..." -ForegroundColor Green


Write-Host "Session started at: $($[Link]('yyyy-MM-dd HH:mm:ss'))" -Fo

do {
try {
Show-AdvancedCalculatorMenu

# Show calculation count if any calculations have been performed


if ($[Link] -gt 0) {
Write-Host "📊 Calculations performed this session: $($[Link]
}

$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📊 CALCULATION HISTORY:" -ForegroundColor Yellow


$CalculationHistory | Format-Table -AutoSize

# Ask to save history


do {
$SaveChoice = Read-Host "Save calculation history to file? (Y/N)"
if ($[Link]() -eq 'Y') {
try {
$HistoryFile = "CalculatorHistory_$(Get-Date -Format 'yyy
$CalculationHistory | Export-Csv -Path $HistoryFile -NoTy
Write-Host "✅ History saved to: $HistoryFile" -Foreground
break
}
catch {
Write-Host "❌ Error saving file: $($_.[Link])
}
}
elseif ($[Link]() -eq 'N') {
break
}
else {
Write-Host "❌ Invalid choice. Please enter Y or N." -Foregrou
}
} while ($true)
} else {
Write-Host " No calculations performed this session." -ForegroundCo
}

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')
}
}

# Add successful operation to history


if ($OperationResult -ne $null) {
$CalculationHistory += $OperationResult
Write-Host "✅ Operation completed successfully!" -ForegroundColor Green
}

# Continue prompt (only if not exiting)


if ($Choice -ne '4') {
Write-Host "`n" -NoNewline
Read-Host "Press Enter to continue"
}

}
catch {
Write-Host "❌ Unexpected error: $($_.[Link])" -ForegroundColor Red
Write-Host "🔄 Returning to main menu..." -ForegroundColor Yellow
Start-Sleep 2
}

} while ($Choice -ne '4')

Q2: Event Log Audit Script

# Event Log Audit Script


function Get-ValidLogName {
Write-Host "`nAvailable Event Logs:" -ForegroundColor Yellow
$AvailableLogs = Get-WinEvent -ListLog * | Where-Object {$_.RecordCount -gt 0} | Sele
$AvailableLogs | Format-Table -AutoSize

do {
$LogName = Read-Host "Enter Log Name (or 'list' to see available logs again)"

if ($[Link]() -eq 'list') {


$AvailableLogs | Format-Table -AutoSize
continue
}
$LogExists = Get-WinEvent -ListLog $LogName -ErrorAction SilentlyContinue
if ($LogExists) {
return $LogName
} else {
Write-Host "❌ Log '$LogName' not found. Please enter a valid log name." -Fore
}
} while ($true)
}

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)
}

# Main Event Log Audit Script


Write-Host "=====================================" -ForegroundColor Cyan
Write-Host " EVENT LOG AUDIT SCRIPT" -ForegroundColor Green
Write-Host "=====================================" -ForegroundColor Cyan

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

# Validate date range


if ($StartDateTime -ge $EndDateTime) {
throw "Start date must be earlier than end date"
}

$EventType = Get-ValidEventType
Write-Host "✅ Event Type: $($[Link])" -ForegroundColor Green

Write-Host "`n🔍 Starting Event Log Query..." -ForegroundColor Yellow


Write-Host " Log: $LogName"
Write-Host " Period: $($[Link]('yyyy-MM-dd HH:mm:ss')) to $($EndDat
Write-Host " Type: $($[Link])"

# Build filter hashtable


$FilterHashtable = @{
LogName = $LogName
StartTime = $StartDateTime
EndTime = $EndDateTime
}

if ($[Link] -ne $null) {


$FilterHashtable['Level'] = $[Link]
}

# Query events with error handling


try {
$Events = Get-WinEvent -FilterHashtable $FilterHashtable -ErrorAction Stop
Write-Host "✅ Query completed successfully!" -ForegroundColor Green
}
catch {
if ($_.[Link] -like "*No events were found*") {
Write-Host "ℹ No events found matching the specified criteria." -ForegroundCo
$Events = @()
} else {
throw $_.Exception
}
}

if ($[Link] -gt 0) {
Write-Host "`n📊 AUDIT RESULTS:" -ForegroundColor Cyan
Write-Host " Total Events Found: $($[Link])" -ForegroundColor Green

# Process events for export


Write-Host "`n🔄 Processing events for export..." -ForegroundColor Yellow

$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]
}
}

Write-Progress -Activity "Processing Events" -Completed

# Display summary statistics


Write-Host "`n📈 EVENT STATISTICS:" -ForegroundColor Yellow
$EventStats = $ProcessedEvents | Group-Object Level | Sort-Object Count -Descendi
$EventStats | Select-Object Name, Count | Format-Table -AutoSize

# Display top event sources


Write-Host "🏷️ TOP EVENT SOURCES:" -ForegroundColor Yellow
$SourceStats = $ProcessedEvents | Group-Object ProviderName | Sort-Object Count -
$SourceStats | Select-Object Name, Count | Format-Table -AutoSize

# Display sample events (first 5)


Write-Host "📋 SAMPLE EVENTS (First 5):" -ForegroundColor Yellow
$ProcessedEvents | Select-Object -First 5 TimeCreated, Id, Level, ProviderName, M

# 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
}

# Generate summary report


$SummaryReport = [PSCustomObject]@{
'Audit Date' = Get-Date
'Log Name' = $LogName
'Event Type' = $[Link]
'Start Time' = $StartDateTime
'End Time' = $EndDateTime
'Total Events' = $[Link]
'Date Range (Days)' = [math]::Round((New-TimeSpan -Start $StartDateTime -End
'Export File' = $ExportFileName
'Critical Events' = ($ProcessedEvents | Where-Object {$_.Level -eq 'Critical'
'Error Events' = ($ProcessedEvents | Where-Object {$_.Level -eq 'Error'}).Cou
'Warning Events' = ($ProcessedEvents | Where-Object {$_.Level -eq 'Warning'})
'Information Events' = ($ProcessedEvents | Where-Object {$_.Level -eq 'Inform
}

Write-Host "`n📄 AUDIT SUMMARY:" -ForegroundColor Green


$SummaryReport | Format-List

# Save summary report


$SummaryFileName = "EventLogAudit_Summary_$(Get-Date -Format 'yyyyMMdd_HHmmss').c
$SummaryReport | Export-Csv -Path $SummaryFileName -NoTypeInformation
Write-Host "📁 Summary report saved to: $SummaryFileName" -ForegroundColor Green

} 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
}

Write-Host "`n🏁 Event Log Audit Complete!" -ForegroundColor Green

Q3: Service Status Monitor

# Service Status Monitor with Error Handling


function Get-ServiceNames {
do {
$ServiceInput = Read-Host "Enter service names (comma-separated, or 'list' to see

if ($[Link]() -eq 'list') {


Write-Host "`nAvailable Services (first 50):" -ForegroundColor Yellow
Get-Service | Select-Object -First 50 Name, Status, DisplayName | Format-Tabl
continue
}

if ([string]::IsNullOrWhiteSpace($ServiceInput)) {
Write-Host "❌ Please enter at least one service name." -ForegroundColor Red
continue
}

# Split and trim service names


$ServiceNames = $ServiceInput -split ',' | ForEach-Object { $_.Trim() } | Where-O

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'
)

$TimeStamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'


$LogEntry = "[$TimeStamp] [$Level] $Message"

try {
Add-Content -Path $LogFile -Value $LogEntry -ErrorAction Stop
}
catch {
Write-Warning "Failed to write to log file: $($_.[Link])"
}
}

# Main Service Status Monitor


Write-Host "==========================================" -ForegroundColor Cyan
Write-Host " SERVICE STATUS MONITOR" -ForegroundColor Green
Write-Host "==========================================" -ForegroundColor Cyan

# 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

Write-ServiceLog -LogFile $LogFilePath -Message "Monitoring services: $($ServiceNames

# Validate services exist


Write-Host "`n🔍 Validating service names..." -ForegroundColor Yellow
$ValidServices = @()
$InvalidServices = @()

foreach ($ServiceName in $ServiceNames) {


if (Test-ServiceExists -ServiceName $ServiceName) {
$ValidServices += $ServiceName
Write-Host " ✅ $ServiceName - Found" -ForegroundColor Green
} else {
$InvalidServices += $ServiceName
Write-Host " ❌ $ServiceName - Not Found" -ForegroundColor Red
}
}

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 = @()

foreach ($ServiceName in $ValidServices) {


Write-Host " Checking $ServiceName..." -ForegroundColor Cyan

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' }
}

Write-Host " Status: $($[Link])" -ForegroundColor $Stat


Write-ServiceLog -LogFile $LogFilePath -Message "$ServiceName status: $($
} else {
Write-Host " Error: $($[Link])" -ForegroundColor
Write-ServiceLog -LogFile $LogFilePath -Message "$ServiceName error: $($S
}
}
catch {
Write-Host " ❌ Unexpected error: $($_.[Link])" -ForegroundColo
Write-ServiceLog -LogFile $LogFilePath -Message "$ServiceName unexpected erro
}
}

# Display results summary


Write-Host "`n📋 SERVICE STATUS SUMMARY:" -ForegroundColor Green
$ServiceResults | Select-Object ServiceName, DisplayName, Status, StartType, CheckTim

# 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

Write-Host "📈 STATISTICS:" -ForegroundColor Yellow


Write-Host " Total Services Checked: $($[Link])"
Write-Host " Running: $RunningServices" -ForegroundColor Green
Write-Host " Stopped: $StoppedServices" -ForegroundColor Red
Write-Host " Errors: $ErrorServices" -ForegroundColor Red

# Log statistics
Write-ServiceLog -LogFile $LogFilePath -Message "Summary - Total: $($ServiceResults.C

# Export results to CSV


$ExportFileName = "ServiceStatus_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"

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

$CriticalStopped = $ServiceResults | Where-Object {$_.Status -eq 'Stopped' -and $_.St


if ($[Link] -gt 0) {
Write-Host "⚠️ The following automatic services are stopped:" -ForegroundColor Y
$CriticalStopped | ForEach-Object {
Write-Host " - $($_.ServiceName) ($($_.DisplayName))" -ForegroundColor Red
}
Write-Host " Consider investigating and starting these services if needed." -Fo
}

$ManualStopped = $ServiceResults | Where-Object {$_.Status -eq 'Stopped' -and $_.Star


if ($[Link] -gt 0) {
Write-Host "ℹ️ Manual services currently stopped: $($[Link])" -Foreg
Write-Host " These are typically stopped unless needed." -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

# Ask to open log file


$OpenLog = Read-Host "Open log file? (Y/N)"
if ($[Link]() -eq 'Y') {
notepad $LogFilePath
}
}

PowerShell Weekly Assessment {#weekly-assessment}

Complete Solutions for All Questions

# PowerShell Weekly Assessment - All Solutions

Write-Host "========================================" -ForegroundColor Cyan


Write-Host " POWERSHELL WEEKLY ASSESSMENT" -ForegroundColor Green
Write-Host "========================================" -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
}

Write-Host "`n" + "="*50

# 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

# Most recent error details


if ($[Link] -gt 0) {
Write-Host "Most Recent Error Details:" -ForegroundColor Yellow
$RecentError = $ApplicationErrors | Sort-Object TimeGenerated -Descending | S
Write-Host " Time: $($[Link])"
Write-Host " Source: $($[Link])"
Write-Host " Event ID: $($[Link])"
Write-Host " Category: $($[Link])"
Write-Host " Message: $($[Link](0,[Math]::Min(200,$Re
}
} else {
Write-Host "✅ No Error events found in the latest 50 Application log entries" -Fo
}
}
catch {
Write-Host "❌ Error querying Application log: $($_.[Link])" -ForegroundCol
Write-Host "Note: You may need to run PowerShell as Administrator to access Event Log
}

Write-Host "`n" + "="*50

# 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
}

Write-Host "`n" + "="*50

# 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"

$UpdateHotfixes = Get-HotFix | Where-Object {


$_.Description -eq 'Update' -and
$_.InstalledOn -ge $StartDate -and
$_.InstalledOn -le $EndDate
}

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

# Show what updates are available for context


$AllUpdates = Get-HotFix | Where-Object {$_.Description -eq 'Update'}
if ($AllUpdates) {
Write-Host "`nFor reference, here are all 'Update' hotfixes on this system:"
$AllUpdates | Select-Object HotFixID, InstalledOn | Sort-Object InstalledOn -
Select-Object -First 10 | Format-Table -AutoSize
}
}
}
catch {
Write-Host "❌ Error querying hotfixes by date range: $($_.[Link])" -Foregr
}

Write-Host "`n" + "="*50


# Q5: Running Services Filter - Find services with Status "Running" and DisplayName start
Write-Host "`nQ5: Finding Running Services with DisplayName starting with 'Remote'" -Fore
Write-Host "Command: Get-Service | Where-Object {`$_.Status -eq 'Running' -and `$_.Displa

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

# Detailed information for each service


Write-Host "Detailed Service Information:" -ForegroundColor Yellow
foreach ($Service in $RemoteServices) {
Write-Host "`n Service: $($[Link])" -ForegroundColor Cyan
Write-Host " Name: $($[Link])"
Write-Host " Status: $($[Link])" -ForegroundColor Green
Write-Host " Start Type: $($[Link])"
Write-Host " Can Pause/Continue: $($[Link])"
Write-Host " Can Stop: $($[Link])"

# Get additional details from WMI


try {
$ServiceDetails = Get-WmiObject -Class Win32_Service -Filter "Name='$($Se
if ($ServiceDetails) {
Write-Host " Process ID: $($[Link])"
Write-Host " Start Name: $($[Link])"
Write-Host " Path: $($[Link])"
}
}
catch {
Write-Host " Additional details: Not available"
}
}

# Service dependency information


Write-Host "`nService Dependencies:" -ForegroundColor Yellow
foreach ($Service in $RemoteServices) {
try {
$Dependencies = Get-Service -Name $[Link] -DependentServices
if ($Dependencies) {
Write-Host " $($[Link]) has $($[Link]) depe
$Dependencies | ForEach-Object {
Write-Host " - $($_.DisplayName) ($($_.Status))" -ForegroundCo
}
}
}
catch {
# No dependencies or error retrieving
}
}

} else {
Write-Host "❌ No running services found with DisplayName starting with 'Remote'"

# Show stopped remote services for context


$StoppedRemoteServices = Get-Service | Where-Object {$_.Status -eq 'Stopped' -and
if ($StoppedRemoteServices) {
Write-Host "`nStopped services with DisplayName starting with 'Remote':" -For
$StoppedRemoteServices | Select-Object Name, DisplayName, Status, StartType |
}

# Show all services starting with Remote regardless of status


$AllRemoteServices = Get-Service | Where-Object {$_.DisplayName -like 'Remote*'}
if ($AllRemoteServices) {
Write-Host "`nAll services with DisplayName starting with 'Remote' (any statu
$AllRemoteServices | Select-Object Name, DisplayName, Status, StartType | For
}
}
}
catch {
Write-Host "❌ Error querying services: $($_.[Link])" -ForegroundColor Red
}

# 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 "`nQuestions Completed:" -ForegroundColor Yellow


$CompletedQuestions | ForEach-Object { Write-Host " ✅ $_" -ForegroundColor Green }

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

Common questions

Powered by AI

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 .

You might also like