From 526ffcdd83854125c88082063e4c7e212f0f75a8 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Tue, 16 Dec 2025 15:46:47 +0000 Subject: [PATCH 1/3] Moved scripts --- scripts_wip/Win_Battery_Capacity_Check.ps1 | 53 ----- scripts_wip/Win_CPU_Uptime_Check.ps1 | 26 --- scripts_wip/Win_Disk_HealthCheck.ps1 | 92 --------- scripts_wip/Win_Disk_SMART.ps1 | 215 --------------------- scripts_wip/Win_Disk_Space_Check.ps1 | 104 ---------- scripts_wip/Win_RAM_Available_Check.ps1 | 39 ---- 6 files changed, 529 deletions(-) delete mode 100644 scripts_wip/Win_Battery_Capacity_Check.ps1 delete mode 100644 scripts_wip/Win_CPU_Uptime_Check.ps1 delete mode 100644 scripts_wip/Win_Disk_HealthCheck.ps1 delete mode 100644 scripts_wip/Win_Disk_SMART.ps1 delete mode 100644 scripts_wip/Win_Disk_Space_Check.ps1 delete mode 100644 scripts_wip/Win_RAM_Available_Check.ps1 diff --git a/scripts_wip/Win_Battery_Capacity_Check.ps1 b/scripts_wip/Win_Battery_Capacity_Check.ps1 deleted file mode 100644 index f1cb0baf..00000000 --- a/scripts_wip/Win_Battery_Capacity_Check.ps1 +++ /dev/null @@ -1,53 +0,0 @@ -<# -.Synopsis - Checks the battery full charge capacity VS the design capacity -.DESCRIPTION - This was written specifically for use as a "Script Check" in mind, where it the output is deliberaly light unless a warning or error condition is found that needs more investigation. - - If the total full charge capacity is less than the minimum capacity amount, an error is returned. -#> - -[CmdletBinding()] -param( - [Parameter(Mandatory = $false)] - [int]#The minimum battery full charge capacity (as a percentage of design capacity by default). Defaults to 85 percent. - $minimumBatteryCapacity = 85, - - [Parameter(Mandatory = $false)] - [switch]#Set the check condition to absolute mWh values instead of a percentage - $absoluteValues -) - -try{ - $searcher = New-Object System.Management.ManagementObjectSearcher("root\wmi","SELECT * FROM BatteryStaticData") - $batteryStatic = $searcher.Get() - #CIM approach threw errors when Get-WMIObject did not - WMI approach is not available in PSv7, so took .NET approach - $batteryCharge = Get-CimInstance -Namespace "root\wmi" -ClassName "BatteryFullChargedCapacity" -ErrorAction Stop -} catch { - Write-Output "No battery detected" - exit 0 -} - -if (-not $batteryStatic -or -not $batteryCharge) { - Write-Output "No battery detected" - exit 0 -} - -$chargeCapacity = $batteryCharge.FullChargedCapacity -$designCapacity = $batteryStatic.DesignedCapacity - -$available = [math]::Round(($chargeCapacity / $designCapacity) * 100,2) -$label = "%" -if ($absoluteValues) { - $available = $chargeCapacity - $label = "mWh" -} - -If($available -le $minimumBatteryCapacity) -{ - Write-Output "The battery needs investigating. Full charge capacity is below the threshold of $minimumBatteryCapacity $label ($available $label available of design capacity $designCapacity mWh." - Exit 1 -} else { - Write-Output "The battery is reporting ok. Full charge capacity is above the threshold of $minimumBatteryCapacity $label ($available $label available of design capacity $designCapacity mWh." - Exit 0 -} \ No newline at end of file diff --git a/scripts_wip/Win_CPU_Uptime_Check.ps1 b/scripts_wip/Win_CPU_Uptime_Check.ps1 deleted file mode 100644 index 1fb55d11..00000000 --- a/scripts_wip/Win_CPU_Uptime_Check.ps1 +++ /dev/null @@ -1,26 +0,0 @@ -<# -.Synopsis - Checks Uptime of the computer -.DESCRIPTION - This was written specifically for use as a "Script Check" in mind, where it the output is deliberaly light unless a warning or error condition is found that needs more investigation. - - If the totalhours of uptime of the computer is greater than or equal to the warning limit, an error is returned. -#> - -[cmdletbinding()] -Param( - [Parameter(Mandatory = $false)] - [int]#Warn if the uptime total hours is over this limit. Defaults to 2.5 days. - $maximumUptimeHoursWarningLimit = 60 -) - -$uptime = (get-Date) - (Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -ExpandProperty LastBootUpTime) - #v7 introduces Get-Uptime, but using WMI is backwards compatiable with v5 - -If($uptime.TotalHours -ge $maximumUptimeHoursWarningLimit){ - "Uptime is over threshold ($($uptime.TotalHours)/$maximumUptimeHoursWarningLimit)" - Exit 1 -} - -"Uptime is below threshold ($($uptime.TotalHours)/$maximumUptimeHoursWarningLimit)" -Exit 0 \ No newline at end of file diff --git a/scripts_wip/Win_Disk_HealthCheck.ps1 b/scripts_wip/Win_Disk_HealthCheck.ps1 deleted file mode 100644 index 24993dc4..00000000 --- a/scripts_wip/Win_Disk_HealthCheck.ps1 +++ /dev/null @@ -1,92 +0,0 @@ -<# -.Synopsis - Outputs Drive Health -.DESCRIPTION - This was written specifically for use as a "Script Check" in mind, where it the output is deliberaly light unless a warning or error condition is found that needs more investigation. - - Uses the Windows Storage Reliabilty Counters first (the information behind Settings - Storage - Disks & Volumes - %DiskID% - Drive health) to report on drive health. - - Will exit if running on a virtual machine. - -.NOTES - Learing taken from "Win_Disk_SMART2.ps1" by nullzilla, and modified by: redanthrax -#> - -# Requires -Version 5.0 -# Requires -RunAsAdministrator -[cmdletbinding()] -Param( - [Parameter(Mandatory = $false)] - [int]#Warn if the temperature (in degrees C) is over this limit - $TemperatureWarningLimit = 55, - - [Parameter(Mandatory = $false)] - [int]#Warn if the "wear" of the drive (as a percentage) is above this - $maximumWearAllowance = 20, - - [Parameter(Mandatory = $false)] - [switch]#Outputs a full report, instead of warnings only - $fullReport -) - -BEGIN { - # If this is a virtual machine, we don't need to continue - $Computer = Get-CimInstance -ClassName 'Win32_ComputerSystem' - if ($Computer.Model -like 'Virtual*') { - exit - } - } - -PROCESS { - Try{ - #Using Windows Storage Reliabilty Counters first (the information behind Settings - Storage - Disks & Volumes - %DiskID% - Drive health) - $physicalDisks = Get-PhysicalDisk -ErrorAction Stop - $storageResults = @() - foreach ($disk in $physicalDisks) { - $reliabilityCounter = $null - try { - $reliabilityCounter = $disk | Get-StorageReliabilityCounter -ErrorAction Stop - } - catch { - Write-Error "No Storage Reliability Counter for '$($disk.FriendlyName)'. This usually means the driver/controller isn't exposing it." - } - - $storageResults += [pscustomobject]@{ - FriendlyName = $disk.FriendlyName - SerialNumber = $disk.SerialNumber - BusType = $disk.BusType - HealthStatus = $disk.HealthStatus - OperationalStatus = ($disk.OperationalStatus -join ", ") - Temperature = $reliabilityCounter.Temperature - Wear = $reliabilityCounter.Wear - ReadErrorsTotal = $reliabilityCounter.ReadErrorsTotal - WriteErrorsTotal = $reliabilityCounter.WriteErrorsTotal - ReallocatedSectors = $reliabilityCounter.ReallocatedSectors - PowerOnHours = $reliabilityCounter.PowerOnHours - } - - If( - $disk.HealthStatus.ToLower() -ne "healthy" -or - ($disk.OperationalStatus | Where-Object -FilterScript { $_.ToLower() -ne "ok" }) -or - $reliabilityCounter.Wear -ge $maximumWearAllowance -or - $reliabilityCounter.Temperature -ge $TemperatureWarningLimit - ){ - Write-Error -Message "$($disk.FriendlyName) has conditions that require investigation. $storageResults" - } - } - - If($fullReport) { $storageResults } - - } catch { - Write-Error -Message "Get-PhysicalDisk failed. This can happen on older OS builds or restricted environments." - } -} - -END{ - if ($error) { - Write-Output $error - exit 1 - } - Write-Output "All drives report as healthy" - Exit 0 -} \ No newline at end of file diff --git a/scripts_wip/Win_Disk_SMART.ps1 b/scripts_wip/Win_Disk_SMART.ps1 deleted file mode 100644 index c255e5a3..00000000 --- a/scripts_wip/Win_Disk_SMART.ps1 +++ /dev/null @@ -1,215 +0,0 @@ -# Requires -Version 4.0 -# Requires -RunAsAdministrator - -<# -.Synopsis - Outputs SMART data -.DESCRIPTION - Checks the system for a comprehensive list of SMART data. - Will exit on finding a virtual machine. - Use the -Warning flag to only get warnings instead of all data. - Use the -Pretty flag to make the output pretty. -.EXAMPLE - Win_Hardware_Disk_SMART -.EXAMPLE - Win_Hardware_Disk_SMART -Warning -.EXAMPLE - Win_Hardware_Disk_SMART -Warning -Pretty -.NOTES - Version: 1.0 - Author: nullzilla - Modified by: redanthrax -#> - -Param( - [Parameter(Mandatory = $false)] - [switch]$Warning, - - [Parameter(Mandatory = $false)] - [switch]$Pretty -) - -function Win_Hardware_Disk_SMART { - [CmdletBinding()] - Param( - [Parameter(Mandatory = $false)] - [switch]$Warning, - - [Parameter(Mandatory = $false)] - [switch]$Pretty - ) - - Begin { - # If this is a virtual machine, we don't need to continue - $Computer = Get-CimInstance -ClassName 'Win32_ComputerSystem' - if ($Computer.Model -like 'Virtual*') { - exit - } - } - - Process { - Try { - $data = @{} - $disks = (Get-CimInstance -Namespace 'Root\WMI' -ClassName 'MSStorageDriver_FailurePredictStatus' | Select-Object 'InstanceName') - foreach ($disk in $disks.InstanceName) { - $SmartData = (Get-CimInstance -Namespace 'Root\WMI' -ClassName 'MSStorageDriver_ATAPISMartData' | Where-Object 'InstanceName' -eq $disk) - [Byte[]]$RawSmartData = $SmartData | Select-Object -ExpandProperty 'VendorSpecific' - # Starting at the third number (first two are irrelevant) - # get the relevant data by iterating over every 12th number - # and saving the values from an offset of the SMART attribute ID - [PSCustomObject[]]$Output = for ($i = 2; $i -lt $RawSmartData.Count; $i++) { - if (0 -eq ($i - 2) % 12 -and $RawSmartData[$i] -ne 0) { - # Construct the raw attribute value by combining the two bytes that make it up - [Decimal]$RawValue = ($RawSmartData[$i + 6] * [Math]::Pow(2, 8) + $RawSmartData[$i + 5]) - - $InnerOutput = [PSCustomObject]@{ - ID = $RawSmartData[$i] - #Flags = $RawSmartData[$i + 1] - #Value = $RawSmartData[$i + 3] - Worst = $RawSmartData[$i + 4] - RawValue = $RawValue - } - - $InnerOutput - - } - } - - # View full table with - #$Output - - $diskData = [PSCustomObject]@{ - "Reallocated Sector Count" = ($Output | Where-Object ID -eq 5 | Select-Object -ExpandProperty RawValue) - "Spin Retry Count" = ($Output | Where-Object ID -eq 10 | Select-Object -ExpandProperty RawValue) - "Recalibration Retries" = ($Output | Where-Object ID -eq 11 | Select-Object -ExpandProperty RawValue) - "Used Reserved Block Count Total" = ($Output | Where-Object ID -eq 179 | Select-Object -ExpandProperty RawValue) - "Erase Failure Count" = ($Output | Where-Object ID -eq 182 | Select-Object -ExpandProperty RawValue) - "SATA Downshift Error Countor Runtime Bad Block" = ($Output | Where-Object ID -eq 183 | Select-Object -ExpandProperty RawValue) - "End-to-End error / IOEDC" = ($Output | Where-Object ID -eq 184 | Select-Object -ExpandProperty RawValue) - "Reported Uncorrectable Errors" = ($Output | Where-Object ID -eq 187 | Select-Object -ExpandProperty RawValue) - "Command Timeout" = ($Output | Where-Object ID -eq 188 | Select-Object -ExpandProperty RawValue) - "High Fly Writes" = ($Output | Where-Object ID -eq 189 | Select-Object -ExpandProperty RawValue) - "Temperature Celcius" = ($Output | Where-Object ID -eq 194 | Select-Object -ExpandProperty RawValue) - "Reallocation Event Count" = ($Output | Where-Object ID -eq 196 | Select-Object -ExpandProperty RawValue) - "Current Pending Sector Count" = ($Output | Where-Object ID -eq 197 | Select-Object -ExpandProperty RawValue) - "Uncorrectable Sector Count" = ($Output | Where-Object ID -eq 198 | Select-Object -ExpandProperty RawValue) - "UltraDMA CRC Error Count" = ($Output | Where-Object ID -eq 199 | Select-Object -ExpandProperty RawValue) - "Soft Read Error Rate" = ($Output | Where-Object ID -eq 201 | Select-Object -ExpandProperty RawValue) - "SSD Life Left" = ($Output | Where-Object ID -eq 231 | Select-Object -ExpandProperty RawValue) - "SSD Media Wear Out Indicator" = ($Output | Where-Object ID -eq 233 | Select-Object -ExpandProperty RawValue) - "Power On Hours" = ($Output | Where-Object ID -eq 9 | Select-Object -ExpandProperty RawValue) - "FailurePredictStatus" = ( - Get-CimInstance -Namespace 'Root\WMI' -ClassName 'MSStorageDriver_FailurePredictStatus' | - Select-Object PredictFailure, Reason - ) - "DiskDriveOkay" = ( - Get-CimInstance -ClassName 'Win32_DiskDrive' | - Select-Object -ExpandProperty Status - ) - "PhysicalDiskOkayAndHealthy" = ( - Get-PhysicalDisk | - Select-Object OperationalStatus, HealthStatus - ) - } - - $data.Add($disk, $diskData) - } - - #Only output warnings - if ($Warning) { - $warnings = @{} - $data.GetEnumerator() | Foreach-Object { - $diskWarnings = @{} - $_.Value.psobject.Members | ForEach-Object { - $item = $_ - switch ($_.Name) { - #Anything in this section will cause the script to return warning. - "Power On Hours" { if ($null -ne $item.Value -and $item.Value -gt 50000) { $diskWarnings.Add($item.Name, $item.Value) } } #Remove line or adjust 50000 number if you don't want Old drives to start returning Warnings - "Reallocated Sector Count" { if ($null -ne $item.Value -and $item.Value -gt 1) { $diskWarnings.Add($item.Name, $item.Value) } } - "Recalibration Retries" { if ($null -ne $item.Value -and $item.Value -ne 0) { $diskWarnings.Add($item.Name, $item.Value) } } - "Used Reserved Block Count Total" { if ($null -ne $item.Value -and $item.Value -gt 1) { $diskWarnings.Add($item.Name, $item.Value) } } - "Erase Failure Count" { if ($null -ne $item.Value -and $item.Value -ne 0) { $diskWarnings.Add($item.Name, $item.Value) } } - "SATA Downshift Error Countor Runtime Bad Block" { if ($null -ne $item.Value -and $item.Value -ne 0) { $diskWarnings.Add($item.Name, $item.Value) } } - "End-to-End error / IOEDC" { if ($null -ne $item.Value -and $item.Value -ne 0) { $diskWarnings.Add($item.Name, $item.Value) } } - "Reported Uncorrectable Errors" { if ($null -ne $item.Value -and $item.Value -ne 0) { $diskWarnings.Add($item.Name, $item.Value) } } - "Command Timeout" { if ($null -ne $item.Value -and $item.Value -gt 2) { $diskWarnings.Add($item.Name, $item.Value) } } - "High Fly Writes" { if ($null -ne $item.Value -and $item.Value -ne 0) { $diskWarnings.Add($item.Name, $item.Value) } } - "Temperature Celcius" { if ($null -ne $item.Value -and $item.Value -gt 50) { $diskWarnings.Add($item.Name, $item.Value) } } - "Reallocation Event Count" { if ($null -ne $item.Value -and $item.Value -ne 0) { $diskWarnings.Add($item.Name, $item.Value) } } - "Current Pending Sector Count" { if ($null -ne $item.Value -and $item.Value -ne 0) { $diskWarnings.Add($item.Name, $item.Value) } } - "Uncorrectable Sector Count" { if ($null -ne $item.Value -and $item.Value -ne 0) { $diskWarnings.Add($item.Name, $item.Value) } } - "UltraDMA CRC Error Count" { if ($null -ne $item.Value -and $item.Value -ne 0) { $diskWarnings.Add($item.Name, $item.Value) } } - "Soft Read Error Rate" { if ($null -ne $item.Value -and $item.Value -lt 95) { $diskWarnings.Add($item.Name, $item.Value) } } - "SSD Life Left" { if ($null -ne $item.Value -and $item.Value -lt 50) { $diskWarnings.Add($item.Name, $item.Value) } } - "SSD Media Wear Out Indicator" { if ($null -ne $item.Value -and $item.Value -lt 50) { $diskWarnings.Add($item.Name, $item.Value) } } - "FailurePredictStatus" { if ($item.Value | Where-Object PredictFailure -ne $False) { $diskWarnings.Add($item.Name, $item.Value) } } - "DiskDriveOkay" { if ($null -ne $item.Value -and $item.Value -ne 'OK') { $diskWarnings.Add($item.Name, $item.Value) } } - "PhysicalDiskOkayAndHealthy" { if ($item.Value | Where-Object { ($_.OperationalStatus -ne 'OK') -or ($_.HealthStatus -ne 'Healthy') }) { $diskWarnings.Add($item.Name, $item.Value) } } - } - } - - if ($diskWarnings.Count -gt 0) { - $warnings.Add($_.Key, $diskWarnings) - } - } - - if ($warnings.Count -gt 0) { - if ($Pretty) { - foreach ($key in $warnings.Keys) { - Write-Output "Disk: $key" - Write-Output $warnings[$key] - } - } - else { - $warnings - } - Write-Output "Done" - Exit 1 - } - } - else { - if ($Pretty) { - foreach ($key in $data.Keys) { - Write-Output "Disk: $key" - Write-Output $data[$key] - } - } - else { - $data - } - } - } - - Catch { - $exception = $_.Exception - Write-Output "Error: $exception" - Write-Output "Done" - Exit 1 - } - } - - End { - if ($Error) { - if ($Error -match "Not supported") { - Write-Output "You may need to switch from ACHI to RAID/RST mode, see the link for how to do this non-destructively: https://www.top-password.com/blog/switch-from-raid-to-ahci-without-reinstalling-windows/" - } - - Write-Output $Error - Write-Output "Done" - exit 1 - } - Write-Output "Done" - Exit 0 - } -} - -if (-not(Get-Command 'Win_Hardware_Disk_SMART' -errorAction SilentlyContinue)) { - . $MyInvocation.MyCommand.Path -} - -$scriptArgs = @{ - Warning = $Warning - Pretty = $Pretty -} - -Win_Hardware_Disk_SMART @scriptArgs \ No newline at end of file diff --git a/scripts_wip/Win_Disk_Space_Check.ps1 b/scripts_wip/Win_Disk_Space_Check.ps1 deleted file mode 100644 index 17242a1a..00000000 --- a/scripts_wip/Win_Disk_Space_Check.ps1 +++ /dev/null @@ -1,104 +0,0 @@ -<# -.Synopsis - Checks all FileSystem drives for an amount of space specified. Fails if less than space specified. -.DESCRIPTION - Long description - Checks all FileSystem drives for an amount of space specified (amount is converted to Gigabytes). -.EXAMPLE - Confirm-DiskSpaceAvailable -Size 10 -.EXAMPLE - Confirm-DiskSpaceAvailable -Size 10 -Percent -.NOTES - Version: 1.0 - Author: redanthrax - Creation Date: 2022-04-05 - Updated: Owen Conti 2025-12-12 -#> - -Param( - [Parameter(Mandatory)] - [int]#The minimum amount of GB that should be available - $Size, - - [Parameter(Mandatory = $false)] - [switch]#Switches the Size to be a percentage instead of GB - $Percent, - - [Parameter(Mandatory = $false)] - [switch]#Writes a message out even when the drive has more than the minimum available amount. In other words, logs *every* time. - $outputSuccess -) - -function Confirm-DiskSpaceAvailable { - [CmdletBinding()] - Param( - [Parameter(Mandatory)] - [int]#The minimum amount of GB that should be available - $Size, - - [Parameter(Mandatory = $false)] - [switch]#Switches the Size to be a percentage instead of GB - $Percent, - - [Parameter(Mandatory = $false)] - [switch]#Writes a message out even when the drive has more than the minimum available amount. In other words, logs *every* time. - $outputSuccess - ) - - Begin {} - - Process { - Try { - $errors = 0 - $drives = Get-PSDrive | Where-Object { $_.Provider.Name -eq "FileSystem" -and $_.Used -gt 0 -and $_.Name.ToLower() -ne "temp" } - foreach ($drive in $drives) { - [string]$label = "GB" - [double]$available = 0 - if ($Percent) { - #Percent flag is set - #Calculate percent of free space left on drive - $available = [math]::Round(($drive.Free / ($drive.Free + $drive.Used)) * 100,2) - $label = "%" - } - else { - $available = [math]::Round($drive.Free / 1Gb, 2) - } - - If($outputSuccess){ - Write-Output "$available $label space remaining on $($drive.Name)." - } - - if ($Size -gt $available) { - Write-Output "ERROR: $($drive.Name) is below the threshold of $size $label ($available available)." - $errors += 1 - } - } - } - - Catch { - Write-Output "Error: ${$_.Exception}" - Exit 1 - } - } - - End { - if ($errors -gt 0) { - Exit 1 - } - - Write-Output "All disks have been checked and have more than or equal to $size $label space available." - Exit 0 - } -} - -if (-not(Get-Command 'Confirm-DiskSpaceAvailable' -errorAction SilentlyContinue)) { - . $MyInvocation.MyCommand.Path -} - -$scriptArgs = @{ - Size = $Size - Percent = $Percent - outputSuccess = $outputSuccess -} - -Confirm-DiskSpaceAvailable @scriptArgs \ No newline at end of file diff --git a/scripts_wip/Win_RAM_Available_Check.ps1 b/scripts_wip/Win_RAM_Available_Check.ps1 deleted file mode 100644 index 503f2c82..00000000 --- a/scripts_wip/Win_RAM_Available_Check.ps1 +++ /dev/null @@ -1,39 +0,0 @@ -<# -.Synopsis - Checks the available amount of RAM on a computer -.DESCRIPTION - This was written specifically for use as a "Script Check" in mind, where it the output is deliberaly light unless a warning or error condition is found that needs more investigation. - - If the total available (free) amount of RAM is less than the warning limit, an error is returned. - -#> - -[cmdletbinding()] -Param( - [Parameter(Mandatory = $false)] - [double]#Warn if the amount of available RAM (defaults to GB) is below this limit. Defaults to 1 GB. - $minimumAvailableRAM = 1, - - [Parameter(Mandatory = $false)] - [switch]#Use percentage instead of absolute GB values - $percent -) - -$os = Get-CimInstance -ClassName Win32_OperatingSystem - -$available = [math]::Round(($os.FreePhysicalMemory * 1KB) / 1GB, 2) -$label = "GB" -if ($Percent) { - #Percent flag is set - #Calculate percent of free available RAM - $available = [math]::Round(($os.FreePhysicalMemory / $os.TotalVisibleMemorySize) * 100, 1) - $label = "%" -} - -If($minimumAvailableRAM -gt $available){ - Write-Output "Avalable RAM is below the threshold of $minimumAvailableRAM $label ($available $label available)." - Exit 1 -} else { - Write-Output "Avalable RAM is above the threshold of $minimumAvailableRAM $label ($available $label available)." - Exit 0 -} \ No newline at end of file From 503c48ee5b4a1fc9d04511838afe59203e2202b7 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Mon, 12 Jan 2026 11:18:09 +0000 Subject: [PATCH 2/3] Added Move Agent script and WhoAmI helper --- scripts_wip/Win_TRMM_GetLoggedOnUPN.ps1 | 1 + .../Win_TRMM_MoveAgentToCorrectSite.ps1 | 113 ++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 scripts_wip/Win_TRMM_GetLoggedOnUPN.ps1 create mode 100644 scripts_wip/Win_TRMM_MoveAgentToCorrectSite.ps1 diff --git a/scripts_wip/Win_TRMM_GetLoggedOnUPN.ps1 b/scripts_wip/Win_TRMM_GetLoggedOnUPN.ps1 new file mode 100644 index 00000000..b3af54eb --- /dev/null +++ b/scripts_wip/Win_TRMM_GetLoggedOnUPN.ps1 @@ -0,0 +1 @@ +whoami /upn \ No newline at end of file diff --git a/scripts_wip/Win_TRMM_MoveAgentToCorrectSite.ps1 b/scripts_wip/Win_TRMM_MoveAgentToCorrectSite.ps1 new file mode 100644 index 00000000..f68c9648 --- /dev/null +++ b/scripts_wip/Win_TRMM_MoveAgentToCorrectSite.ps1 @@ -0,0 +1,113 @@ +<# +.DESCRIPTION +Moves an Windows Workstation Agent to the first Site created for the Client with a match in the Client's "Domains" Custom Field. + +Assumptions made: + - The User will be on a Windows client machine and logged in with their Microsoft 365 account, therefore their UPN will be their M365 username (UPN) + - The lowest value ID site per Client is the one you want the Agent to be pushed to (or Clients only have 1 site) + - - If this is not true, you'll need to update the "Determine the Site..." region with logic that returns the desired site(s) + - There is a Client Custom Field called "Domains" and it's for all of the the domains that could be valid for the UPN + +You will need: + - A script in TRMM that runs "whoami /upn" and the ID of that script (hover over it) - E.g. "Win_TRMM_GetLoggedOnUPN.ps1" + - - The ID will be the value supplied to the "-whoAmIScriptId" script arguement + - - This is deliberately not done as a script snippit because it must be run as the USER (and not SYSTEM) + - A Client Custom Field for storing domains exists, and is populated with the domains that any valid UPN may have for the given Client + - - The name of this field can be overridden by supplying the "-clientCustomFieldName" script argument with a value + +.SYNOPSIS +Moves an Agent to the first Site created for the Client with a match in the Client's "Domains" Custom Field. (Assumes Windows & the user is logged in with their M365 account, and requires an additional script (see Description).) + +.NOTES +v1.0 2026-01-12 Owen Conti + +#> + +[cmdletbinding()] +Param( + [string]#Provided by using the script arguement "-agentId {{agent.agent_id}}" + $agentId, + [string]#The API Key value to use. A better approach is to pass this with an ENVIRONMENT VARIABLE in the script triggering so your API key is not logged in the Windows Event Log on all the Clients that run this. If you provide a value here it will override any environment variable you provide. + $apiKey, + [int]#The ID of the "WhoAmI" script on your environment + $whoAmIScriptId, + [string]#The FQDN of your API end point (the URI is built later). E.g. "api.example.com" + $apiFQDN, + [string]#The exact name of the Client level Custom Field used for storing the valid Domains + $clientCustomFieldName = "Domains" +) + +#region script wide parameters +If($apiKey){ + $apiAuthKey = $apiKey +} else { + $apiAuthKey = $env:apiKey +} + +$headers = @{ + 'Content-Type' = 'application/json' + 'X-API-KEY' = $apiAuthKey +} #These are common to all our API calls +#endRegion + + +#region Collect the User's UPN using the "Who Am I" script +$whoamiPayload = @{ + output = "wait" + emails = @() + emailMode = "default" + custom_field = $null + save_all_output = $false + script = $whoAmIScriptId + args = @() + env_vars = @() + run_as_user = $false + timeout = 10 +} | ConvertTo-Json + +$upn = Invoke-RestMethod -Uri "https://$apiFQDN/agents/$agentId/runscript/" -Method POST -Body $whoamiPayload -Headers $headers +If($upn.Contains("ERROR:")) +{ + #The user is not logged in with an account that presents the UPN to whoami.exe + Write-Error "An error occured when trying to collect the UPN of the user: $upn" + Exit 1 +} +#endRegion + +#region Determine the Site (and therefore Client) the user belongs to +$domain = $upn.Split("@")[1].Trim() #The trim is required as trailing spaces cause problems +#Need to define a method for doing a lookup for UPN domain to Customer ID to correct Site in TRMM +$customFields = Invoke-RestMethod -Uri "https://$apiFQDN/core/customfields" -Method GET -Headers $headers +$domainFieldId = $customFields | Where-Object -FilterScript {$_.model -eq "client" -and $_.name -eq $clientCustomFieldName} | Select-Object -ExpandProperty id + +$clients = Invoke-RestMethod -Uri "https://$apiFQDN/clients/" -Method GET -Headers $headers +$siteId = $clients | + Where-Object {$_.custom_fields.field -eq $domainFieldId -and $_.custom_fields.value -match $domain} | + Select-Object -ExpandProperty sites | + Sort-Object -Property id | + Select-Object -ExpandProperty id -First 1 +#endRegion + +#region Move the agent to the correct site +If($siteId){ + + $body = @{ + site = $siteId + } | ConvertTo-Json + + $moveResult = Invoke-RestMethod -Method PUT -Uri "https://$apiFQDN/agents/$agentId" -Headers $headers -Body $body + If($moveResult -eq "The agent was updated successfully") + { + $moveResult + Exit 0 + } else { + Write-Error "There was a problem with the API call to move the Agent" + $moveResult + Exit 1 + } + +} else { + Write-Error "There was a problem collecting the Site ID. The domain value is between the asterisks: ***$domain*** Check the Clients and ensure this domain value is in the correct place." + Exit 1 +} +#endRegion \ No newline at end of file From 85471d7afbed37a910c9f61bc7aba2af7d1a5d19 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Mon, 12 Jan 2026 11:20:05 +0000 Subject: [PATCH 3/3] Updated output to be much shorter so "everything" can be seen at one glance in the Checks view. --- scripts_wip/Win_Battery_Capacity_Check.ps1 | 49 +++++++++++++ scripts_wip/Win_CPU_Uptime_Check.ps1 | 26 +++++++ scripts_wip/Win_Disk_HealthCheck.ps1 | 84 ++++++++++++++++++++++ scripts_wip/Win_Disk_Space_Check.ps1 | 64 +++++++++++++++++ scripts_wip/Win_RAM_Available_Check.ps1 | 36 ++++++++++ 5 files changed, 259 insertions(+) create mode 100644 scripts_wip/Win_Battery_Capacity_Check.ps1 create mode 100644 scripts_wip/Win_CPU_Uptime_Check.ps1 create mode 100644 scripts_wip/Win_Disk_HealthCheck.ps1 create mode 100644 scripts_wip/Win_Disk_Space_Check.ps1 create mode 100644 scripts_wip/Win_RAM_Available_Check.ps1 diff --git a/scripts_wip/Win_Battery_Capacity_Check.ps1 b/scripts_wip/Win_Battery_Capacity_Check.ps1 new file mode 100644 index 00000000..f2bc2619 --- /dev/null +++ b/scripts_wip/Win_Battery_Capacity_Check.ps1 @@ -0,0 +1,49 @@ +<# +.Synopsis + Checks the battery full charge capacity VS the design capacity +.DESCRIPTION + This was written specifically for use as a "Script Check" in mind, where it the output is deliberaly light unless a warning or error condition is found that needs more investigation. + + If the total full charge capacity is less than the minimum capacity amount, an error is returned. +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $false)] + [int]#The minimum battery full charge capacity (as a percentage of design capacity by default). Defaults to 85 percent. + $minimumBatteryCapacity = 85, + + [Parameter(Mandatory = $false)] + [switch]#Set the check condition to absolute mWh values instead of a percentage + $absoluteValues +) + +try{ + $searcher = New-Object System.Management.ManagementObjectSearcher("root\wmi","SELECT * FROM BatteryStaticData") + $batteryStatic = $searcher.Get() + #CIM approach threw errors when Get-WMIObject did not - WMI approach is not available in PSv7, so took .NET approach + $batteryCharge = Get-CimInstance -Namespace "root\wmi" -ClassName "BatteryFullChargedCapacity" -ErrorAction Stop +} catch { + Write-Output "No battery detected" + exit 0 +} + +if (-not $batteryStatic -or -not $batteryCharge) { + Write-Output "No battery detected" + exit 0 +} + +$chargeCapacity = $batteryCharge.FullChargedCapacity +$designCapacity = $batteryStatic.DesignedCapacity + +$available = [math]::Round(($chargeCapacity / $designCapacity) * 100,2) +$label = "%" +if ($absoluteValues) { + $available = $chargeCapacity + $label = "mWh" +} + +"Full charge capacity $available$label of $designCapacity mWh." + +If($available -le $minimumBatteryCapacity){ Exit 1 } +Exit 0 \ No newline at end of file diff --git a/scripts_wip/Win_CPU_Uptime_Check.ps1 b/scripts_wip/Win_CPU_Uptime_Check.ps1 new file mode 100644 index 00000000..2cbd2638 --- /dev/null +++ b/scripts_wip/Win_CPU_Uptime_Check.ps1 @@ -0,0 +1,26 @@ +<# +.Synopsis + Checks Uptime of the computer +.DESCRIPTION + This was written specifically for use as a "Script Check" in mind, where it the output is deliberaly light unless a warning or error condition is found that needs more investigation. + + If the totalhours of uptime of the computer is greater than or equal to the warning limit, an error is returned. +#> + +[cmdletbinding()] +Param( + [Parameter(Mandatory = $false)] + [int]#Warn if the uptime total hours is over this limit. Defaults to 2.5 days. + $maximumUptimeHoursWarningLimit = 60 +) + +$uptime = (get-Date) - (Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -ExpandProperty LastBootUpTime) + #v7 introduces Get-Uptime, but using WMI is backwards compatiable with v5 + +$hiberbootEnabled = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power' -Name 'HiberbootEnabled' -ErrorAction Stop).HiberbootEnabled +[bool]$FastStartupEnabled = ($hiberbootEnabled -eq 1) + +"CPU Uptime $([math]::Round($uptime.TotalHours,2)) hours. Fast Startup enabled: $FastStartupEnabled" + +If($uptime.TotalHours -ge $maximumUptimeHoursWarningLimit){ Exit 1 } +Exit 0 \ No newline at end of file diff --git a/scripts_wip/Win_Disk_HealthCheck.ps1 b/scripts_wip/Win_Disk_HealthCheck.ps1 new file mode 100644 index 00000000..87319f39 --- /dev/null +++ b/scripts_wip/Win_Disk_HealthCheck.ps1 @@ -0,0 +1,84 @@ +<# +.Synopsis + Outputs Drive Health +.DESCRIPTION + This was written specifically for use as a "Script Check" in mind, where it the output is deliberaly light unless a warning or error condition is found that needs more investigation. + + Uses the Windows Storage Reliabilty Counters first (the information behind Settings - Storage - Disks & Volumes - %DiskID% - Drive health) to report on drive health. + + Will exit if running on a virtual machine. + +.NOTES + Learing taken from "Win_Disk_SMART2.ps1" by nullzilla, and modified by: redanthrax +#> + +# Requires -Version 5.0 +# Requires -RunAsAdministrator +[cmdletbinding()] +Param( + [Parameter(Mandatory = $false)] + [int]#Warn if the temperature (in degrees C) is over this limit + $TemperatureWarningLimit = 60, + + [Parameter(Mandatory = $false)] + [int]#Warn if the "wear" of the drive (as a percentage) is above this + $maximumWearAllowance = 20 +) + +BEGIN { + # If this is a virtual machine, we don't need to continue + $Computer = Get-CimInstance -ClassName 'Win32_ComputerSystem' + if ($Computer.Model -like 'Virtual*') { + exit + } + } + +PROCESS { + Try{ + #Using Windows Storage Reliabilty Counters first (the information behind Settings - Storage - Disks & Volumes - %DiskID% - Drive health) + $physicalDisks = Get-PhysicalDisk -ErrorAction Stop + foreach ($disk in $physicalDisks) { + $reliabilityCounter = $null + try { + $reliabilityCounter = $disk | Get-StorageReliabilityCounter -ErrorAction Stop + } + catch { + Write-Error "No Storage Reliability Counter for '$($disk.FriendlyName)'. This usually means the driver/controller isn't exposing it." + } + $driveLetters = (get-disk -FriendlyName $Disk.FriendlyName | Get-Partition | Where-Object -FilterScript {$_.DriveLetter} | Select-Object -Expand DriveLetter) -join ", " + + <# + DriveLetters = $driveLetters + HealthStatus = $disk.HealthStatus + FriendlyName = $disk.FriendlyName + SerialNumber = $disk.SerialNumber + BusType = $disk.BusType + OperationalStatus = ($disk.OperationalStatus -join ", ") + Temperature = $reliabilityCounter.Temperature + Wear = $reliabilityCounter.Wear + ReadErrorsTotal = $reliabilityCounter.ReadErrorsTotal + WriteErrorsTotal = $reliabilityCounter.WriteErrorsTotal + ReallocatedSectors = $reliabilityCounter.ReallocatedSectors + PowerOnHours = $reliabilityCounter.PowerOnHours + #> + If( + $disk.HealthStatus.ToLower() -ne "healthy" -or + ($disk.OperationalStatus | Where-Object -FilterScript { $_.ToLower() -ne "ok" }) -or + $reliabilityCounter.Wear -gt $maximumWearAllowance -or + $reliabilityCounter.Temperature -gt $TemperatureWarningLimit + ){ + "Disk issue: $DriveLetters $($disk.HealthStatus) Status:$(($disk.OperationalStatus -join ", ")) $($reliabilityCounter.Temperature)*C $($reliabilityCounter.Wear)% wear" + Write-Error -Message "Disk issues need investigating" + } else { + "$DriveLetters $($disk.HealthStatus) Status:$(($disk.OperationalStatus -join ", ")) $($reliabilityCounter.Temperature)*C $($reliabilityCounter.Wear)% wear" + } + } + } catch { + Write-Error -Message "Get-PhysicalDisk failed. This can happen on older OS builds or restricted environments." + } +} + +END{ + if ($error) { Exit 1 } + Exit 0 +} \ No newline at end of file diff --git a/scripts_wip/Win_Disk_Space_Check.ps1 b/scripts_wip/Win_Disk_Space_Check.ps1 new file mode 100644 index 00000000..d9bb2713 --- /dev/null +++ b/scripts_wip/Win_Disk_Space_Check.ps1 @@ -0,0 +1,64 @@ +<# +.Synopsis + Checks all FileSystem drives for an amount of space specified. Fails if less than space specified. +.DESCRIPTION + Long description + Checks all FileSystem drives for an amount of space specified (amount is converted to Gigabytes). +.EXAMPLE + Confirm-DiskSpaceAvailable -Size 10 +.EXAMPLE + Confirm-DiskSpaceAvailable -Size 10 -Percent +.NOTES + Version: 1.0 + Author: redanthrax + Creation Date: 2022-04-05 + Updated: Owen Conti 2025-12-12 +#> + +Param( + [Parameter(Mandatory = $false)] + [int]#The minimum amount of GB that should be available + $Size = 25, + + [Parameter(Mandatory = $false)] + [switch]#Switches the Size to be a percentage instead of GB + $Percent +) + +Begin {} + +Process { + Try { + $errors = 0 + $drives = Get-PSDrive | Where-Object { $_.Provider.Name -eq "FileSystem" -and $_.Used -gt 0 -and $_.Name.ToLower() -ne "temp" } + foreach ($drive in $drives) { + [string]$label = "GB" + [double]$available = 0 + if ($Percent) { + #Percent flag is set + #Calculate percent of free space left on drive + $available = [math]::Round(($drive.Free / ($drive.Free + $drive.Used)) * 100,2) + $label = "%" + } + else { + $available = [math]::Round($drive.Free / 1Gb, 2) + } + + "$($drive.Name) $available $label space remaining." + + if ($Size -gt $available) { + $errors += 1 + } + } + } + + Catch { + "ERROR: ${$_.Exception}" + Exit 1 + } +} + +End { + if ($errors -gt 0) { Exit 1 } + Exit 0 +} diff --git a/scripts_wip/Win_RAM_Available_Check.ps1 b/scripts_wip/Win_RAM_Available_Check.ps1 new file mode 100644 index 00000000..02532ffb --- /dev/null +++ b/scripts_wip/Win_RAM_Available_Check.ps1 @@ -0,0 +1,36 @@ +<# +.Synopsis + Checks the available amount of RAM on a computer +.DESCRIPTION + This was written specifically for use as a "Script Check" in mind, where it the output is deliberaly light unless a warning or error condition is found that needs more investigation. + + If the total available (free) amount of RAM is less than the warning limit, an error is returned. + +#> + +[cmdletbinding()] +Param( + [Parameter(Mandatory = $false)] + [double]#Warn if the amount of available RAM (defaults to GB) is below this limit. Defaults to 1 GB. + $minimumAvailableRAM = 0.75, + + [Parameter(Mandatory = $false)] + [switch]#Use percentage instead of absolute GB values + $percent +) + +$os = Get-CimInstance -ClassName Win32_OperatingSystem + +$available = [math]::Round(($os.FreePhysicalMemory * 1KB) / 1GB, 2) +$label = "GB" +if ($Percent) { + #Percent flag is set + #Calculate percent of free available RAM + $available = [math]::Round(($os.FreePhysicalMemory / $os.TotalVisibleMemorySize) * 100, 1) + $label = "%" +} + +"$available $label RAM available." + +If($minimumAvailableRAM -gt $available){ Exit 1 } +Exit 0 \ No newline at end of file