Save this entire file as lims-complete.ps1
and load it with . .\lims-complete.ps1
# ====================================
# COMPLETE LIMS DEBUGGING FUNCTIONS
# ====================================
# Save this file as: C:\Scripts\lims-complete.ps1
# Load with: . C:\Scripts\lims-complete.ps1
# Then run any function you want
#region Path Discovery
function Find-LIMSInstallationPaths {
param(
[string[]]$SearchPatterns = @("*LIMS*", "*LAB*", "*Laboratory*"),
[string[]]$CommonVendors = @("Thermo", "Waters", "Agilent", "PerkinElmer", "Abbott", "Roche", "Siemens"),
[switch]$IncludeRegistry = $true,
[switch]$IncludeServices = $true,
[switch]$IncludeIIS = $true,
[switch]$Verbose = $false
)
Write-Host "Discovering LIMS installation paths..." -ForegroundColor Yellow
$discoveredPaths = @{
ProgramFiles = @()
IISPaths = @()
ServicePaths = @()
RegistryPaths = @()
ConfigFiles = @()
LogDirectories = @()
DataDirectories = @()
TempDirectories = @()
AllUniquePaths = @()
}
# 1. Search Program Files directories
Write-Host "Searching Program Files..." -ForegroundColor Cyan
$programDirs = @("C:\Program Files", "C:\Program Files (x86)", "D:\Program Files")
foreach ($dir in $programDirs) {
if (Test-Path $dir) {
# Search by common patterns
foreach ($pattern in $SearchPatterns) {
$found = Get-ChildItem $dir -Directory -Name $pattern -ErrorAction SilentlyContinue
foreach ($folder in $found) {
$fullPath = Join-Path $dir $folder
$discoveredPaths.ProgramFiles += $fullPath
if ($Verbose) { Write-Host " Found: $fullPath" -ForegroundColor Gray }
}
}
# Search by vendor names
foreach ($vendor in $CommonVendors) {
$found = Get-ChildItem $dir -Directory -Name "*$vendor*" -ErrorAction SilentlyContinue
foreach ($folder in $found) {
$fullPath = Join-Path $dir $folder
# Check if it contains LIMS-related files
$hasLIMSFiles = Get-ChildItem $fullPath -Recurse -File -Include "*.exe", "*.dll", "*.config" -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match "LIMS|Lab|Sample|Result|Instrument" } |
Select-Object -First 1
if ($hasLIMSFiles) {
$discoveredPaths.ProgramFiles += $fullPath
if ($Verbose) { Write-Host " Found vendor dir: $fullPath" -ForegroundColor Gray }
}
}
}
}
}
# 2. Check IIS sites and applications
if ($IncludeIIS) {
Write-Host "Checking IIS sites..." -ForegroundColor Cyan
try {
Import-Module WebAdministration -ErrorAction SilentlyContinue
$sites = Get-IISSite -ErrorAction SilentlyContinue
foreach ($site in $sites) {
if ($site.Name -match ($SearchPatterns -join "|")) {
$discoveredPaths.IISPaths += $site.PhysicalPath
if ($Verbose) { Write-Host " Found IIS site: $($site.Name) -> $($site.PhysicalPath)" -ForegroundColor Gray }
}
# Check applications within sites
$apps = Get-WebApplication -Site $site.Name -ErrorAction SilentlyContinue
foreach ($app in $apps) {
if ($app.Path -match ($SearchPatterns -join "|")) {
$discoveredPaths.IISPaths += $app.PhysicalPath
if ($Verbose) { Write-Host " Found IIS app: $($app.Path) -> $($app.PhysicalPath)" -ForegroundColor Gray }
}
}
}
}
catch {
Write-Warning "Could not check IIS: $($_.Exception.Message)"
}
}
# 3. Check Windows Services
if ($IncludeServices) {
Write-Host "Checking Windows services..." -ForegroundColor Cyan
$services = Get-WmiObject Win32_Service | Where-Object {
$_.Name -match ($SearchPatterns -join "|") -or
$_.DisplayName -match ($SearchPatterns -join "|") -or
$_.PathName -match ($SearchPatterns -join "|")
}
foreach ($service in $services) {
if ($service.PathName) {
# Extract directory from service path
$servicePath = $service.PathName -replace '"', ''
if (Test-Path $servicePath) {
$serviceDir = Split-Path $servicePath -Parent
$discoveredPaths.ServicePaths += $serviceDir
if ($Verbose) { Write-Host " Found service: $($service.Name) -> $serviceDir" -ForegroundColor Gray }
}
}
}
}
# 4. Check Registry for installation paths
if ($IncludeRegistry) {
Write-Host "Checking Registry..." -ForegroundColor Cyan
$regPaths = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
)
foreach ($regPath in $regPaths) {
try {
$programs = Get-ItemProperty $regPath -ErrorAction SilentlyContinue |
Where-Object {
$_.DisplayName -match ($SearchPatterns -join "|") -or
$_.Publisher -match ($CommonVendors -join "|")
}
foreach ($program in $programs) {
if ($program.InstallLocation -and (Test-Path $program.InstallLocation)) {
$discoveredPaths.RegistryPaths += $program.InstallLocation
if ($Verbose) { Write-Host " Found registry: $($program.DisplayName) -> $($program.InstallLocation)" -ForegroundColor Gray }
}
}
}
catch {
# Registry access might fail, continue silently
}
}
}
# Consolidate all paths
$allPaths = @()
$allPaths += $discoveredPaths.ProgramFiles
$allPaths += $discoveredPaths.IISPaths
$allPaths += $discoveredPaths.ServicePaths
$allPaths += $discoveredPaths.RegistryPaths
$discoveredPaths.AllUniquePaths = $allPaths | Sort-Object -Unique | Where-Object { $_ -and (Test-Path $_) }
# Find related directories (Config, Logs, Temp) for each discovered path
foreach ($basePath in $discoveredPaths.AllUniquePaths) {
# Look for log directories
$logDirs = Get-ChildItem $basePath -Recurse -Directory -Name "*log*", "*Log*" -ErrorAction SilentlyContinue
foreach ($logDir in $logDirs) {
$discoveredPaths.LogDirectories += Join-Path $basePath $logDir
}
# Look for temp directories
$tempDirs = Get-ChildItem $basePath -Recurse -Directory -Name "*temp*", "*tmp*", "*cache*" -ErrorAction SilentlyContinue
foreach ($tempDir in $tempDirs) {
$discoveredPaths.TempDirectories += Join-Path $basePath $tempDir
}
}
# Remove duplicates
$discoveredPaths.LogDirectories = $discoveredPaths.LogDirectories | Sort-Object -Unique | Where-Object { $_ -and (Test-Path $_) }
$discoveredPaths.TempDirectories = $discoveredPaths.TempDirectories | Sort-Object -Unique | Where-Object { $_ -and (Test-Path $_) }
# Display summary
Write-Host "`nLIMS Path Discovery Summary:" -ForegroundColor Green
Write-Host " Program installations: $($discoveredPaths.ProgramFiles.Count)" -ForegroundColor Cyan
Write-Host " IIS sites/applications: $($discoveredPaths.IISPaths.Count)" -ForegroundColor Cyan
Write-Host " Service locations: $($discoveredPaths.ServicePaths.Count)" -ForegroundColor Cyan
Write-Host " Registry entries: $($discoveredPaths.RegistryPaths.Count)" -ForegroundColor Cyan
Write-Host " Log directories: $($discoveredPaths.LogDirectories.Count)" -ForegroundColor Cyan
Write-Host " Temp directories: $($discoveredPaths.TempDirectories.Count)" -ForegroundColor Cyan
Write-Host " Total unique paths: $($discoveredPaths.AllUniquePaths.Count)" -ForegroundColor Yellow
return $discoveredPaths
}
#endregion
#region File System Health
function Test-LIMSFileSystemHealth {
param(
[string[]]$CriticalPaths = @(),
[switch]$AutoDiscoverPaths = $true,
[string[]]$AdditionalPaths = @(),
[int]$LargeFolderSizeMB = 1000,
[int]$OldFileDays = 30,
[switch]$IncludeStandardPaths = $true
)
Write-Host "Analyzing LIMS file system health..." -ForegroundColor Yellow
# Build the list of paths to check
$pathsToCheck = @()
# Add manually specified paths
$pathsToCheck += $CriticalPaths
$pathsToCheck += $AdditionalPaths
# Add standard Windows paths that are commonly used
if ($IncludeStandardPaths) {
$standardPaths = @(
"C:\inetpub\wwwroot",
"C:\Windows\Temp",
"C:\Temp"
)
$pathsToCheck += $standardPaths | Where-Object { Test-Path $_ }
}
# Auto-discover LIMS paths if requested
if ($AutoDiscoverPaths) {
Write-Host "Auto-discovering LIMS paths..." -ForegroundColor Cyan
try {
$discoveredPaths = Find-LIMSInstallationPaths -Verbose:$false
$pathsToCheck += $discoveredPaths.AllUniquePaths
$pathsToCheck += $discoveredPaths.LogDirectories
$pathsToCheck += $discoveredPaths.TempDirectories
}
catch {
Write-Warning "Auto-discovery failed: $($_.Exception.Message)"
}
}
# Remove duplicates and empty paths
$pathsToCheck = $pathsToCheck | Where-Object { $_ } | Sort-Object -Unique
if ($pathsToCheck.Count -eq 0) {
Write-Warning "No paths to check. Use -CriticalPaths parameter or enable -AutoDiscoverPaths"
return $null
}
Write-Host "Checking $($pathsToCheck.Count) discovered paths..." -ForegroundColor Cyan
$results = @{
PathChecks = @()
LargeFolders = @()
OldFiles = @()
Recommendations = @()
Summary = @{}
}
foreach ($path in $pathsToCheck) {
if (Test-Path $path) {
try {
# Basic path info
$pathInfo = [PSCustomObject]@{
Path = $path
Exists = $true
IsWritable = $false
FileCount = 0
TotalSizeMB = 0
LastModified = $null
PathType = "Unknown"
}
# Determine path type
if ($path -match "log|Log") { $pathInfo.PathType = "Logs" }
elseif ($path -match "temp|tmp|cache") { $pathInfo.PathType = "Temporary" }
elseif ($path -match "config|Config") { $pathInfo.PathType = "Configuration" }
elseif ($path -match "data|Data|database") { $pathInfo.PathType = "Data" }
elseif ($path -match "program|Program") { $pathInfo.PathType = "Program" }
elseif ($path -match "inetpub|wwwroot") { $pathInfo.PathType = "Web" }
else { $pathInfo.PathType = "Other" }
# Test write access (only for certain types)
if ($pathInfo.PathType -in @("Temporary", "Data", "Logs")) {
$testFile = Join-Path $path "lims_test_$(Get-Random).tmp"
try {
"test" | Out-File $testFile -Force
Remove-Item $testFile -Force
$pathInfo.IsWritable = $true
}
catch {
$pathInfo.IsWritable = $false
$results.Recommendations += "Check write permissions for $($pathInfo.PathType) directory: $path"
}
}
# Get folder statistics
$files = Get-ChildItem $path -Recurse -File -ErrorAction SilentlyContinue | Select-Object -First 10000
$pathInfo.FileCount = ($files | Measure-Object).Count
if ($pathInfo.FileCount -eq 10000) {
$pathInfo.FileCount = "10000+"
$results.Recommendations += "Large directory detected (>10k files): $path - Consider cleanup"
}
if ($files) {
$pathInfo.TotalSizeMB = [math]::Round(($files | Measure-Object Length -Sum).Sum / 1MB, 2)
$pathInfo.LastModified = ($files | Sort-Object LastWriteTime -Descending | Select-Object -First 1).LastWriteTime
}
# Check for large folders
if ($pathInfo.TotalSizeMB -gt $LargeFolderSizeMB) {
$results.LargeFolders += $pathInfo
}
# Find old files (especially in temp directories)
if ($pathInfo.PathType -in @("Temporary", "Logs")) {
$oldFiles = $files | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$OldFileDays) }
if ($oldFiles) {
$oldFileInfo = [PSCustomObject]@{
Path = $path
PathType = $pathInfo.PathType
OldFileCount = ($oldFiles | Measure-Object).Count
OldFileSizeMB = [math]::Round(($oldFiles | Measure-Object Length -Sum).Sum / 1MB, 2)
OldestFile = ($oldFiles | Sort-Object LastWriteTime | Select-Object -First 1).LastWriteTime
}
$results.OldFiles += $oldFileInfo
if ($oldFileInfo.OldFileSizeMB -gt 100) {
$results.Recommendations += "Consider cleanup of old files in $($pathInfo.PathType): $path ($($oldFileInfo.OldFileSizeMB)MB, $($oldFileInfo.OldFileCount) files)"
}
}
}
$results.PathChecks += $pathInfo
}
catch {
$results.PathChecks += [PSCustomObject]@{
Path = $path
Exists = $true
Error = $_.Exception.Message
}
}
}
}
# Display summary
Write-Host "`nFile System Health Summary:" -ForegroundColor Green
$results.PathChecks | ForEach-Object {
$icon = switch ($_.PathType) {
"Program" { "📁" }
"Data" { "💾" }
"Logs" { "📄" }
"Temporary" { "🗂️" }
"Configuration" { "⚙️" }
"Web" { "🌐" }
default { "📂" }
}
$color = if ($_.Exists -and $_.IsWritable) { "Green" }
elseif ($_.Exists) { "Yellow" }
else { "Red" }
$status = if ($_.Exists -and $_.IsWritable) { "✓ OK" }
elseif ($_.Exists) { "⚠ Read-Only" }
else { "✗ Missing" }
Write-Host " $icon $($_.Path) [$($_.PathType)]: $status" -ForegroundColor $color
}
return $results
}
#endregion
#region Windows Event Log Analysis
function Get-LIMSWindowsEvents {
param(
[int]$Hours = 24,
[string[]]$LogNames = @("Application", "System", "Security"),
[string[]]$Sources = @("ASP.NET", "IIS", "W3SVC", "WAS", "Oracle*", "LIMS*"),
[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)"
}
}
# Generate report
$report = @"
LIMS Windows Event Analysis - Last $Hours Hours
Generated: $(Get-Date)
================================================
TOTAL EVENTS FOUND: $($allEvents.Count)
EVENTS BY SEVERITY:
"@
$allEvents | Group-Object LevelDisplayName | Sort-Object Name | ForEach-Object {
$report += "`n$($_.Name): $($_.Count) events"
}
$report += "`n`nRECENT CRITICAL/ERROR EVENTS:`n"
$allEvents | Where-Object { $_.LevelDisplayName -in @("Critical", "Error") } |
Sort-Object TimeCreated -Descending | Select-Object -First 20 | ForEach-Object {
$report += "$($_.TimeCreated) [$($_.LevelDisplayName)] $($_.ProviderName) - $($_.Message.Substring(0, [Math]::Min(100, $_.Message.Length)))`n"
}
# Create output directory if it doesn't exist
$outputDir = Split-Path $OutputPath -Parent
if (-not (Test-Path $outputDir)) {
New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
}
$report | Out-File $OutputPath -Encoding UTF8
Write-Host "Event analysis saved to: $OutputPath" -ForegroundColor Green
return $allEvents
}
#endregion
#region Process Memory Monitoring
function Monitor-LIMSProcessMemory {
param(
[string[]]$ProcessNames = @("w3wp", "sqlservr", "oracle", "tnslsnr"),
[int]$DurationMinutes = 30,
[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)
HandleCount = $process.Handles
ThreadCount = $process.Threads.Count
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
$outputDir = Split-Path $OutputPath -Parent
if (-not (Test-Path $outputDir)) {
New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
}
$results | Export-Csv $OutputPath -NoTypeInformation
Write-Host "Memory trend analysis saved to: $OutputPath" -ForegroundColor Green
return $results
}
#endregion
#region Services Monitoring
function Get-LIMSServiceStatus {
param(
[string[]]$ServicePatterns = @("*Oracle*", "*SQL*", "*IIS*", "*W3SVC*", "*LIMS*", "*Print*"),
[switch]$IncludeAutoStartOnly = $true
)
Write-Host "Checking LIMS-related Windows services..." -ForegroundColor Yellow
$services = @()
foreach ($pattern in $ServicePatterns) {
$services += Get-Service -Name $pattern -ErrorAction SilentlyContinue
}
$results = $services | Sort-Object Name -Unique | ForEach-Object {
$startType = (Get-WmiObject -Class Win32_Service -Filter "Name='$($_.Name)'").StartMode
[PSCustomObject]@{
ServiceName = $_.Name
DisplayName = $_.DisplayName
Status = $_.Status
StartType = $startType
CanStop = $_.CanStop
}
}
if ($IncludeAutoStartOnly) {
$results = $results | Where-Object { $_.StartType -eq "Auto" }
}
# Display summary
$stopped = ($results | Where-Object { $_.Status -eq "Stopped" }).Count
$running = ($results | Where-Object { $_.Status -eq "Running" }).Count
Write-Host "Service Summary: $running running, $stopped stopped" -ForegroundColor Cyan
# Highlight critical stopped services
$stoppedCritical = $results | Where-Object { $_.Status -eq "Stopped" -and $_.StartType -eq "Auto" }
if ($stoppedCritical) {
Write-Host "⚠ Critical services stopped:" -ForegroundColor Red
$stoppedCritical | ForEach-Object {
Write-Host " - $($_.ServiceName) ($($_.DisplayName))" -ForegroundColor Red
}
}
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"
}
}
}
# 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 @{
Issues = $issues
Recommendations = $recommendations
}
}
catch {
Write-Error "Failed to analyze IIS configuration: $($_.Exception.Message)"
}
}
#endregion
#region Network 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" }
},
[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()
$tcpTest = Test-NetConnection -ComputerName $config.Server -Port $config.Port -WarningAction SilentlyContinue
$stopwatch.Stop()
$status = if ($tcpTest.TcpTestSucceeded) { "Connected" } else { "Failed" }
$detail = if ($tcpTest.TcpTestSucceeded) { "$($config.Type) connection successful" } else { "$($config.Type) connection failed" }
$result = [PSCustomObject]@{
Endpoint = $name
Server = $config.Server
Port = $config.Port
Type = $config.Type
Status = $status
ResponseTime = $stopwatch.ElapsedMilliseconds
Detail = $detail
}
$results += $result
$color = if ($status -eq "Connected") { "Green" } else { "Red" }
Write-Host " $status - $($stopwatch.ElapsedMilliseconds)ms - $detail" -ForegroundColor $color
}
catch {
Write-Host " Error - $($_.Exception.Message)" -ForegroundColor Red
}
}
return $results
}
#endregion
#region System Resources
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
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)"
}
}
return $results
}
#endregion
# ====================================
# USAGE INSTRUCTIONS
# ====================================
Write-Host @"
LIMS DEBUGGING FUNCTIONS LOADED!
=================================
1. Discover LIMS Paths:
Find-LIMSInstallationPaths -Verbose
2. File System Health Check:
Test-LIMSFileSystemHealth -AutoDiscoverPaths
3. Windows Event Analysis:
Get-LIMSWindowsEvents -Hours 12
4. Memory Monitoring:
Monitor-LIMSProcessMemory -DurationMinutes 30
5. Service Status Check:
Get-LIMSServiceStatus
6. IIS Configuration Check:
Test-LIMSIISConfiguration -SiteName "Default Web Site"
7. Network Connectivity Test:
Test-LIMSConnectivity
8. System Resource Check:
Get-LIMSSystemResources
To load this file: . .\lims-complete.ps1
Then run any function above!
"@ -ForegroundColor Green
How to Use This File:
1. Save it as: C:\Scripts\lims-complete.ps1
2. Load it:
. C:\Scripts\lims-complete.ps1
3. Run any function:
Find-LIMSInstallationPaths -Verbose
Test-LIMSFileSystemHealth -AutoDiscoverPaths
DONE. Everything is in one file now!
Unlike Linux, PowerShell has execution policies that may block scripts:
# Check current policy
Get-ExecutionPolicy
# If it shows "Restricted", you need to change it
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
# Or for the current session only
Set-ExecutionPolicy Bypass -Scope Process
Common policies:
Restricted
- No scripts allowed (default on some systems)RemoteSigned
- Local scripts OK, downloaded scripts need signatureUnrestricted
- All scripts allowedBypass
- Nothing is blocked---
Open PowerShell and load functions directly:
# 1. Open PowerShell as Administrator (recommended for LIMS functions)
# Right-click PowerShell → "Run as Administrator"
# 2. Copy and paste the entire function definition
function Test-LIMSFileSystemHealth {
param(
[string[]]$CriticalPaths = @(),
# ... rest of function
)
# ... function body
}
# 3. Press Enter - function is now loaded in memory
# 4. Run the function
Test-LIMSFileSystemHealth -AutoDiscoverPaths
Linux equivalent: Like sourcing functions in bash: . ./functions.sh
---
Create a PowerShell script file:
# 1. Create file: lims-debug.ps1
# Save all your functions in this file
# 2. Load the functions (like sourcing in Linux)
. .\lims-debug.ps1
# 3. Run individual functions
Test-LIMSFileSystemHealth -AutoDiscoverPaths
Get-LIMSServiceStatus
Linux equivalent: Like ./script.sh
but you need to source (load) first
---
Create a complete script that loads and runs functions:
# File: run-lims-checks.ps1
# Define all functions first
function Find-LIMSInstallationPaths {
# ... function definition
}
function Test-LIMSFileSystemHealth {
# ... function definition
}
# Then execute them at the bottom
Write-Host "Starting LIMS health checks..." -ForegroundColor Green
$paths = Find-LIMSInstallationPaths
$health = Test-LIMSFileSystemHealth -AutoDiscoverPaths
Write-Host "Checks complete!" -ForegroundColor Green
Run it:
.\run-lims-checks.ps1
---
Create a PowerShell module (like a Python package):
# 1. Create directory: C:\Users\YourName\Documents\PowerShell\Modules\LIMSDebug
# 2. Create file: LIMSDebug.psm1 with all your functions
# 3. Create file: LIMSDebug.psd1 (manifest)
@{
ModuleVersion = '1.0'
FunctionsToExport = @('Find-LIMSInstallationPaths', 'Test-LIMSFileSystemHealth')
}
# 4. Import and use
Import-Module LIMSDebug
Test-LIMSFileSystemHealth
---
# Open PowerShell as Administrator
# Copy entire function, paste, press Enter
# Run immediately
Test-LIMSFileSystemHealth -AutoDiscoverPaths
# Save functions in: C:\Scripts\lims-functions.ps1
# To use:
. C:\Scripts\lims-functions.ps1
Test-LIMSFileSystemHealth -AutoDiscoverPaths
# Create: C:\Scripts\daily-lims-check.ps1
# Schedule with Task Scheduler or run via:
powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\daily-lims-check.ps1"
---
# Start Menu → PowerShell ISE
# Great for development and testing
# Can save/load scripts easily
# Built-in help and intellisense
# Start Menu → PowerShell (or Windows Terminal)
# Good for quick tasks
# Copy/paste functions directly
# Best for serious development
# Syntax highlighting, debugging
# Can run functions directly in integrated terminal
---
./script.sh --path /var/log --verbose
./script.sh -p /var/log -v
Test-Function -Path "C:\Logs" -Verbose
Test-Function -Path "C:\Logs" -V # Short form if supported
# Named parameters (order doesn't matter)
Test-Function -Verbose -Path "C:\Logs"
# Positional parameters
Test-Function "C:\Logs" $true
---
1. Open PowerShell as Administrator
# Right-click Start → Windows PowerShell (Admin)
2. Set execution policy if needed
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
3. Navigate to your script location
cd C:\Scripts
# or wherever you saved the functions
4. Load the functions
# If functions are in a file:
. .\lims-functions.ps1
# Or copy/paste the function definitions directly
5. Run the functions
# Discover LIMS paths
$paths = Find-LIMSInstallationPaths -Verbose
# Check what was found
$paths.AllUniquePaths
# Run health check
$health = Test-LIMSFileSystemHealth -AutoDiscoverPaths
# View results
$health.Summary
$health.Recommendations
---
1. "Execution Policy" Error
Set-ExecutionPolicy Bypass -Scope Process
2. "Function not recognized"
# Function wasn't loaded - reload it
. .\your-script.ps1
3. "Access Denied"
# Run PowerShell as Administrator
# Many LIMS functions need elevated privileges
4. "Path not found"
# Use full paths
Get-ChildItem "C:\Full\Path\To\File"
# Not: Get-ChildItem "~/relative/path"
---
# See all loaded functions
Get-Command -CommandType Function
# Get help for a function
Get-Help Test-LIMSFileSystemHealth -Full
# See function definition
${function:Test-LIMSFileSystemHealth}
# Test if a function exists
if (Get-Command "Test-LIMSFileSystemHealth" -ErrorAction SilentlyContinue) {
Write-Host "Function is loaded"
}
# Clear all functions (start fresh)
Get-ChildItem function: | Remove-Item
# Profile location (like .bashrc)
$PROFILE
---
| Task | Linux | PowerShell |
|------|-------|------------|
| Make executable | chmod +x script.sh
| Set-ExecutionPolicy
|
| Run script | ./script.sh
| .\script.ps1
|
| Source functions | . ./functions.sh
| . .\functions.ps1
|
| Background job | ./script.sh &
| Start-Job { .\script.ps1 }
|
| Pipe to file | ./script.sh > output.txt
| .\script.ps1 > output.txt
|
| Run as admin | sudo ./script.sh
| Right-click → "Run as Administrator" |
| Environment variables | export VAR=value
| $env:VAR = "value"
|
| Path separator | /
| \
(or \\
in strings) |
---
Save this as quick-lims-test.ps1
:
# Set execution policy for this session
Set-ExecutionPolicy Bypass -Scope Process -Force
# Your functions go here
function Test-QuickLIMS {
Write-Host "LIMS Quick Test Running..." -ForegroundColor Green
# Basic system info
Write-Host "Computer: $env:COMPUTERNAME" -ForegroundColor Cyan
Write-Host "User: $env:USERNAME" -ForegroundColor Cyan
Write-Host "PowerShell Version: $($PSVersionTable.PSVersion)" -ForegroundColor Cyan
# Test basic functionality
$drives = Get-PSDrive -PSProvider FileSystem
Write-Host "Available drives: $($drives.Name -join ', ')" -ForegroundColor Cyan
}
# Run the test
Test-QuickLIMS
Execute it:
.\quick-lims-test.ps1
This gives you a foundation to build upon and test that PowerShell functions are working correctly!