DEV Community

Excalibra
Excalibra

Posted on

Script for checking Windows baselines

Script for checking Windows baselines, which will facilitate on-site troubleshooting and fault analysis. The baseline script covers a wide range of topics.

Target Audience: This is suitable for desktop support engineers, network engineers in small and micro enterprises, IT security personnel in administrative and logistical roles, HR information specialists, and computer enthusiasts, among others.

Usage

Instructions:

1. Open PowerShell
Run the following command to set the execution policy:

Set-ExecutionPolicy RemoteSigned
Enter fullscreen mode Exit fullscreen mode

2. Copy and run the script
Copy the following code into your PowerShell and execute it:

irm https://ghfast.top/https://raw.githubusercontent.com/Excalibra/scripts/refs/heads/main/d-pwsh/frontline_helpdesk.ps1|iex
Enter fullscreen mode Exit fullscreen mode
  1. Note: The first time you execute item [8], you need to be connected to the internet to load the Import-Excel module.

Terminal Reference Legend

Initial

Function 1: Check IP Network
Function 2: Printers and Scanners
Function 3: Check Hard Drive, CPU, Memory, Graphics Card Drivers, etc.
Function 4: Check Device Security, Recent Updates, Scheduled Tasks
Function 5: Check Host Active Sharing Protocol Information
Function 6: Check Computer Sleep, Restart Frequency, Unexpected Shutdowns, Program Crashes, etc.

Function 8: View Instructions

Note: Function 7 executes all functions. The above legend provides detailed descriptions for each function, so Function 8 is selected.

Report Generation Reference Legend

1. Device Driver Information

Image description

2. Summary of "Warning," "Error," and "Critical" Events

Note: There will be slight adjustments at the end, changing from the current day to within the last three days, excluding the following event IDs:

134, 1014, 8233, 10010, 10016
4648, 4634, 4199, 6013, 4803, 4802, 4800, 4801

The three-day timeframe is to capture prior signs. For information on event IDs, please refer to:

https://github.com/Excalibra/scripts/blob/main/AQUICK/BITRH/Win10_Events_ID_useful.xlsx

3. Activity Log

4. Threat Detection Records

Image description

5. Threat Category Details

Image description

Source Code Section
Due to space constraints, the source code is quite lengthy, with over a thousand lines, so I have shortened some explanatory text functions.

Note
The publicly available source code serves as a master template, functioning as a baseline for troubleshooting template code.

Attached Source Code: https://github.com/Excalibra/scripts/blob/main/d-pwsh/frontline_helpdesk.ps1

# Check Hostname, System Installation Date, Boot Time, Uptime, and System Architecture
function check_sys {

    Clear-Host
    Write-Host "`n"
    Write-Host "### Basic Host Information ###" -ForegroundColor Cyan

    Get-ComputerInfo | Select-Object -Property `
        OsRegisteredUser, CsDomain, CsDNSHostName, OsName,
    OsInstallDate, OsLastBootUpTime, OsUptime, OsArchitecture `
    | Out-Host
}

# Check IP and Network Device Connection Status
function check_ip {

    Write-Host " "
    Write-Host "### Checking Basic Network Connectivity ###`n" -ForegroundColor Cyan

    Write-Host "--- Checking IP address and whether the proxy is enabled (1 for enabled, 0 for disabled) ---"  -ForegroundColor Yellow
    netsh interface ipv4 show addresses "Ethernet"
    netsh interface ipv4 show dnsservers "Ethernet"
    Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' | Select-Object ProxyEnable

    Write-Host "--- Checking Local Area Network (LAN) connection  ---`n"  -ForegroundColor Yellow
    $result = Get-NetConnectionProfile | Select-Object -Property Name, InterfaceAlias, NetworkCategory
    if ($result) {
        $result | Out-Host
    }
    else {
        Write-Host "There is an issue with this network.`n" -ForegroundColor DarkRed
    }

    Write-Host "--- Checking if there have been any recent IP conflicts ---`n"  -ForegroundColor Yellow

    $result = Get-WinEvent -FilterHashtable @{
        LogName   = 'System'
        StartTime = (Get-Date).Date.AddDays(-14)
    } | Where-Object {
        ($_.Id -in 4199)
    } | Select-Object Id, Level, ProviderName, LogName, `
        TimeCreated, LevelDisplayName, TaskDisplayName

    if ($result) {
        $result | Out-Host
    }
    else {
        Write-Host "No IP conflict events have occurred recently.`n" -ForegroundColor Green
    }

    Write-Host "### Basic Network Connectivity Check Completed`n" -ForegroundColor Green
}

# Check Printer Status Details
function check_printer {

    Write-Host " "
    Write-Host "### Checking Printer Status ###`n" -ForegroundColor Cyan

    Write-Host "--- Checking Printer Service and Number of Connected Printers ---"  -ForegroundColor Yellow
    Get-Service | findstr "Spooler" | Out-Host

    Write-Host "--- Checking if there are files in the print queue ---"  -ForegroundColor Yellow
    Get-ChildItem C:\Windows\System32\spool\PRINTERS

    $result = Get-Printer | Select-Object Name, PrinterStatus
    if ($result) {
        $result | Out-Host
    }
    else {
        Write-Host "No virtual or physical printers are configured" -ForegroundColor DarkRed
    }

    Write-Host "--- Checking if a default printer is set ---"  -ForegroundColor Yellow

    $result = Get-CimInstance -Class Win32_Printer | Where-Object { $_.Default -eq $true } | Select-Object Name
    if ($result) {
        $result | Out-Host
    }
    else {
        Write-Host "No default printer is configured" -ForegroundColor Magenta
    }

    Write-Host "--- Checking if Scanner Service is present ---"  -ForegroundColor Yellow

    $result = Get-Service stisvc
    if ($result) {
        $result | Out-Host
    }
    else {
        Write-Host "Scanner service is missing" -ForegroundColor Magenta
    }

    Write-Host "`n### Printer Status Check Completed`n" -ForegroundColor Green
}

# Check hard disk, CPU, and memory information
function check_disk_cpu_mem {

    # [math]::Round is used to call static methods or properties from the .NET Framework.
    # For more details: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_arithmetic_operators?view=powershell-7.3
    Write-Host " "
    Write-Host "### Starting to check disk, CPU, memory, and system drivers ###`n"  -ForegroundColor Cyan

    Write-Host "--- Checking disk type and capacity ---"  -ForegroundColor Yellow
    $result = Get-PhysicalDisk
    if ($result) {
        $result | Out-Host
    }
    else {
        Write-Host "Unable to retrieve disk type and capacity`n"  -ForegroundColor Red
    }

    Write-Host "--- Checking disk partitions and available space ---"  -ForegroundColor Yellow
    $result = Get-Volume
    if ($result) {
        $result | Out-Host
    }
    else {
        Write-Host "Unable to retrieve disk partitions and available space`n"  -ForegroundColor Red
    }

    Write-Host "--- Checking CPU parameters ---"  -ForegroundColor Yellow
    $result = Get-CimInstance -Class Win32_Processor | Select-Object Caption, MaxClockSpeed
    if ($result) {
        $result | Out-Host
    }
    else {
        Write-Host "Unable to retrieve CPU parameters`n"  -ForegroundColor Red
    }

    Write-Host "--- Checking memory module parameters and types ---`n"  -ForegroundColor Yellow
    Write-Host "DDR1: Below 400 MHz, DDR2: Below 800 MHz, DDR3: Below 2133 MHz, DDR4: Below 3200 MHz."

    $result = Get-CimInstance -Class Win32_PhysicalMemory |
    Select-Object -Property BankLabel,
    @{Name = "Capacity(GB)"; Expression = { [math]::Round($_.Capacity / 1GB, 2) } },
    DeviceLocator, PartNumber, SerialNumber, Speed
    if ($result) {
        $result | Out-Host
    }
    else {
        Write-Host "Unable to retrieve memory module parameters and types`n"  -ForegroundColor Red
    }


    Write-Host "--- Checking display parameters status ---"  -ForegroundColor Yellow

    $videoController = Get-CimInstance -Class Win32_VideoController -ErrorAction SilentlyContinue

    if ($videoController) {

        $Name = $videoController.Name
        $DriverVersion = $videoController.DriverVersion
        $AdapterCompatibility = $videoController.AdapterCompatibility
        $Status = $videoController.Status
        $AdapterRAM = [System.Math]::Round($videoController.AdapterRAM / (1024 * 1024 * 1024), 2)
        $CurrentHorizontalResolution = $videoController.CurrentHorizontalResolution
        $CurrentVerticalResolution = $videoController.CurrentVerticalResolution
        $VideoModeDescription = $videoController.VideoModeDescription
        $MaxRefreshRate = $videoController.MaxRefreshRate

        if ([string]::IsNullOrEmpty($Name)) { $Name = "N/A" }
        if ([string]::IsNullOrEmpty($AdapterCompatibility)) { $Name = "N/A" }
        if ([string]::IsNullOrEmpty($Status)) { $Status = "N/A" }
        if ([string]::IsNullOrEmpty($DriverVersion)) { $DriverVersion = "N/A" }
        if ([string]::IsNullOrEmpty($AdapterRAM)) { $AdapterRAM = "N/A" }

        if ([string]::IsNullOrEmpty($CurrentHorizontalResolution)) { $CurrentHorizontalResolution = "N/A" }
        if ([string]::IsNullOrEmpty($CurrentVerticalResolution)) { $CurrentVerticalResolution = "N/A" }
        if ([string]::IsNullOrEmpty($VideoModeDescription)) { $VideoModeDescription = "N/A" }
        if ([string]::IsNullOrEmpty($MaxRefreshRate)) { $MaxRefreshRate = "N/A" }

        Write-Host " "
        Write-Host "Graphics Driver:$Name"
        Write-Host "Driver Version:$DriverVersion"
        Write-Host "Status:$Status"
        Write-Host "Video Memory (GB):$AdapterRAM"
        Write-Host "Platform Compatibility:$AdapterCompatibility"
        Write-Host "Max Refresh Rate:$MaxRefreshRate"
        Write-Host "Current Horizontal Resolution:$CurrentHorizontalResolution"
        Write-Host "Current Vertical Resolution:$CurrentVerticalResolution"
        Write-Host "Video Mode Description:$VideoModeDescription"
        Write-Host " "
    }
    else {
        Write-Host "Failed to detect Video Controller.`n"
    }

    Write-Host "`n--- Checking display device details ---`n"  -ForegroundColor Yellow

    $monitor_id = Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | Select-Object -First 1

    if ($null -ne $monitor_id) {
        $Manufacturer = [System.Text.Encoding]::UTF8.GetString($monitor_id.ManufacturerName)
        $ProductCode = [System.Text.Encoding]::UTF8.GetString($monitor_id.ProductCodeID)
        $SerialNumber = [System.Text.Encoding]::UTF8.GetString($monitor_id.SerialNumberID)
        $UserFriendlyNameLength = $monitor_id.UserFriendlyNameLength
        $UserFriendlyNameBytes = $monitor_id.UserFriendlyName[0..($UserFriendlyNameLength - 1)]

        if ($null -ne $UserFriendlyNameBytes) {
            $UserFriendlyName = [System.Text.Encoding]::UTF8.GetString($UserFriendlyNameBytes)
        }
        else {
            $UserFriendlyName = "N/A"
        }

        $WeekOfManufacture = $monitor_id.WeekOfManufacture
        $YearOfManufacture = $monitor_id.YearOfManufacture

        Write-Host "Active: $($monitor_id.Active)"
        Write-Host "Instance Name: $($monitor_id.InstanceName)"
        Write-Host "Manufacturer: $Manufacturer"
        Write-Host "Product Code: $ProductCode"
        Write-Host "Serial Number: $SerialNumber"
        Write-Host "User-friendly name: $UserFriendlyName (Length: $UserFriendlyNameLength)"
        Write-Host "Week of Manufacture: $WeekOfManufacture"
        Write-Host "Year of Manufacture: $YearOfManufacture"
    }
    else {
        Write-Host "`nNo specific display information found.`n" -ForegroundColor Red
    }

    Write-Host "`n--- Checking motherboard details ---"  -ForegroundColor Yellow

    $result = Get-CimInstance -Class Win32_BaseBoard | Select-Object Manufacturer, Product, Model, SerialNumber
    if ($result) {
        $result | Format-List
    }
    else {
        Write-Host "`nNo motherboard details found`n"  -ForegroundColor Green
    }

    Write-Host "`n--- Checking for driver issues ---`n"  -ForegroundColor Yellow
    $result = Get-PnpDevice | Where-Object { $_.Status -ne "Ok" }
    if ($result) {
        $result | Select-Object FriendlyName, Status | Out-Host
    }
    else {
        Write-Host "Device drivers are operating normally`n"  -ForegroundColor Green
    }
    Write-Host "### Disk, CPU, memory, and system driver check completed`n"  -ForegroundColor Green
}

# Check the firewall status and whether specific port rules are open (initial functionality)
# Check device security, recent upgrade patches, and scheduled tasks
function check_fw {

    Write-Host " "
    Write-Host "### Checking device security, recent patch upgrades, scheduled tasks, certificate policies, and system core file access control ###`n" -ForegroundColor Cyan

    Write-Host "--- Checking the status of Windows Defender Real-time ProtectionChecking the status of Windows Defender Real-time Protection ---"  -ForegroundColor Yellow
    Get-MpComputerStatus | Select-Object -Property RealTimeProtectionEnabled, AntivirusEnabled | Out-Host

    Write-Host "--- Checking if the firewall is enabled ---"  -ForegroundColor Yellow
    Get-NetFirewallProfile | Select-Object Name, Enabled | Out-Host

    Write-Host "--- Checking if Remote Desktop and ICMP ping firewall rules are enabled ---"  -ForegroundColor Yellow
    Get-NetFirewallRule -DisplayName "Remote Desktop*", "Core Network Diagnostics*ICMPv4*" | Select-Object DisplayName, Enabled | Out-Host

    Write-Host "--- Checking recent patches installed on the host ---`n"  -ForegroundColor Yellow
    Get-HotFix | Sort-Object -Property InstalledOn -Descending | Select-Object -First 9 | Out-Host

    Write-Host "--- Checking non-system scheduled tasks ---`n"  -ForegroundColor Yellow

    Get-ScheduledTask | Where-Object { $_.TaskPath -notlike "*Microsoft*" -and $_.TaskName -notlike "*Microsoft*" } `
    | Get-ScheduledTaskInfo | Select-Object TaskName, LastRunTime, NextRunTime | Format-table

    Write-Host "--- Checking system-level software auto-start (Run) ---`n" -ForegroundColor Yellow

    Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -ErrorAction SilentlyContinue `
    | Select-Object * -ExcludeProperty PSPath, PSChildName, PSDrive, PSParentPath, PSProvider, *Microsoft* | Format-List

    Write-Host "--- Checking user-level software auto-start (Run) ---`n" -ForegroundColor Yellow

    Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -ErrorAction SilentlyContinue `
    | Select-Object * -ExcludeProperty PSPath, PSChildName, PSDrive, PSParentPath, PSProvider, *Microsoft* | Format-List

    Write-Host "--- Checking system and user-level software that runs only once (RunOnce) ---`n" -ForegroundColor Yellow

    # System-level HKLM
    $run_once_path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
    if ((-not (Test-Path $run_once_path)) -or ($null -eq (Get-ItemProperty -Path $run_once_path))) {
        # Write-Warning "RunOnce property not found."
        Write-Host "No system-level one-time auto-start entries found`n" -ForegroundColor Green
    }
    else {
        Get-ItemProperty -Path $run_once_path `
        | Select-Object * -ExcludeProperty PSPath, PSChildName, PSDrive, PSParentPath, PSProvider, *Microsoft* | Format-List
    }
    # User-level HKCU
    if (-not (Test-Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce")) {
        Write-Host "No user-level one-time auto-start entries found`n"  -ForegroundColor Green
    }
    else {
        Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" `
        | Select-Object * -ExcludeProperty PSPath, PSChildName, PSDrive, PSParentPath, PSProvider, *Microsoft* | Format-List
    }

    Write-Host "--- Checking for evaluation version automatic restart registry (Enterprise version) ---`n" -ForegroundColor Yellow
    if (Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Services\WLMS") {
        $result = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\WLMS"
        Write-Host "Solution for Windows system automatically shutting down periodically:" -ForegroundColor Yellow -NoNewline
        Write-Host "http://www.yvsy.com/501.html" -ForegroundColor Blue
        $result | Select-Object ImagePath, Start | Format-List
    } else {
        Write-Host "No related registry for evaluation version found`n" -ForegroundColor Green
    }

    Write-Host "--- Checking for malicious image hijacking ---`n" -ForegroundColor Yellow

    $result = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\*" | Where-Object { $_.debugger -eq "\" }
    if ($null -eq $result) {
        Write-Host "No malicious image hijacking registry found`n" -ForegroundColor Green
    }else {
        $result|Select-Object{$_.PSPath}|Format-List
    }

    Write-Host "`n--- Checking for disabled certificate checks ---`n" -ForegroundColor Yellow

    # Get-ChildItem -Path 'Cert:\LocalMachine\Root' | Format-List *
    $result = Get-ChildItem -Path 'Cert:\LocalMachine\Disallowed' | Select-Object Subject, PSPath, NotBefore, NotAfter, Thumbprint
    if ($null -eq $result) {
        Write-Host "No disabled certificate checks found`n" -ForegroundColor Green
    }else {
        $result|Format-List
    }

    Write-Host "`n--- Checking if system core files are denied access ---`n" -ForegroundColor Yellow
    Write-Host "Normally, the host should contain these four: FxsTmp, Recovery, SleepStudy, WDI (Virtual machines do not have FxsTmp)`n"

   $result = Get-Acl -Path C:\Windows\System32\*|Where-Object{$_.AccessToString -like "*Deny*"}|Select-Object Path
   if ($null -eq $result) {
        Write-Host "No related records found, please ensure the script is run as administrator`n" -ForegroundColor DarkMagenta
    }else {
        $result|Format-List
    }

    Write-Host "### Checking device security, recent patch upgrades, scheduled tasks, certificate policies, and system core file access control, completed`n" -ForegroundColor Green
}

# Share Check (including: shared ports, shared files)
function check_share {

    Write-Host " "
    Write-Host "### Checking host's shared resource security (basic checks only: default ports, shared files) ###`n" -ForegroundColor Cyan

    Write-Host "--- Checking if the firewall is enabled (for easier viewing) ---"  -ForegroundColor Yellow
    Get-NetFirewallProfile | Select-Object Name, Enabled | Out-Host

    Write-Host "--- Checking if SMB 1.0 functionality is enabled for accessing local network resources ---"  -ForegroundColor Yellow
    Get-WindowsOptionalFeature -Online | Where-Object FeatureName -eq "SMB1Protocol" | Out-Host

    Write-Host "--- Checking if the host has shared files with other computers using SMB ---`n" -ForegroundColor Yellow

    # https://support.microsoft.com/en-gb/windows/file-sharing-over-a-network-in-windows-b58704b2-f53a-4b82-7bc1-80f9994725bf    Write-Host "SMB服务检测"
    Get-Service | Where-Object { $_.Name -match 'LanmanServer' } | Out-Host

    $result = Get-SmbShare | Select-Object Name, Path, Description
    if ($result) {
        $result | Out-Host
    }
    else {
        Write-Host "No shared files found.`n" -ForegroundColor Green
    }

    Write-Host "--- Checking if the host has an active FTP sharing service ---" -ForegroundColor Yellow

    $result = Get-Service | Where-Object { $_.Name -match 'ftp' }
    if ($result) {
        $result | Out-Host
    }
    else {
        Write-Host "`nNo active FTP service found.`n" -ForegroundColor Green
    }

    Write-Host "--- Checking if Remote Desktop is enabled: 0 is enabled, 1 is disabled ---" -ForegroundColor Yellow
    Get-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -Name "fDenyTSConnections" | Select-Object fDenyTSConnections | Out-Host

    # Remote Desktop Service
    Get-Service | Where-Object { $_.Name -match 'TermService' } | Out-Host

    Write-Host "--- Checking for Suspicious Remote Desktop (SRP) login behavior in the last month ---`n"  -ForegroundColor Yellow
    $result = Get-WinEvent -FilterHashtable @{
        LogName   = 'Security';
        ID        = 4624, 4625;
        StartTime = (Get-Date).Date.AddDays(-30);
        Message   = '*Remote Desktop*'
    } -ErrorAction SilentlyContinue
    if ($result) {
        $result | Out-GridView -Title "Suspicious Remote Desktop (SRP) Login Records"
    }
    else {
        Write-Host "No suspicious Remote Desktop login behavior found in the last 30 days.`n" -ForegroundColor Green
    }
    Write-Host "### Share Resource Check (including: shared ports, shared files) is complete`n" -ForegroundColor Green
}

# Event Query
function check_key_events {

    Write-Host " "
    Write-Host "### Checking computer events such as sleep, shutdown/restart, and program crashes ###`n" -ForegroundColor Cyan

    # View local users and user groups
    Write-Host "--- Checking local user status ---`n" -ForegroundColor Yellow
    localuser | Out-Host
    Get-LocalGroupMember -Group Administrators | Out-Host

    Write-Host "--- Checking local users with no password set ---`n" -ForegroundColor Yellow
    Get-LocalUser | Where-Object { $null -eq $_.Password } | Select-Object Name | Out-Host

    # New: Check the system sleep state independently
    # Difference between Hibernate and Sleep: https://excalibra.github.io/2025/01-19/01
    Write-Host "--- Checking if sleep functionality is enabled. (AC Power: plugged in; DC Power: on battery) ---`n" -ForegroundColor Yellow
    Write-Host 'Note: For desktop PCs and virtual machines, you may ignore "lid close or open" information.' -ForegroundColor Green

    powercfg -q SCHEME_BALANCED SUB_SLEEP STANDBYIDLE; powercfg -q SCHEME_BALANCED SUB_BUTTONS | Out-Host

    Write-Host "--- Restart frequency in the last two weeks ---"  -ForegroundColor Yellow

    # Reference: [codeantenna - Windows system log shutdown, restart events](https://codeantenna.com/a/QEcwIkyexa)
    # When multiple IDs describe the same term, check the Message attribute for fine distinctions
    $result = Get-WinEvent -FilterHashtable @{
        LogName      = 'System'
        ProviderName = 'User32'
        Id           = 1074
        StartTime    = (Get-Date).Date.AddDays(-14)
    }

    if ($result) {
        $result | Out-Host
        $sum = ($result | Measure-Object).Count
        Write-Host "Total restarts:"$sum, "times$i; Average restarts per day:"$([math]::Round($sum / 14, 2)),"times" -ForegroundColor Green

        # Calculate daily restart count and find the highest
        $dateCounts = @{}
        foreach ($event in $result) {
            # Convert to string, keep only the date part
            $date = $event.TimeCreated.ToShortDateString()
            # If the date exists, increment the count, otherwise initialize to 1
            if ($dateCounts.Contains($date)) {
                $dateCounts[$date] += 1
            }
            else {
                $dateCounts[$date] = 1
            }
        }
        # Find the maximum value
        $maxDate = ($dateCounts.GetEnumerator() | Sort-Object -Property Value -Descending | Select-Object -First 1).Name
        $maxCount = $dateCounts[$maxDate]
        Write-Host "Date with most restarts: $maxDate, and the number of restarts on that day: $maxCount" -ForegroundColor Cyan

    }
    else {
        Write-Host "No restart data found for the last 14 days."-ForegroundColor DarkRed
    }

    # Event ID 41 - Unexpected Shutdown, Event ID 6008 - Abnormal Shutdown
    Write-Host "`n--- Checking for abnormal startups and shutdowns in the last 2 weeks ---`n" -ForegroundColor Yellow
    $result = Get-WinEvent -FilterHashtable @{
        LogName   = 'System'
        Id        = 41, 6008
        StartTime = (Get-Date).Date.AddDays(-14)
    } -ErrorAction SilentlyContinue

    if ($result) {
        # $result | Out-GridView -Title "Abnormal startup and shutdown events in the last 2 weeks"
        $result | Out-Host
    }
    else {
        Write-Host "No abnormal shutdowns or startups in the last 2 weeks.`n" -ForegroundColor Green
    }

    Write-Host "--- Checking for blue screens or crashes in the last 7 days ---`n"  -ForegroundColor Yellow
    # https://social.microsoft.com/Forums/zh-CN/068ccdf2-96f4-484d-a5cb-df05f59e1959/win1020107202142659730475221202010720214id1000652921001?forum=window7betacn
    $result = Get-WinEvent -FilterHashtable @{
        LogName   = 'System'
        Id        = 1001 # Event ID 1001 corresponds to multiple LogNames, and each LogName has different levels for ID 1001.
        StartTime = (Get-Date).Date.AddDays(-7)
    } -ErrorAction SilentlyContinue

    if ($result) {
        $result | Out-Host
    }
    else {
        Write-Host "No blue screens or crashes in the last 7 days.`n" -ForegroundColor Green
    }

    shoudong_check

    Write-Host "`n### Checking computer events such as sleep, shutdown/restart, and program crashes is complete`n" -ForegroundColor Green
}

# Manual Input Check
function shoudong_check{

    Write-Host "--- Enter a time period and check for abnormal warnings and error events relative to the current time ---`n"  -ForegroundColor Yellow

    do {
        # Get the user input for date and time
        $dateTimeString = Read-Host "Please enter the date and time in the format yyyy-MM-dd HH:mm e.g., 2023-06-09 13:01 or enter K to skip"

        if ($dateTimeString -eq 'K' -or $dateTimeString -eq 'k') {
            Write-Host "Skipped." -ForegroundColor Yellow
            return
        }

        try {
            # Use Get-Date to try and convert the string to a date-time object
            $startTime = Get-Date $dateTimeString
            break
        }
        catch {
            # If conversion fails, prompt the user to re-enter
            Write-Host "The entered format is invalid. Please re-enter." -ForegroundColor Yellow
        }
    } while ($true)

    # Build the filter and retrieve abnormal events
    $filter = @{
        LogName   = 'Application', 'System', 'Security'
        StartTime = $startTime
    }

    $events = Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue `
    | Where-Object { $_.LevelDisplayName -in "Error", "Warning", "Critical" }

    if ($events) {
        $events | Out-GridView -Title "Recent and Current Abnormal Warnings and Error Events"
    }
    else {
        Write-Host "No abnormal events found." -ForegroundColor Green
    }
}

# Generate Baseline Report
function try_csv_xlsx {

    Write-Host " "
    Write-Host '### Generating "Device Information"、"Event Summary"、"Activity Records"、and "Windows Defender Threat Overview" analysis reports ###' -ForegroundColor Cyan; Write-Host " "

    # Check if PowerShell version supports ImportExcel module
    if ($PSVersionTable.PSVersion.Major -lt 5) {
        Write-Host "The current PowerShell version does not support the ImportExcel module. Please upgrade to PowerShell version 5 or higher." -ForegroundColor Red
        return
    }

    # Attempt to install ImportExcel module
    try {
        if (!(Get-Module -Name ImportExcel -ListAvailable)) {
            Install-Module ImportExcel -Force
        }
    }
    catch {
        Write-Host "Failed to install the ImportExcel module$i; please ensure the network is functioning properly:" -ForegroundColor Red
        Write-Host $_.Exception.Message -ForegroundColor Red
        return
    }


    # Get the current user's Desktop directory path, more portable than ${env:username}/desktop
    $desktop_path = [Environment]::GetFolderPath('Desktop')
    $report_path = Join-Path $desktop_path ((Get-Date).ToString('yyyy-MM-dd') + 'Baseline_Check_Report.xlsx')

    Write-Host "`nDevice information and warning event summary are being generated. Please wait a few minutes... `n" -ForegroundColor Yellow

    # Device driver information
    #  -ErrorAction SilentlyContinue
    $result = Get-PnpDevice | Select-Object `
        Class, FriendlyName, Problem, `
        Status, ConfigManagerUserConfig, SystemName, `
        ClassGuid, Manufacturer, Present, Service

    if ($result) {
        $result | Export-Excel -Path $report_path -WorksheetName "Device Driver Info"
        Write-Host "Driver information summary completed" -ForegroundColor Green
    }
    else {
        Write-Host 'No matching information found. Please check account permissions, event log settings, etc.'
    }

    # Write-Host "`nGenerating statistics on important events for today up to this point...`n" -ForegroundColor Yellow
    # # Event ID, see:https://github.com/Excalibra/scripts/blob/main/AQUICK/BITRH/Win10_Events_ID_useful.xlsx
    # $result = Get-WinEvent -FilterHashtable @{
    #     LogName   = 'Application', 'System', 'Security'
    #     StartTime = (Get-Date).Date
    # } | Where-Object { $_.LevelDisplayName -in "Error", "Warning", "Critical"
    # } | Select-Object Message, Id, Level, ProviderName, LogName, `
    #     TimeCreated, LevelDisplayName | Where-Object {
    #     $_.LevelDisplayName -in "Error","Warning","Critical" `
    #     -and $_.Id -notin 134, 1014, 8233, 10010, 10016, 6155 `
    #     -or $_.Id -in 4648, 4634, 4199, 6013, 4803, 4802, 4800, 4801
    # }

    Write-Host "`nCurrently compiling important events from the past five days. This may take some time, so please be patient...`n" -ForegroundColor Yellow
    # Event ID, see: https://github.com/Excalibra/scripts/blob/main/AQUICK/BITRH/Win10_Events_ID_useful.xlsx
    # Subsequent reference: https://learn.microsoft.com/en-us/answers/questions/961608/event-id-6155-(the-lsa-package-is-not-signed-as-ex

    $elapsedTime = (Measure-Command {
        $result = Get-WinEvent -FilterHashtable @{
        LogName   = 'Application', 'System', 'Security'
        StartTime = (Get-Date).Date.AddDays(-5).AddHours(8.5)
        EndTime   = (Get-Date)
    } | Where-Object {
        $_.LevelDisplayName -in "Error","Critical"
    } | Select-Object Id, Level, ProviderName, LogName, `
        TimeCreated, LevelDisplayName, Message, @{Name="TaskDisplayName"; Expression={If($_.TaskDisplayName){$_.TaskDisplayName}else{'N/A'}}}

    if ($result) {
        $result | Export-Excel -Path $report_path -WorksheetName '预警事件汇总'
    }
    else {
        Write-Host 'No “Warning”、“Error”、or “Critical” events found in the last five days. All is normal, so this report was not generated.' -ForegroundColor Green
    }
}).TotalSeconds

    Write-Host "Filtered and processed important events from the last five days in ${elapsedTime} seconds." -ForegroundColor Yellow

    Write-Host "`nAppending logon/logoff activity records from the past week and system power usage reports from the last three days...`n"

    $result = Get-WinEvent -FilterHashtable @{
        LogName   = 'Application', 'System', 'Security'
        StartTime = (Get-Date).Date.AddDays(-7)
    } | Where-Object {
        ($_.Id -in 4648, 4634)
    } |Select-Object MachineName, Id, Level, ProviderName, LogName,  `
    TimeCreated, ContainerLog, LevelDisplayName, TaskDisplayName

    if ($result) {
        $result | Export-Excel -Path $report_path -WorksheetName "Logon and Logoff Activity"
    }
    else {
        Write-Host 'No matching entries found. Please check system permissions, event logs, etc.' -ForegroundColor Red
    }

    powercfg /spr /duration 3

    # SQLlite with Get-MpThreatDetection and Get-MpThreat for better threat data
    # Using Excel to import security threat detection statistics

    # Threat detection records for the past 30 days
    Write-Host " "
    Write-Host 'Detecting stored threats and generating a monthly overview report (if no threats, this report will not be generated)' -ForegroundColor Yellow

    $result = Get-MpThreatDetection `
    | Select-Object ActionSuccess, CurrentThreatExecutionStatusID, `
        DetectionID, DetectionSourceTypeID, DomainUser, InitialDetectionTime, LastThreatStatusChangeTime, `
        ProcessName, ThreatID, ThreatStatusID

    if ($result) {
        $result | Export-Excel -Path $report_path -WorksheetName "Threat Detection Records"
    }
    else {
        Write-Host 'No threat events detected. Possible reasons: third-party antivirus software taking control, or Windows Defender is not enabled.' -ForegroundColor Magenta
    }

    # Threat categories in the last 30 days
    $result = Get-MpThreat `
    | Select-Object CategoryID, DidThreatExecute, IsActive, RollupStatus, `
        SeverityID, ThreatID, ThreatName

    if ($result) {
        $result | Export-Excel -Path $report_path -WorksheetName "Threat Category Details"
    }
    else {
        Write-Host 'No threat events detected. Possible reasons: third-party antivirus took over, or Windows Defender is not enabled.' -ForegroundColor Magenta
    }

    Write-Host " "
    Write-Host '### Baseline check report has been generated. Please check the desktop location.' -ForegroundColor Green; Write-Host "`n"

}


# switch
function select_option {

    # Instructions
    sel_man

    $valid_option = $true
    $has_checked_sys = $false

    while ($valid_option) {

        # Virtual key codes and corresponding keyboard keys reference
        # https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
        $key = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown").VirtualKeyCode

        switch ($key) {
            { $_ -in 49, 97 } {
                # Number key 1 and numeric keypad 1
                if (!$has_checked_sys) {
                    check_sys
                    $has_checked_sys = $true
                }
                check_ip
            }
            { $_ -in 50, 98 } {
                # Number key 2 and numeric keypad 2
                if (!$has_checked_sys) {
                    check_sys
                    $has_checked_sys = $true
                }
                check_printer
            }
            { $_ -in 51, 99 } {
                # Number key 3 and numeric keypad 3
                if (!$has_checked_sys) {
                    check_sys
                    $has_checked_sys = $true
                }
                check_disk_cpu_mem
            }
            { $_ -in 52, 100 } {
                # Number key 4 and numeric keypad 4
                if (!$has_checked_sys) {
                    check_sys
                    $has_checked_sys = $true
                }
                check_fw
            }
            { $_ -in 53, 101 } {
                # Number key 5 and numeric keypad 5
                if (!$has_checked_sys) {
                    check_sys
                    $has_checked_sys = $true
                }
                check_share
            }
            { $_ -in 54, 102 } {
                # Number key 6 and numeric keypad 6
                if (!$has_checked_sys) {
                    check_sys
                    $has_checked_sys = $true
                }
                check_key_events
            }
            { $_ -in 55, 103 } {
                # Number key 7 and numeric keypad 7
                if (!$has_checked_sys) {
                    check_sys
                    $has_checked_sys = $true
                }
                check_ip
                check_printer
                check_fw
                check_disk_cpu_mem
                check_key_events
            }
            { $_ -in 56, 104 } {
                # Number key 8 and numeric keypad 8
                if (!$has_checked_sys) {
                    check_sys
                    $has_checked_sys = $true
                }
                try_csv_xlsx
            }
            { $_ -in 57, 105 } {
                # Number key 9 and numeric keypad 9
                if (!$has_checked_sys) {
                    check_sys
                    $has_checked_sys = $true
                }
                dev_man
            }
            191 {
                # Keyboard /?
                # Remote call
                # Invoke-Expression ((New-Object Net.WebClient).DownloadString($url));$function
                sel_man
            }
            Default {
                # $valid_option = $false
                continue
            }
        }
    }
}

select_option
Enter fullscreen mode Exit fullscreen mode

Top comments (0)