#region Windows Event Log Analysis
function Get-LIMSWindowsEvents {
param(
[int]$Hours = 24,
[string[]]$LogNames = @("Application", "System", "Security"),
[string[]]$Sources = @("ASP.NET", "IIS", "W3SVC", "WAS"),
[string]$OutputPath = "C:\temp\lims_events.txt"
)
$startTime = (Get-Date).AddHours(-$Hours)
$allEvents = @()
Write-Host "Analyzing Windows Event Logs for LIMS issues..." -ForegroundColor Yellow
foreach ($logName in $LogNames) {
try {
$events = Get-WinEvent -FilterHashtable @{
LogName = $logName
StartTime = $startTime
Level = @(1,2,3,4) # Critical, Error, Warning, Information
} -ErrorAction SilentlyContinue
# Filter for LIMS-related events
$limsEvents = $events | Where-Object {
$_.Message -match "IIS|ASP\.NET|w3wp|application pool|SQL|Oracle|LIMS|timeout|error|fail" -or
$_.ProviderName -in $Sources -or
$_.Id -in @(1000, 1001, 1002, 1309, 2001, 2002, 5011, 5186, 7034, 7035, 7036)
}
$allEvents += $limsEvents
}
catch {
Write-Warning "Could not read $logName log: $($_.Exception.Message)"
}
}
# Analyze and categorize events
$categorizedEvents = $allEvents | ForEach-Object {
$category = "Other"
$severity = switch ($_.LevelDisplayName) {
"Critical" { "CRITICAL" }
"Error" { "ERROR" }
"Warning" { "WARNING" }
default { "INFO" }
}
# Categorize by content
if ($_.Message -match "pool|w3wp|worker process") { $category = "Application Pool" }
elseif ($_.Message -match "SQL|Oracle|database|connection") { $category = "Database" }
elseif ($_.Message -match "authentication|login|logon|401|403") { $category = "Authentication" }
elseif ($_.Message -match "memory|out of memory") { $category = "Memory" }
elseif ($_.Message -match "timeout|slow|performance") { $category = "Performance" }
elseif ($_.Message -match "certificate|SSL|TLS") { $category = "Security" }
[PSCustomObject]@{
Timestamp = $_.TimeCreated
Severity = $severity
Category = $category
Source = $_.ProviderName
EventID = $_.Id
Message = $_.Message.Substring(0, [Math]::Min(200, $_.Message.Length))
FullMessage = $_.Message
}
}
# Generate report
$report = @"
LIMS Windows Event Analysis - Last $Hours Hours
Generated: $(Get-Date)
================================================
SUMMARY BY SEVERITY:
"@
$categorizedEvents | Group-Object Severity | Sort-Object Name | ForEach-Object {
$report += "`n$($_.Name): $($_.Count) events"
}
$report += "`n`nSUMMARY BY CATEGORY:"
$categorizedEvents | Group-Object Category | Sort-Object Count -Descending | ForEach-Object {
$report += "`n$($_.Name): $($_.Count) events"
}
$report += "`n`nCRITICAL AND ERROR EVENTS:`n"
$categorizedEvents | Where-Object { $_.Severity -in @("CRITICAL", "ERROR") } |
Sort-Object Timestamp -Descending | ForEach-Object {
$report += "$($_.Timestamp) [$($_.Severity)] $($_.Category) - $($_.Message)`n"
}
$report | Out-File $OutputPath
Write-Host "Event analysis saved to: $OutputPath" -ForegroundColor Green
return $categorizedEvents
}
function Monitor-LIMSProcessMemory {
param(
[string[]]$ProcessNames = @("w3wp", "sqlservr", "oracle"),
[int]$DurationMinutes = 60,
[int]$SampleIntervalSeconds = 60,
[string]$OutputPath = "C:\temp\lims_memory_trend.csv"
)
$endTime = (Get-Date).AddMinutes($DurationMinutes)
$results = @()
Write-Host "Monitoring LIMS process memory for $DurationMinutes minutes..." -ForegroundColor Yellow
Write-Host "Sample interval: $SampleIntervalSeconds seconds" -ForegroundColor Cyan
while ((Get-Date) -lt $endTime) {
foreach ($processName in $ProcessNames) {
$processes = Get-Process -Name $processName -ErrorAction SilentlyContinue
foreach ($process in $processes) {
try {
$result = [PSCustomObject]@{
Timestamp = Get-Date
ProcessName = $process.Name
ProcessId = $process.Id
WorkingSetMB = [math]::Round($process.WorkingSet64 / 1MB, 2)
PrivateMemoryMB = [math]::Round($process.PrivateMemorySize64 / 1MB, 2)
VirtualMemoryMB = [math]::Round($process.VirtualMemorySize64 / 1MB, 2)
PagedMemoryMB = [math]::Round($process.PagedMemorySize64 / 1MB, 2)
HandleCount = $process.Handles
ThreadCount = $process.Threads.Count
CPUTime = $process.TotalProcessorTime.TotalSeconds
StartTime = $process.StartTime
}
$results += $result
Write-Host "$(Get-Date -Format 'HH:mm:ss') - $($process.Name)($($process.Id)): $($result.WorkingSetMB)MB" -ForegroundColor Gray
}
catch {
Write-Warning "Could not get details for $($process.Name): $($_.Exception.Message)"
}
}
}
Start-Sleep $SampleIntervalSeconds
}
# Save results and analyze trends
$results | Export-Csv $OutputPath -NoTypeInformation
Write-Host "`nMemory trend analysis:" -ForegroundColor Yellow
$results | Group-Object ProcessName | ForEach-Object {
$processData = $_.Group | Sort-Object Timestamp
$first = $processData | Select-Object -First 1
$last = $processData | Select-Object -Last 1
$growth = $last.WorkingSetMB - $first.WorkingSetMB
Write-Host "$($_.Name): Started at $($first.WorkingSetMB)MB, ended at $($last.WorkingSetMB)MB (Growth: $([math]::Round($growth,2))MB)" -ForegroundColor Cyan
if ($growth -gt 100) {
Write-Host " WARNING: Significant memory growth detected!" -ForegroundColor Red
}
}
Write-Host "Detailed data saved to: $OutputPath" -ForegroundColor Green
return $results
}
#endregion
#region IIS Configuration Analysis
function Test-LIMSIISConfiguration {
param(
[string]$SiteName = "Default Web Site",
[string]$AppPoolName,
[string[]]$CriticalPaths = @("C:\inetpub\wwwroot\uploads", "C:\inetpub\wwwroot\temp")
)
Import-Module WebAdministration -ErrorAction SilentlyContinue
$issues = @()
$recommendations = @()
Write-Host "Validating IIS configuration for LIMS..." -ForegroundColor Yellow
try {
# Check application pool settings
if ($AppPoolName) {
$appPool = Get-IISAppPool -Name $AppPoolName -ErrorAction SilentlyContinue
if ($appPool) {
# Check critical app pool settings
if ($appPool.ProcessModel.IdleTimeout.TotalMinutes -gt 0) {
$issues += "App pool idle timeout is set to $($appPool.ProcessModel.IdleTimeout.TotalMinutes) minutes"
$recommendations += "Set idle timeout to 0 for LIMS (always-on application)"
}
if ($appPool.Recycling.PeriodicRestart.Time.TotalHours -lt 24) {
$issues += "App pool recycles every $($appPool.Recycling.PeriodicRestart.Time.TotalHours) hours"
$recommendations += "Consider increasing recycle time for LIMS stability"
}
if ($appPool.ProcessModel.MaxProcesses -ne 1) {
$issues += "App pool max processes is $($appPool.ProcessModel.MaxProcesses)"
$recommendations += "LIMS typically works best with MaxProcesses = 1"
}
}
}
# Check site configuration
$site = Get-IISSite -Name $SiteName -ErrorAction SilentlyContinue
if ($site) {
# Check request limits
$config = Get-WebConfiguration -Filter "system.webserver/security/requestFiltering/requestLimits" -PSPath "IIS:\Sites\$SiteName"
if ($config.maxAllowedContentLength -lt 52428800) { # 50MB
$issues += "Max upload size is only $([math]::Round($config.maxAllowedContentLength/1MB,1))MB"
$recommendations += "Increase maxAllowedContentLength for LIMS file uploads"
}
# Check timeout settings
$httpRuntime = Get-WebConfiguration -Filter "system.web/httpRuntime" -PSPath "IIS:\Sites\$SiteName" -ErrorAction SilentlyContinue
if ($httpRuntime -and $httpRuntime.executionTimeout.TotalSeconds -lt 900) { # 15 minutes
$issues += "Execution timeout is only $($httpRuntime.executionTimeout.TotalSeconds) seconds"
$recommendations += "Increase execution timeout for long-running LIMS operations"
}
}
# Check critical directories
foreach ($path in $CriticalPaths) {
if (-not (Test-Path $path)) {
$issues += "Critical directory missing: $path"
$recommendations += "Create directory: $path"
} else {
# Check permissions
$acl = Get-Acl $path
$hasIISAccess = $acl.Access | Where-Object {
$_.IdentityReference -like "*IIS_IUSRS*" -or
$_.IdentityReference -like "*IUSR*"
}
if (-not $hasIISAccess) {
$issues += "IIS may not have access to: $path"
$recommendations += "Grant IIS_IUSRS modify permissions to: $path"
}
}
}
# Check .NET version
$aspNetVersion = Get-WebConfiguration -Filter "system.webserver/aspNetCore" -PSPath "IIS:\Sites\$SiteName" -ErrorAction SilentlyContinue
if (-not $aspNetVersion) {
$frameworkVersion = Get-WebConfiguration -Filter "system.web/compilation" -PSPath "IIS:\Sites\$SiteName" -ErrorAction SilentlyContinue
if ($frameworkVersion -and $frameworkVersion.targetFramework -lt "4.7") {
$issues += ".NET Framework version is $($frameworkVersion.targetFramework)"
$recommendations += "Consider upgrading to .NET Framework 4.7+ for better performance"
}
}
# Results
$result = [PSCustomObject]@{
SiteName = $SiteName
AppPoolName = $AppPoolName
IssuesFound = $issues.Count
Issues = $issues
Recommendations = $recommendations
Timestamp = Get-Date
}
# Display results
Write-Host "`nIIS Configuration Analysis Results:" -ForegroundColor Green
if ($issues.Count -eq 0) {
Write-Host "✓ No configuration issues found" -ForegroundColor Green
} else {
Write-Host "⚠ Found $($issues.Count) configuration issues:" -ForegroundColor Yellow
$issues | ForEach-Object { Write-Host " - $_" -ForegroundColor Red }
Write-Host "`nRecommendations:" -ForegroundColor Cyan
$recommendations | ForEach-Object { Write-Host " + $_" -ForegroundColor Green }
}
return $result
}
catch {
Write-Error "Failed to analyze IIS configuration: $($_.Exception.Message)"
}
}
log path is a placeholder
need site id and drive F: or C: etc
the error patterns is not exhaustive
function Find-LIMSSpecificErrors {
param(
[string]$LogPath = "<F:\inetpub\logs\LogFiles\W3SVC1>",
[int]$Hours = 24,
[hashtable]$ErrorPatterns = @{
"File_Upload_Errors" = @("413", "Request Entity Too Large", "maxAllowedContentLength")
"Database_Errors" = @("timeout", "deadlock", "connection", "pool")
"Authentication_Errors" = @("401", "403", "authentication", "login")
"Session_Errors" = @("session", "viewstate", "timeout")
"Memory_Errors" = @("out.*memory", "heap", "gc")
"Integration_Errors" = @("instrument", "external", "api", "service")
}
)
$startTime = (Get-Date).AddHours(-$Hours)
$findings = @{}
Write-Host "Analyzing IIS logs for LIMS-specific error patterns..." -ForegroundColor Yellow
foreach ($pattern in $ErrorPatterns.GetEnumerator()) {
$findings[$pattern.Key] = @()
}
Get-ChildItem "$LogPath\*.log" | Where-Object { $_.LastWriteTime -ge $startTime } | ForEach-Object {
$content = Get-Content $_.FullName
$fields = ($content | Where-Object { $_ -like "#Fields:*" } | Select-Object -First 1) -replace "#Fields: ", "" -split " "
$content | Where-Object { $_ -notlike "#*" -and $_ -ne "" } | ForEach-Object {
$line = $_
$values = $_ -split " "
if ($values.Length -ge $fields.Length) {
$entry = @{}
for ($i = 0; $i -lt $fields.Length; $i++) {
$entry[$fields[$i]] = $values[$i]
}
foreach ($patternGroup in $ErrorPatterns.GetEnumerator()) {
foreach ($pattern in $patternGroup.Value) {
if ($line -match $pattern) {
$findings[$patternGroup.Key] += [PSCustomObject]@{
Timestamp = "$($entry['date']) $($entry['time'])"
URL = $entry['cs-uri-stem']
Status = $entry['sc-status']
ClientIP = $entry['c-ip']
UserAgent = $entry['cs(User-Agent)']
TimeTaken = $entry['time-taken']
Pattern = $pattern
FullLine = $line
}
break
}
}
}
}
}
}
# Report findings
Write-Host "`nLIMS Error Pattern Analysis:" -ForegroundColor Green
foreach ($finding in $findings.GetEnumerator()) {
if ($finding.Value.Count -gt 0) {
Write-Host "`n$($finding.Key): $($finding.Value.Count) occurrences" -ForegroundColor Yellow
$finding.Value | Group-Object Pattern | ForEach-Object {
Write-Host " $($_.Name): $($_.Count) times" -ForegroundColor Cyan
}
# Show recent examples
$recent = $finding.Value | Sort-Object Timestamp -Descending | Select-Object -First 3
$recent | ForEach-Object {
Write-Host " $($_.Timestamp) - $($_.URL) - $($_.Status)" -ForegroundColor Gray
}
}
}
return $findings
}
#endregion
#region Network and Connectivity
function Test-LIMSConnectivity {
param(
[hashtable]$Endpoints = @{
"Database_Server" = @{ Server = "localhost"; Port = 1521; Type = "Oracle" }
"File_Server" = @{ Server = "fileserver"; Port = 445; Type = "SMB" }
"Email_Server" = @{ Server = "mailserver"; Port = 25; Type = "SMTP" }
"Web_Service" = @{ Server = "api.vendor.com"; Port = 443; Type = "HTTPS" }
},
[int]$TimeoutSeconds = 10
)
$results = @()
Write-Host "Testing LIMS network connectivity..." -ForegroundColor Yellow
foreach ($endpoint in $Endpoints.GetEnumerator()) {
$name = $endpoint.Key
$config = $endpoint.Value
Write-Host "Testing $name ($($config.Server):$($config.Port))..." -ForegroundColor Cyan
try {
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
switch ($config.Type) {
"Oracle" {
$tcpTest = Test-NetConnection -ComputerName $config.Server -Port $config.Port -WarningAction SilentlyContinue
$status = if ($tcpTest.TcpTestSucceeded) { "Connected" } else { "Failed" }
$detail = if ($tcpTest.TcpTestSucceeded) { "TCP connection successful" } else { "TCP connection failed" }
}
"SMB" {
$tcpTest = Test-NetConnection -ComputerName $config.Server -Port $config.Port -WarningAction SilentlyContinue
$status = if ($tcpTest.TcpTestSucceeded) { "Connected" } else { "Failed" }
$detail = if ($tcpTest.TcpTestSucceeded) { "SMB port accessible" } else { "SMB port blocked" }
}
"SMTP" {
$tcpTest = Test-NetConnection -ComputerName $config.Server -Port $config.Port -WarningAction SilentlyContinue
$status = if ($tcpTest.TcpTestSucceeded) { "Connected" } else { "Failed" }
$detail = if ($tcpTest.TcpTestSucceeded) { "SMTP port accessible" } else { "SMTP port blocked" }
}
"HTTPS" {
try {
$response = Invoke-WebRequest "https://$($config.Server)" -UseBasicParsing -TimeoutSec $TimeoutSeconds
$status = "Connected"
$detail = "HTTP $($response.StatusCode) - $($response.StatusDescription)"
}
catch {
$status = "Failed"
$detail = $_.Exception.Message
}
}
default {
$tcpTest = Test-NetConnection -ComputerName $config.Server -Port $config.Port -WarningAction SilentlyContinue
$status = if ($tcpTest.TcpTestSucceeded) { "Connected" } else { "Failed" }
$detail = "Generic TCP test"
}
}
$stopwatch.Stop()
$result = [PSCustomObject]@{
Endpoint = $name
Server = $config.Server
Port = $config.Port
Type = $config.Type
Status = $status
ResponseTime = $stopwatch.ElapsedMilliseconds
Detail = $detail
Timestamp = Get-Date
}
$results += $result
$color = if ($status -eq "Connected") { "Green" } else { "Red" }
Write-Host " $status - $($stopwatch.ElapsedMilliseconds)ms - $detail" -ForegroundColor $color
}
catch {
$result = [PSCustomObject]@{
Endpoint = $name
Server = $config.Server
Port = $config.Port
Type = $config.Type
Status = "Error"
ResponseTime = -1
Detail = $_.Exception.Message
Timestamp = Get-Date
}
$results += $result
Write-Host " Error - $($_.Exception.Message)" -ForegroundColor Red
}
}
# Summary
$connected = ($results | Where-Object { $_.Status -eq "Connected" }).Count
$total = $results.Count
Write-Host "`nConnectivity Summary: $connected/$total endpoints accessible" -ForegroundColor $(if ($connected -eq $total) { "Green" } else { "Yellow" })
return $results
}
function Test-LIMSCertificates {
param(
[string[]]$Hostnames = @("localhost", "lims.domain.com"),
[int]$WarningDays = 30
)
$results = @()
Write-Host "Checking SSL certificates for LIMS..." -ForegroundColor Yellow
foreach ($hostname in $Hostnames) {
try {
Write-Host "Checking certificate for $hostname..." -ForegroundColor Cyan
$tcpClient = New-Object System.Net.Sockets.TcpClient
$tcpClient.Connect($hostname, 443)
$sslStream = New-Object System.Net.Security.SslStream($tcpClient.GetStream())
$sslStream.AuthenticateAsClient($hostname)
$cert = $sslStream.RemoteCertificate
$x509cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($cert)
$daysUntilExpiry = ($x509cert.NotAfter - (Get-Date)).Days
$status = if ($daysUntilExpiry -le 0) { "Expired" }
elseif ($daysUntilExpiry -le $WarningDays) { "Warning" }
else { "OK" }
$result = [PSCustomObject]@{
Hostname = $hostname
Subject = $x509cert.Subject
Issuer = $x509cert.Issuer
NotBefore = $x509cert.NotBefore
NotAfter = $x509cert.NotAfter
DaysUntilExpiry = $daysUntilExpiry
Status = $status
Thumbprint = $x509cert.Thumbprint
}
$results += $result
$color = switch ($status) {
"OK" { "Green" }
"Warning" { "Yellow" }
"Expired" { "Red" }
}
Write-Host " $status - Expires in $daysUntilExpiry days ($($x509cert.NotAfter))" -ForegroundColor $color
$sslStream.Close()
$tcpClient.Close()
}
catch {
Write-Host " Failed to check certificate: $($_.Exception.Message)" -ForegroundColor Red
$result = [PSCustomObject]@{
Hostname = $hostname
Subject = "N/A"
Issuer = "N/A"
NotBefore = $null
NotAfter = $null
DaysUntilExpiry = -999
Status = "Error"
Thumbprint = "N/A"
Error = $_.Exception.Message
}
$results += $result
}
}
return $results
}
#endregion
#region System Resource Monitoring
function Get-LIMSSystemResources {
param(
[string[]]$Drives = @("C:", "D:", "F:"),
[int]$MemoryWarningPercent = 85,
[int]$DiskWarningPercent = 80
)
Write-Host "Checking LIMS system resources..." -ForegroundColor Yellow
$results = @{
Memory = $null
Drives = @()
CPU = $null
Network = @()
Timestamp = Get-Date
}
# Memory check
$memory = Get-CimInstance -ClassName Win32_OperatingSystem
$totalMemoryGB = [math]::Round($memory.TotalVisibleMemorySize / 1MB, 2)
$freeMemoryGB = [math]::Round($memory.FreePhysicalMemory / 1MB, 2)
$usedMemoryGB = $totalMemoryGB - $freeMemoryGB
$memoryPercent = [math]::Round(($usedMemoryGB / $totalMemoryGB) * 100, 1)
$results.Memory = [PSCustomObject]@{
TotalGB = $totalMemoryGB
UsedGB = $usedMemoryGB
FreeGB = $freeMemoryGB
UsedPercent = $memoryPercent
Status = if ($memoryPercent -gt $MemoryWarningPercent) { "Warning" } else { "OK" }
}
Write-Host "Memory: $usedMemoryGB/$totalMemoryGB GB ($memoryPercent%)" -ForegroundColor $(if ($memoryPercent -gt $MemoryWarningPercent) { "Yellow" } else { "Green" })
# Disk space check
foreach ($drive in $Drives) {
try {
$disk = Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object { $_.DeviceID -eq $drive }
if ($disk) {
$totalGB = [math]::Round($disk.Size / 1GB, 2)
$freeGB = [math]::Round($disk.FreeSpace / 1GB, 2)
$usedGB = $totalGB - $freeGB
$usedPercent = [math]::Round(($usedGB / $totalGB) * 100, 1)
$driveResult = [PSCustomObject]@{
Drive = $drive
TotalGB = $totalGB
UsedGB = $usedGB
FreeGB = $freeGB
UsedPercent = $usedPercent
Status = if ($usedPercent -gt $DiskWarningPercent) { "Warning" } else { "OK" }
}
$results.Drives += $driveResult
Write-Host "Drive $drive`: $usedGB/$totalGB GB ($usedPercent%)" -ForegroundColor $(if ($usedPercent -gt $DiskWarningPercent) { "Yellow" } else { "Green" })
}
}
catch {
Write-Warning "Could not check drive $drive`: $($_.Exception.Message)"
}
}
# CPU check (average over 5 seconds)
$cpu = Get-CimInstance -ClassName Win32_Processor | Measure-Object -Property LoadPercentage -Average
$cpuPercent = [math]::Round($cpu.Average, 1)
$results.CPU = [PSCustomObject]@{
UsedPercent = $cpuPercent
Status = if ($cpuPercent -gt 80) { "High" } elseif ($cpuPercent -gt 60) { "Medium" } else { "Normal" }
}
Write-Host "CPU: $cpuPercent%" -ForegroundColor $(if ($cpuPercent -gt 80) { "Red" } elseif ($cpuPercent -gt 60) { "Yellow" } else { "Green" })
# Network adapters
$adapters = Get-NetAdapter | Where-Object { $_.Status -eq "Up" -and $_.MediaType -eq "802.3" }
foreach ($adapter in $adapters) {
$results.Network += [PSCustomObject]@{
Name = $adapter.Name
LinkSpeed = $adapter.LinkSpeed
Status = $adapter.Status
}
}
return $results
}
#endregion
Write-Host @"
ADDITIONAL LIMS DEBUGGING COMMANDS:
===================================
1. Windows Event Analysis:
Get-LIMSWindowsEvents -Hours 12
2. Memory Leak Detection:
Monitor-LIMSProcessMemory -DurationMinutes 30
3. IIS Configuration Check:
Test-LIMSIISConfiguration -SiteName "Default Web Site" -AppPoolName "LIMSAppPool"
4. Specific Error Pattern Analysis:
Find-LIMSSpecificErrors -Hours 6
5. Network Connectivity Test:
Test-LIMSConnectivity
6. Certificate Expiration Check:
Test-LIMSCertificates -Hostnames @("lims.company.com", "api.company.com")
7. System Resource Check:
Get-LIMSSystemResources
"@ -ForegroundColor Green
[string]$OutputPath = "C:\temp\lims_events.txt"
How to find/choose:
Method 1: Check if C:\temp exists
dir C:\temp
If it doesn't exist: mkdir C:\temp
or use different path
Method 2: Use your user profile temp
$env:TEMP\lims_events.txt
# Usually: C:\Users\YourName\AppData\Local\Temp\lims_events.txt
Method 3: Check where you have write permissions
Test-Path "C:\temp" -PathType Container
Test-Path "D:\logs" -PathType Container
Access needed: Write permissions to chosen directory
---
[string[]]$Sources = @("ASP.NET", "IIS", "W3SVC", "WAS")
How to find Oracle-specific sources:
Method 1: Check what Oracle sources exist in Event Viewer
Get-WinEvent -ListProvider * | Where-Object {$_.Name -like "*Oracle*"}
Method 2: Look at recent Oracle events
Get-WinEvent -FilterHashtable @{LogName="Application"} |
Where-Object {$_.ProviderName -like "*Oracle*"} |
Select-Object ProviderName -Unique
Method 3: Check Event Viewer GUI
Examples you might find:
@("OracleServiceORCL", "OracleDBConsoleorcl", "Oracle.DataAccess", "TNSListener")
Access needed: Read access to Event Logs (usually default)
---
$_.Message -match "IIS|ASP\.NET|w3wp|application pool|SQL|Oracle|LIMS|timeout|error|fail"
How to find Oracle-specific terms:
Method 1: Search existing logs for Oracle errors
Get-WinEvent -FilterHashtable @{LogName="Application"; StartTime=(Get-Date).AddDays(-1)} |
Where-Object {$_.Message -like "*Oracle*"} |
Select-Object -First 5 -Property Message
Method 2: Check Oracle documentation for common error terms
Method 3: Check your LIMS application logs
findstr /i "oracle error fail" "C:\path\to\lims\logs\*.log"
Better pattern for Oracle:
"Oracle|ORA-|TNS-|listener|tablespace|archive|deadlock|LIMS|timeout|error|fail"
Access needed: Read access to application log directories
---
$_.Id -in @(1000, 1001, 1002, 1309, 2001, 2002, 5011, 5186, 7034, 7035, 7036)
How to find Oracle-specific Event IDs:
Method 1: Check recent Oracle events for common IDs
Get-WinEvent -FilterHashtable @{LogName="Application"; StartTime=(Get-Date).AddDays(-7)} |
Where-Object {$_.ProviderName -like "*Oracle*"} |
Group-Object Id | Sort-Object Count -Descending
Method 2: Look up Oracle Windows Event IDs online
Method 3: Check Event Viewer for patterns
Oracle-specific IDs you might add:
@(600, 601, 1000, 1001, 1002, 1309, 2001, 2002, 5011, 5186, 7034, 7035, 7036)
Access needed: Read access to Event Logs
---
Example usage:
Get-LIMSWindowsEvents -Hours 12 `
-Sources @("OracleServiceORCL", "OracleDBConsoleorcl", "TNSListener") `
-OutputPath "$env:TEMP\oracle_lims_events.txt"
Most critical to customize: Output path and Sources array. The search pattern and Event IDs can stay generic initially.
---
[string[]]$ProcessNames = @("w3wp", "sqlservr", "oracle")
How to find Oracle process names:
Method 1: Check running Oracle processes
Get-Process | Where-Object {$_.Name -like "*oracle*"}
Method 2: Check Windows Services
Get-Service | Where-Object {$_.Name -like "*oracle*"} | Select-Object Name, DisplayName
Method 3: Task Manager
Common Oracle process names:
@("oracle", "tnslsnr", "oracleoradb19home1tnslistener", "w3wp")
Access needed: Read access to process information (usually default)
---
[string]$OutputPath = "C:\temp\lims_memory_trend.csv"
How to find/choose:
Method 1: Use temp directory
"$env:TEMP\oracle_memory_trend.csv"
Method 2: Check writable locations
Test-Path "C:\temp" -PathType Container
Test-Path "C:\logs" -PathType Container
Method 3: Use current directory
".\oracle_memory_trend.csv"
Access needed: Write permissions to chosen directory
---
[int]$DurationMinutes = 60,
[int]$SampleIntervalSeconds = 60
How to choose appropriate values:
Method 1: For troubleshooting active issues
-DurationMinutes 30 -SampleIntervalSeconds 30
Method 2: For trend analysis
-DurationMinutes 240 -SampleIntervalSeconds 120 # 4 hours, 2-minute samples
Method 3: For memory leak detection
-DurationMinutes 480 -SampleIntervalSeconds 300 # 8 hours, 5-minute samples
Access needed: None, these are just timing preferences
---
[string]$SiteName = "Default Web Site"
How to find your IIS site name:
Method 1: PowerShell (if WebAdministration module available)
Import-Module WebAdministration
Get-IISSite | Select-Object Name, State
Method 2: IIS Manager GUI
Method 3: Command line
%windir%\system32\inetsrv\appcmd list site
Common site names:
"Default Web Site"
"Oracle LIMS"
"LIMS Application"
Access needed: IIS read permissions, Administrative rights preferred
---
[string]$AppPoolName
How to find application pool name:
Method 1: PowerShell
Get-IISAppPool | Select-Object Name, State
Method 2: IIS Manager
Method 3: Check site configuration
Get-IISSite -Name "YourSiteName" | Select-Object Applications
Common pool names:
"DefaultAppPool"
"LIMSAppPool"
"OracleLIMSPool"
Access needed: IIS configuration read access
---
[string[]]$CriticalPaths = @("C:\inetpub\wwwroot\uploads", "C:\inetpub\wwwroot\temp")
How to find your application paths:
Method 1: Check IIS site physical path
Get-IISSite -Name "YourSiteName" | Select-Object PhysicalPath
Method 2: Look in web.config
<!-- Look for paths like: -->
<add key="UploadPath" value="C:\LIMS\uploads" />
<add key="TempPath" value="C:\LIMS\temp" />
Method 3: Check application directories
dir "C:\inetpub\wwwroot"
dir "C:\Program Files\LIMS"
Access needed: File system read access to web directories
---
[string]$LogPath = "C:\inetpub\logs\LogFiles\W3SVC1"
How to find IIS log location:
Method 1: Check IIS site logging settings
Get-IISSite -Name "YourSiteName" | Get-WebConfiguration -Filter "system.webServer/httpLogging"
Method 2: IIS Manager
Method 3: Default locations to check
dir "C:\inetpub\logs\LogFiles"
dir "C:\Windows\System32\LogFiles"
Common log paths:
C:\inetpub\logs\LogFiles\W3SVC1
C:\inetpub\logs\LogFiles\W3SVC2
Access needed: Read access to IIS log directory
---
[hashtable]$ErrorPatterns = @{
"File_Upload_Errors" = @("413", "Request Entity Too Large", "maxAllowedContentLength")
"Database_Errors" = @("timeout", "deadlock", "connection", "pool")
# ... more patterns
}
How to customize for Oracle:
Method 1: Add Oracle-specific patterns
"Oracle_Errors" = @("ORA-", "TNS-", "Oracle", "listener")
"LIMS_Errors" = @("LIMS", "sample", "result", "instrument")
Method 2: Check existing logs for common errors
Select-String -Path "C:\inetpub\logs\LogFiles\W3SVC1\*.log" -Pattern "error|fail|exception" | Select-Object -First 10
Method 3: Review application-specific errors
Access needed: Read access to log files
---
[hashtable]$Endpoints = @{
"Database_Server" = @{ Server = "localhost"; Port = 1521; Type = "Oracle" }
"File_Server" = @{ Server = "fileserver"; Port = 445; Type = "SMB" }
# ... more endpoints
}
How to find your Oracle connection details:
Method 1: Check LIMS configuration files
findstr /i "server\|host\|port" "C:\Program Files\LIMS\*.config"
findstr /i "server\|host\|port" "C:\inetpub\wwwroot\LIMS\*.config"
Method 2: Check TNS names file
type "%ORACLE_HOME%\network\admin\tnsnames.ora"
Method 3: Check connection strings in web.config
<connectionStrings>
<add name="Oracle" connectionString="Data Source=oracleserver:1521/ORCL;..." />
</connectionStrings>
Real example:
@{
"Oracle_LIMS_DB" = @{ Server = "oraprod01.company.com"; Port = 1521; Type = "Oracle" }
"Oracle_Backup" = @{ Server = "192.168.1.55"; Port = 1521; Type = "Oracle" }
"File_Share" = @{ Server = "fileserver01"; Port = 445; Type = "SMB" }
}
Access needed: Read access to configuration files, or ask DBA for connection details
---
[string[]]$Hostnames = @("localhost", "lims.domain.com")
How to find your LIMS hostnames:
Method 1: Check IIS site bindings
Get-IISSite | Get-IISBinding | Where-Object {$_.Protocol -eq "https"}
Method 2: Check your LIMS URL
Method 3: Check configuration files
findstr /i "https\|ssl" "C:\Program Files\LIMS\*.config"
Examples:
@("lims.yourcompany.com", "oraclelims.internal.com", "api.lims.com")
Access needed: Read access to IIS configuration
---
[string[]]$Drives = @("C:", "D:", "F:")
How to find your system drives:
Method 1: PowerShell
Get-PSDrive -PSProvider FileSystem | Select-Object Name, Used, Free
Method 2: Command prompt
wmic logicaldisk get deviceid,size,freespace
Method 3: File Explorer
Access needed: Basic file system access (usually default)
---
[int]$MemoryWarningPercent = 85,
[int]$DiskWarningPercent = 80
How to choose appropriate thresholds:
Method 1: Check current usage
Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object @{Name="MemoryUsage";Expression={[math]::Round(($_.TotalVisibleMemorySize - $_.FreePhysicalMemory) / $_.TotalVisibleMemorySize * 100, 1)}}
Method 2: Oracle recommendations
Method 3: Environment-specific
Access needed: System performance counters (usually default)