From 770d79402e48418d98d5965acb4d99722443cf24 Mon Sep 17 00:00:00 2001 From: sethvs Date: Wed, 18 Feb 2026 19:33:52 +0300 Subject: [PATCH 1/4] Add support for legacy 6.x, 7.x versions --- functions/DiskSmartInfo.functions.archive.ps1 | 4 ++-- functions/DiskSmartInfo.functions.history.ps1 | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/functions/DiskSmartInfo.functions.archive.ps1 b/functions/DiskSmartInfo.functions.archive.ps1 index 89995f7..c6941d8 100644 --- a/functions/DiskSmartInfo.functions.archive.ps1 +++ b/functions/DiskSmartInfo.functions.archive.ps1 @@ -81,7 +81,7 @@ function inGetArchiveDataFileName $filename = "localhost$($dateTime.ToString('_yyyy-MM-dd_HH-mm-ss')).json" } - if ($IsCoreCLR) + if ($IsCoreCLR -and ($PSVersionTable.PSVersion.Major -ge 7 -or $PSVersionTable.PSVersion.Minor -ge 1)) { if ([System.IO.Path]::IsPathFullyQualified($Config.ArchivePath)) { @@ -92,7 +92,7 @@ function inGetArchiveDataFileName $folder = Join-Path -Path (Split-Path -Path $PSScriptRoot) -ChildPath $Config.ArchivePath } } - # .NET Framework version 4 and lower does not have [System.IO.Path]::IsPathFullyQualified method + # .NET Framework 4 (Windows PowerShell 5.1) and .NET Core 2.0 (PowerShell 6.0) and lower do not have [System.IO.Path]::IsPathFullyQualified method else { $pathroot = [System.IO.Path]::GetPathRoot($Config.ArchivePath) diff --git a/functions/DiskSmartInfo.functions.history.ps1 b/functions/DiskSmartInfo.functions.history.ps1 index 6ddede3..494dd03 100644 --- a/functions/DiskSmartInfo.functions.history.ps1 +++ b/functions/DiskSmartInfo.functions.history.ps1 @@ -69,11 +69,11 @@ function inGetHistoricalData { $sourceHostHistoricalData = ConvertFrom-Json -InputObject $historicalDataFileContent - if ($IsCoreCLR) + if ($IsCoreCLR -and (($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -ge 2) -or $PSVersionTable.PSVersion.Major -gt 7)) { $timestamp = $sourceHostHistoricalData.TimeStamp } - # Windows PowerShell 5.1 ConvertTo-Json converts DateTime objects differently + # Windows PowerShell 5.1 and PowerShell < 7.2 ConvertTo-Json converts DateTime objects differently else { $timestamp = $sourceHostHistoricalData.TimeStamp.DateTime @@ -172,7 +172,7 @@ function inGetHistoricalDataFileName $filename = 'localhost.json' } - if ($IsCoreCLR) + if ($IsCoreCLR -and ($PSVersionTable.PSVersion.Major -ge 7 -or $PSVersionTable.PSVersion.Minor -ge 1)) { if ([System.IO.Path]::IsPathFullyQualified($Config.DataHistoryPath)) { @@ -183,7 +183,7 @@ function inGetHistoricalDataFileName $folder = Join-Path -Path (Split-Path -Path $PSScriptRoot) -ChildPath $Config.DataHistoryPath } } - # .NET Framework version 4 and lower does not have [System.IO.Path]::IsPathFullyQualified method + # .NET Framework 4 (Windows PowerShell 5.1) and .NET Core 2.0 (PowerShell 6.0) and lower do not have [System.IO.Path]::IsPathFullyQualified method else { $pathroot = [System.IO.Path]::GetPathRoot($Config.DataHistoryPath) From bf44f9f56a90f180f78441fec4c379640bf0541b Mon Sep 17 00:00:00 2001 From: sethvs Date: Wed, 18 Feb 2026 19:41:27 +0300 Subject: [PATCH 2/4] Update tasks --- .vscode/tasks.json | 192 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 5ac35fd..0ad64ac 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -99,6 +99,188 @@ } } }, + { + "label": "InvokePester: PowerShell 7.3", + "type": "shell", + "command": "Set-Location ${workspaceFolder}; . ./tests/PesterConfiguration.ps1; Invoke-Pester -Configuration $PesterConfiguration", + "group": { + "kind": "test", + "isDefault": false + }, + "problemMatcher": [ + "$pester" + ], + "presentation": { + "echo": false, + "reveal": "always", + "focus": true, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + }, + "options": { + "shell": { + "executable": "C:/Program Files/PowerShell/7.3/pwsh.exe", + "args": ["-Command"] + } + } + }, + { + "label": "InvokePester: PowerShell 7.2", + "type": "shell", + "command": "Set-Location ${workspaceFolder}; . ./tests/PesterConfiguration.ps1; Invoke-Pester -Configuration $PesterConfiguration", + "group": { + "kind": "test", + "isDefault": false + }, + "problemMatcher": [ + "$pester" + ], + "presentation": { + "echo": false, + "reveal": "always", + "focus": true, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + }, + "options": { + "shell": { + "executable": "C:/Program Files/PowerShell/7.2/pwsh.exe", + "args": ["-Command"] + } + } + }, + { + "label": "InvokePester: PowerShell 7.1", + "type": "shell", + "command": "Set-Location ${workspaceFolder}; . ./tests/PesterConfiguration.ps1; Invoke-Pester -Configuration $PesterConfiguration", + "group": { + "kind": "test", + "isDefault": false + }, + "problemMatcher": [ + "$pester" + ], + "presentation": { + "echo": false, + "reveal": "always", + "focus": true, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + }, + "options": { + "shell": { + "executable": "C:/Program Files/PowerShell/7.1/pwsh.exe", + "args": ["-Command"] + } + } + }, + { + "label": "InvokePester: PowerShell 7.0", + "type": "shell", + "command": "Set-Location ${workspaceFolder}; . ./tests/PesterConfiguration.ps1; Invoke-Pester -Configuration $PesterConfiguration", + "group": { + "kind": "test", + "isDefault": false + }, + "problemMatcher": [ + "$pester" + ], + "presentation": { + "echo": false, + "reveal": "always", + "focus": true, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + }, + "options": { + "shell": { + "executable": "C:/Program Files/PowerShell/7.0/pwsh.exe", + "args": ["-Command"] + } + } + }, + { + "label": "InvokePester: PowerShell 6.2", + "type": "shell", + "command": "Set-Location ${workspaceFolder}; . ./tests/PesterConfiguration.ps1; Invoke-Pester -Configuration $PesterConfiguration", + "group": { + "kind": "test", + "isDefault": false + }, + "problemMatcher": [ + "$pester" + ], + "presentation": { + "echo": false, + "reveal": "always", + "focus": true, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + }, + "options": { + "shell": { + "executable": "C:/Program Files/PowerShell/6.2/pwsh.exe", + "args": ["-Command"] + } + } + }, + { + "label": "InvokePester: PowerShell 6.1", + "type": "shell", + "command": "Set-Location ${workspaceFolder}; . ./tests/PesterConfiguration.ps1; Invoke-Pester -Configuration $PesterConfiguration", + "group": { + "kind": "test", + "isDefault": false + }, + "problemMatcher": [ + "$pester" + ], + "presentation": { + "echo": false, + "reveal": "always", + "focus": true, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + }, + "options": { + "shell": { + "executable": "C:/Program Files/PowerShell/6.1/pwsh.exe", + "args": ["-Command"] + } + } + }, + { + "label": "InvokePester: PowerShell 6.0", + "type": "shell", + "command": "Set-Location ${workspaceFolder}; . ./tests/PesterConfiguration.ps1; Invoke-Pester -Configuration $PesterConfiguration", + "group": { + "kind": "test", + "isDefault": false + }, + "problemMatcher": [ + "$pester" + ], + "presentation": { + "echo": false, + "reveal": "always", + "focus": true, + "panel": "dedicated", + "showReuseMessage": false, + "clear": true + }, + "options": { + "shell": { + "executable": "C:/Program Files/PowerShell/6.0/pwsh.exe", + "args": ["-Command"] + } + } + }, { "label": "InvokePester: Windows PowerShell 5.1", "type": "shell", @@ -134,6 +316,16 @@ }, "problemMatcher": "$pester" }, + { + "label": "InvokePester: Overall Test", + "dependsOn":["InvokePester: PowerShell 7.6", "InvokePester: PowerShell 7.5", "InvokePester: PowerShell 7.4", "InvokePester: PowerShell 7.3", "InvokePester: PowerShell 7.2", "InvokePester: PowerShell 7.1", "InvokePester: PowerShell 7.0", "InvokePester: PowerShell 6.2", "InvokePester: PowerShell 6.1", "InvokePester: PowerShell 6.0", "InvokePester: Windows PowerShell 5.1"], + "dependsOrder": "parallel", + "group": { + "kind": "test", + "isDefault": false + }, + "problemMatcher": "$pester" + }, { "label": "UpdateHelp", "type": "shell", From b6d0bd36cd867a93c922b2639f4266cfc63dde87 Mon Sep 17 00:00:00 2001 From: sethvs Date: Wed, 18 Feb 2026 21:03:25 +0300 Subject: [PATCH 3/4] Cleanup --- ...iskSmartAttributeDescription.functions.ps1 | 2 +- functions/DiskSmartInfo.completers.ps1 | 8 +- functions/DiskSmartInfo.functions.archive.ps1 | 2 +- functions/DiskSmartInfo.functions.history.ps1 | 2 +- .../DiskSmartInfo.functions.internal.ps1 | 73 +- functions/DiskSmartInfo.functions.ps1 | 1062 ++++++++--------- functions/DiskSmartInfo.functions.utility.ps1 | 4 +- 7 files changed, 576 insertions(+), 577 deletions(-) diff --git a/functions/DiskSmartAttributeDescription.functions.ps1 b/functions/DiskSmartAttributeDescription.functions.ps1 index 439a166..ce9b34a 100644 --- a/functions/DiskSmartAttributeDescription.functions.ps1 +++ b/functions/DiskSmartAttributeDescription.functions.ps1 @@ -5,7 +5,7 @@ function Get-DiskSmartAttributeDescription [ValidateRange(1, 255)] [int[]]$AttributeID, [Parameter(Position=1)] - [ValidatePattern("^(0?[1-9A-F])|([1-9A-F])([0-9A-F])$")] + [ValidatePattern('^(0?[1-9A-F])|([1-9A-F])([0-9A-F])$')] [string[]]$AttributeIDHex, [Parameter(Position=2)] [ArgumentCompleter([AttributeNameCompleter])] diff --git a/functions/DiskSmartInfo.completers.ps1 b/functions/DiskSmartInfo.completers.ps1 index 3eca93b..58d819c 100644 --- a/functions/DiskSmartInfo.completers.ps1 +++ b/functions/DiskSmartInfo.completers.ps1 @@ -19,7 +19,7 @@ class AttributeNameCompleter : IArgumentCompleter $attributeNames = $Script:descriptions.AttributeName } - $result = New-Object -TypeName "System.Collections.Generic.List[CompletionResult]" + $result = New-Object -TypeName 'System.Collections.Generic.List[CompletionResult]' [System.Collections.Generic.List[String]]$valuesToExclude = $null @@ -66,7 +66,7 @@ class AttributeNameCompleter : IArgumentCompleter $id = ($Script:descriptions.Find([Predicate[PSCustomObject]]{$args[0].AttributeName -eq $completionResult})).AttributeID } - if ($completionResult.Contains(" ")) + if ($completionResult.Contains(' ')) { $result.Add([CompletionResult]::new("'$completionResult'", $completionResult, [CompletionResultType]::ParameterValue, "${id}: $completionResult")) } @@ -90,7 +90,7 @@ class DiskCompleter : IArgumentCompleter [System.Collections.IDictionary] $fakeBoundParameters ) { - $result = New-Object -TypeName "System.Collections.Generic.List[CompletionResult]" + $result = New-Object -TypeName 'System.Collections.Generic.List[CompletionResult]' [System.Collections.Generic.List[String]]$valuesToExclude = $null $instanceParameters = @{ @@ -201,7 +201,7 @@ class DiskCompleter : IArgumentCompleter if ($completionResult -like "$wordToComplete*" -and $completionResult -notin $valuesToExclude) { $index = ($diskDrives.Where{$_.Model -eq $completionResult}).Index - if ($completionResult.Contains(" ")) + if ($completionResult.Contains(' ')) { $result.Add([CompletionResult]::new("'$completionResult'", $completionResult, [CompletionResultType]::ParameterValue, "${index}: $completionResult")) } diff --git a/functions/DiskSmartInfo.functions.archive.ps1 b/functions/DiskSmartInfo.functions.archive.ps1 index c6941d8..2bd22c0 100644 --- a/functions/DiskSmartInfo.functions.archive.ps1 +++ b/functions/DiskSmartInfo.functions.archive.ps1 @@ -48,7 +48,7 @@ function inUpdateArchive if ($attributes) { - $hash.Add("SmartData", $attributes) + $hash.Add('SmartData', $attributes) $archiveData.Add([PSCustomObject]$hash) } } diff --git a/functions/DiskSmartInfo.functions.history.ps1 b/functions/DiskSmartInfo.functions.history.ps1 index 494dd03..e27dbf6 100644 --- a/functions/DiskSmartInfo.functions.history.ps1 +++ b/functions/DiskSmartInfo.functions.history.ps1 @@ -37,7 +37,7 @@ function inUpdateHistoricalData if ($attributes) { - $hash.Add("SmartData", $attributes) + $hash.Add('SmartData', $attributes) $historicalData.Add([PSCustomObject]$hash) } } diff --git a/functions/DiskSmartInfo.functions.internal.ps1 b/functions/DiskSmartInfo.functions.internal.ps1 index de73f17..62bcd9d 100644 --- a/functions/DiskSmartInfo.functions.internal.ps1 +++ b/functions/DiskSmartInfo.functions.internal.ps1 @@ -162,20 +162,20 @@ function inGetSmartDataStructureCIM if ($attributeID) { - $attribute.Add("ID", [byte]$attributeID) - $attribute.Add("IDHex", [string]$attributeID.ToString("X")) - $attribute.Add("Name", [string]$actualAttributesList.Where{$_.AttributeID -eq $attributeID}.AttributeName) - $attribute.Add("Threshold", [byte]$thresholdsData[$attributeStart + 1]) - $attribute.Add("Value", [byte]$smartData[$attributeStart + 3]) - $attribute.Add("Worst", [byte]$smartData[$attributeStart + 4]) - $attribute.Add("Data", $(inGetAttributeData -actualAttributesList $actualAttributesList -smartData $smartData -attributeStart $attributeStart)) + $attribute.Add('ID', [byte]$attributeID) + $attribute.Add('IDHex', [string]$attributeID.ToString('X')) + $attribute.Add('Name', [string]$actualAttributesList.Where{$_.AttributeID -eq $attributeID}.AttributeName) + $attribute.Add('Threshold', [byte]$thresholdsData[$attributeStart + 1]) + $attribute.Add('Value', [byte]$smartData[$attributeStart + 3]) + $attribute.Add('Worst', [byte]$smartData[$attributeStart + 4]) + $attribute.Add('Data', $(inGetAttributeData -actualAttributesList $actualAttributesList -smartData $smartData -attributeStart $attributeStart)) $attributes += $attribute } } - $hash.Add("SmartData", $attributes) - $hash.Add("AuxiliaryData", @{BytesPerSector=$diskDrive.BytesPerSector}) + $hash.Add('SmartData', $attributes) + $hash.Add('AuxiliaryData', @{BytesPerSector=$diskDrive.BytesPerSector}) $hostSmartData.DisksSmartData += $hash } @@ -241,7 +241,6 @@ function inGetSourceSmartDataCtl if (Get-Command -Name 'smartctl' -ErrorAction SilentlyContinue) { - $sbs = inGetSmartCtlCommand -Sudo $IsLinux -SmartCtlOptions $SmartCtlOptions $devices = Invoke-Command -ScriptBlock { smartctl --scan } @@ -266,7 +265,7 @@ function inGetSourceSmartDataCtl } else { - $message = "SmartCtl utility is not found." + $message = 'SmartCtl utility is not found.' $exception = [System.Exception]::new($message) $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::NotInstalled, $null) $PSCmdlet.WriteError($errorRecord) @@ -411,38 +410,38 @@ function inGetSmartDataStructureCtl if ($entry -match '^\s*(?\S+)\s+(?\S+)\s+\S+\s+(?\S+)\s+(?\S+)\s+(?\S+)\s+\S+\s+\S+\s+\S+\s+(?\S+.*)$') { - $attribute.Add("ID", [byte]$Matches.id) - $attribute.Add("IDHex", [string]($attribute.ID.ToString("X"))) + $attribute.Add('ID', [byte]$Matches.id) + $attribute.Add('IDHex', [string]($attribute.ID.ToString('X'))) if ($Config.ReplaceSmartCtlAttributeNames) { - $attribute.Add("Name", [string]$actualAttributesList.Where{$_.AttributeID -eq $attribute.ID}.AttributeName) + $attribute.Add('Name', [string]$actualAttributesList.Where{$_.AttributeID -eq $attribute.ID}.AttributeName) } else { - $attribute.Add("Name", [string]$Matches.name) + $attribute.Add('Name', [string]$Matches.name) } - $attribute.Add("Threshold", [byte]$Matches.threshold) - $attribute.Add("Value", [byte]$Matches.value) - $attribute.Add("Worst", [byte]$Matches.worst) + $attribute.Add('Threshold', [byte]$Matches.threshold) + $attribute.Add('Value', [byte]$Matches.value) + $attribute.Add('Worst', [byte]$Matches.worst) $sourcedata = $Matches.data # 32 (Min/Max 18/40) if ($sourcedata -match '^(?\d+) \(Min/Max (?\d+)/(?\d+)\)$') { - $attribute.Add("Data", @([long]$Matches.data, [long]$Matches.min, [long]$Matches.max)) + $attribute.Add('Data', @([long]$Matches.data, [long]$Matches.min, [long]$Matches.max)) } # 10/11 elseif ($sourcedata -match '^(?\d+)/(?\d+)$') { - $attribute.Add("Data", @([long]$Matches.first, [long]$Matches.second)) + $attribute.Add('Data', @([long]$Matches.first, [long]$Matches.second)) } # 1 else { - $attribute.Add("Data", [long]$Matches.data) + $attribute.Add('Data', [long]$Matches.data) } $attributes += $attribute @@ -450,7 +449,7 @@ function inGetSmartDataStructureCtl } } - $hash.Add("SmartData", $attributes) + $hash.Add('SmartData', $attributes) if ($diskSmartData.diskSmartData -match '^Sector sizes?:' | ForEach-Object { $PSItem -match '^Sector sizes?:\s+(?\d+).*$' }) { @@ -460,7 +459,7 @@ function inGetSmartDataStructureCtl { $sectorSize = $null } - $hash.Add("AuxiliaryData", @{BytesPerSector=$sectorSize}) + $hash.Add('AuxiliaryData', @{BytesPerSector=$sectorSize}) } elseif ($hash.DiskType -eq 'NVMe') @@ -479,15 +478,15 @@ function inGetSmartDataStructureCtl if ($entry -match '^\s*(?.+):\s+(?\S+.*)$') { - $attribute.Add("Name", [string]$Matches.name) - $attribute.Add("Data", [string]$Matches.data) + $attribute.Add('Name', [string]$Matches.name) + $attribute.Add('Data', [string]$Matches.data) $attributes += $attribute } } } - $hash.Add("SmartData", $attributes) + $hash.Add('SmartData', $attributes) } $hostSmartData.DisksSmartData += $hash @@ -586,16 +585,16 @@ function inGetDiskSmartInfo if ($ShowHistory) { - $attribute.Add("DataHistory", $(inGetAttributeHistoricalData -diskHistoricalData $diskHistoricalData -attribute $attribute -diskType $diskSmartData.DiskType)) + $attribute.Add('DataHistory', $(inGetAttributeHistoricalData -diskHistoricalData $diskHistoricalData -attribute $attribute -diskType $diskSmartData.DiskType)) } if ($Convert) { - $attribute.Add("DataConverted", $(inConvertData -actualAttributesList $actualAttributesList -attribute $attribute)) + $attribute.Add('DataConverted', $(inConvertData -actualAttributesList $actualAttributesList -attribute $attribute)) } $attributeObject = [PSCustomObject]$attribute - $attributeObject | Add-Member -TypeName "DiskSmartAttribute" + $attributeObject | Add-Member -TypeName 'DiskSmartAttribute' if ($ShowHistory -and $Convert) { @@ -637,11 +636,11 @@ function inGetDiskSmartInfo if ($ShowHistory) { - $attribute.Add("DataHistory", $(inGetAttributeHistoricalData -diskHistoricalData $diskHistoricalData -attribute $attribute -diskType $diskSmartData.DiskType)) + $attribute.Add('DataHistory', $(inGetAttributeHistoricalData -diskHistoricalData $diskHistoricalData -attribute $attribute -diskType $diskSmartData.DiskType)) } $attributeObject = [PSCustomObject]$attribute - $attributeObject | Add-Member -TypeName "DiskSmartAttributeNVMe" + $attributeObject | Add-Member -TypeName 'DiskSmartAttributeNVMe' if ($ShowHistory) { @@ -660,7 +659,7 @@ function inGetDiskSmartInfo { if (-not $AttributeProperties) { - $hash.Add("SmartData", $attributes) + $hash.Add('SmartData', $attributes) Add-Member -InputObject $hash.SmartData -TypeName 'DiskSmartAttribute[]' } else @@ -669,7 +668,7 @@ function inGetDiskSmartInfo $scriptBlockString = '$this | Format-Table -Property ' + $formatProperties $formatScriptBlock = [scriptblock]::Create($scriptBlockString) - $hash.Add("SmartData", (inSelectAttributeProperties -attributes $attributes -properties $AttributeProperties -formatScriptBlock $formatScriptBlock -diskType $diskSmartData.DiskType)) + $hash.Add('SmartData', (inSelectAttributeProperties -attributes $attributes -properties $AttributeProperties -formatScriptBlock $formatScriptBlock -diskType $diskSmartData.DiskType)) Add-Member -InputObject $hash.SmartData -TypeName 'DiskSmartAttributeCustom[]' Add-Member -InputObject $hash.SmartData -MemberType ScriptMethod -Name FormatTable -Value $formatScriptBlock @@ -679,7 +678,7 @@ function inGetDiskSmartInfo { if (-not $AttributeProperties) { - $hash.Add("SmartData", $attributes) + $hash.Add('SmartData', $attributes) Add-Member -InputObject $hash.SmartData -TypeName 'DiskSmartAttributeNVMe[]' } else @@ -688,7 +687,7 @@ function inGetDiskSmartInfo $scriptBlockString = '$this | Format-Table -Property ' + $formatProperties $formatScriptBlock = [scriptblock]::Create($scriptBlockString) - $hash.Add("SmartData", (inSelectAttributeProperties -attributes $attributes -properties $AttributeProperties.Where{$PSItem.ToString() -in 'AttributeName', 'Data', 'History'} -formatScriptBlock $formatScriptBlock -diskType $diskSmartData.DiskType)) + $hash.Add('SmartData', (inSelectAttributeProperties -attributes $attributes -properties $AttributeProperties.Where{$PSItem.ToString() -in 'AttributeName', 'Data', 'History'} -formatScriptBlock $formatScriptBlock -diskType $diskSmartData.DiskType)) Add-Member -InputObject $hash.SmartData -TypeName 'DiskSmartAttributeNVMeCustom[]' Add-Member -InputObject $hash.SmartData -MemberType ScriptMethod -Name FormatTable -Value $formatScriptBlock @@ -697,11 +696,11 @@ function inGetDiskSmartInfo } $diskSmartInfo = [PSCustomObject]$hash - $diskSmartInfo | Add-Member -TypeName "DiskSmartInfo" + $diskSmartInfo | Add-Member -TypeName 'DiskSmartInfo' if ($ShowHistory) { - $diskSmartInfo | Add-Member -TypeName "DiskSmartInfo#History" + $diskSmartInfo | Add-Member -TypeName 'DiskSmartInfo#History' } $diskSmartInfo diff --git a/functions/DiskSmartInfo.functions.ps1 b/functions/DiskSmartInfo.functions.ps1 index 1d4b05e..88c3ad3 100644 --- a/functions/DiskSmartInfo.functions.ps1 +++ b/functions/DiskSmartInfo.functions.ps1 @@ -1,531 +1,531 @@ -function Get-DiskSmartInfo -{ - [CmdletBinding(PositionalBinding=$false,DefaultParameterSetName='ComputerName')] - Param( - [Alias('PSComputerName')] - [Parameter(Position=0,ValueFromPipeline,ValueFromPipelineByPropertyName,ParameterSetName='ComputerName')] - [string[]]$ComputerName, - [Parameter(ParameterSetName='ComputerName')] - [ValidateSet('CimSession','PSSession','SSHSession','SSHClient')] - [string]$Transport, - [Parameter(ValueFromPipeline,ParameterSetName='Session')] - [CimSession[]]$CimSession, - [Parameter(ValueFromPipeline,ParameterSetName='Session')] - [System.Management.Automation.Runspaces.PSSession[]]$PSSession, - [ValidateSet('CIM','SmartCtl')] - [string]$Source, - [switch]$Convert, - [Alias('CriticalAttributesOnly')] - [switch]$Critical, - [Alias('Index','Number','DeviceId')] - [Parameter(ValueFromPipelineByPropertyName)] - [ArgumentCompleter([DiskCompleter])] - [int[]]$DiskNumber, - [Alias('Model')] - [ArgumentCompleter([DiskCompleter])] - [string[]]$DiskModel, - [string[]]$Device, - [ValidateRange(1, 255)] - [int[]]$AttributeID, - [ValidatePattern("^(0?[1-9A-F])|([1-9A-F])([0-9A-F])$")] - [string[]]$AttributeIDHex, - [ArgumentCompleter([AttributeNameCompleter])] - [string[]]$AttributeName, - [AttributeProperty[]]$AttributeProperty, - [switch]$Quiet, - [switch]$ShowHistory, - [switch]$UpdateHistory, - [switch]$Archive, - [Parameter(Position=1,ParameterSetName='ComputerName')] - [pscredential]$Credential, - [string]$SmartCtlOption, - [Parameter(ParameterSetName='ComputerName')] - [switch]$SSHClientSudo, - [Parameter(ParameterSetName='ComputerName')] - [string]$SSHClientOption - ) - - begin - { - # Restrictions - if ($IsMacOS) - { - $message = "Platform is not supported." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::NotImplemented, $null) - $PSCmdlet.ThrowTerminatingError($errorRecord) - } - - if (-not $IsCoreCLR -and $Transport -eq 'SSHSession') - { - $message = "PSSession with SSH transport is not supported in Windows PowerShell 5.1 and earlier." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::NotImplemented, $null) - $PSCmdlet.ThrowTerminatingError($errorRecord) - } - - if (-not $IsLinux) - { - # Get-DiskSmartInfo -Source SmartCtl -CimSession $cs - # Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Source SmartCtl -CimSession $cs - - # Get-DiskSmartInfo -Source SmartCtl -Transport CIMSession - # ComputerName, Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Source SmartCtl -Transport CIMSession - if ($Source -eq 'SmartCtl' -and ($CimSession -or $Transport -eq 'CIMSession')) - { - $message = "CIMSession transport only supports CIM source." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) - $PSCmdlet.ThrowTerminatingError($errorRecord) - } - - # Get-DiskSmartInfo -Source SmartCtl -ComputerName $cn - # Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Source SmartCtl -ComputerName $cn - if ($Source -eq 'SmartCtl' -and -not $Transport -and $ComputerName) - { - $message = "Transport parameter is not specified and its default value is ""CIMSession"". CIMSession transport only supports CIM source." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) - $PSCmdlet.ThrowTerminatingError($errorRecord) - } - - # Get-DiskSmartInfo -Transport SSHClient -Source CIM -ComputerName $cn - # Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Transport SSHClient -Source CIM -ComputerName $cn - if ($Transport -eq 'SSHClient' -and $Source -eq 'CIM' -and $ComputerName) - { - $message = "SSHClient transport does not support CIM source." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) - $PSCmdlet.ThrowTerminatingError($errorRecord) - } - - # Get-DiskSmartInfo -Transport SSHClient -ComputerName $cn - # Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Transport SSHClient -ComputerName $cn - if ($Transport -eq 'SSHClient' -and -not $Source -and $ComputerName) - { - $message = "Source parameter is not specified and its default value is ""CIM"". SSHClient transport does not support CIM source." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) - $PSCmdlet.ThrowTerminatingError($errorRecord) - } - } - - if ($IsLinux) - { - if ($Transport -eq 'CIMSession') - { - $message = "CIMSession transport is not supported on this platform." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) - $PSCmdlet.ThrowTerminatingError($errorRecord) - } - elseif ($Transport -eq 'PSSession') - { - $message = "PSSession transport is not supported on this platform." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) - $PSCmdlet.ThrowTerminatingError($errorRecord) - } - } - - # Notifications - if ($Credential -and -not $ComputerName -and -not $PSCmdlet.MyInvocation.ExpectingInput) - { - Write-Warning -Message "The -Credential parameter is used only for connecting to computers, listed or bound to the -ComputerName parameter." - } - elseif ($Credential -and (($Transport -eq 'SSHSession') -or ($IsLinux -and -not $Transport))) - { - Write-Warning -Message "The -Credential parameter is not used with SSHSession transport." - } - - if ($Credential -and $Transport -eq 'SSHClient') - { - Write-Warning -Message "The -Credential parameter is not used with SSHClient transport." - } - - if ($SSHClientSudo -and $Transport -ne 'SSHClient') - { - Write-Warning -Message "The -SSHClientSudo parameter is only used with SSHClient transport." - } - - if ($SSHClientOption -and $Transport -ne 'SSHClient') - { - Write-Warning -Message "The -SSHClientOption parameter is only used with SSHClient transport." - } - - if ($SmartCtlOption -and ((-not $IsLinux -and $Source -ne 'SmartCtl') -or ($IsLinux -and $Source -eq 'CIM'))) - { - Write-Warning -Message "The -SmartCtlOption parameter is only used with SmartCtl source." - } - - # Defaults - if ($PSCmdlet.ParameterSetName -eq 'ComputerName' -and -not $Transport) - { - if (-not $IsLinux) - { - $Transport = 'CimSession' - } - elseif ($IsLinux) - { - $Transport = 'SSHSession' - } - } - - if (-not $Source) - { - if (-not $IsLinux) - { - $Source = 'CIM' - } - elseif ($IsLinux) - { - $Source = 'SmartCtl' - } - } - - if ($AttributeProperty) - { - $AttributeProperty = $AttributeProperty | Select-Object -Unique - - if ('History' -in $AttributeProperty) - { - $ShowHistory = $true - } - - if ('Converted' -in $AttributeProperty) - { - $Convert = $true - } - } - - $errorParameters = @{ - ErrorVariable = 'sessionErrors' - ErrorAction = 'SilentlyContinue' - } - - $RequestedAttributes = @{AttributeIDs=$AttributeID; AttributeIDHexes=$AttributeIDHex; AttributeNames=$AttributeName} - } - - process - { - if ($PSCmdlet.ParameterSetName -eq 'Session') - { - foreach ($cs in $CimSession) - { - if (-not $IsLinux) - { - if ($Source -eq 'CIM') - { - $SourceSmartDataCIM = inGetSourceSmartDataCIM -CimSession $cs - $HostsSmartData = inGetSmartDataStructureCIM -SourceSmartDataCIM $SourceSmartDataCIM - - inGetDiskSmartInfo ` - -HostsSmartData $HostsSmartData ` - -Convert:$Convert ` - -Critical:$Critical ` - -DiskNumbers $DiskNumber ` - -DiskModels $DiskModel ` - -Devices $Device ` - -RequestedAttributes $RequestedAttributes ` - -AttributeProperties $AttributeProperty ` - -Quiet:$Quiet ` - -ShowHistory:$ShowHistory ` - -UpdateHistory:$UpdateHistory ` - -Archive:$Archive - } - - # CIMSession | Get-DiskSmartInfo -Source SmartCtl - elseif ($Source -eq 'SmartCtl') - { - $message = "ComputerName: ""$($cs.ComputerName)"": CIMSession only supports CIM source." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) - $PSCmdlet.WriteError($errorRecord) - } - } - elseif ($IsLinux) - { - $message = "ComputerName: ""$($cs.ComputerName)"": CIMSession transport is not supported on this platform." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) - $PSCmdlet.WriteError($errorRecord) - } - } - - foreach ($ps in $PSSession) - { - if (-not ($IsLinux -and $ps.Transport -ne 'SSH')) - { - if ($Source -eq 'CIM') - { - $SourceSmartDataCIM = inGetSourceSmartDataCIM -PSSession $ps - $HostsSmartData = inGetSmartDataStructureCIM -SourceSmartDataCIM $SourceSmartDataCIM - } - elseif ($Source -eq 'SmartCtl') - { - $SourceSmartDataCtl = inGetSourceSmartDataCtl -PSSession $ps -SmartCtlOptions $SmartCtlOption - $HostsSmartData = inGetSmartDataStructureCtl -SourceSmartDataCtl $SourceSmartDataCtl - } - - inGetDiskSmartInfo ` - -HostsSmartData $HostsSmartData ` - -Convert:$Convert ` - -Critical:$Critical ` - -DiskNumbers $DiskNumber ` - -DiskModels $DiskModel ` - -Devices $Device ` - -RequestedAttributes $RequestedAttributes ` - -AttributeProperties $AttributeProperty ` - -Quiet:$Quiet ` - -ShowHistory:$ShowHistory ` - -UpdateHistory:$UpdateHistory ` - -Archive:$Archive - } - else - { - $message = "ComputerName: ""$($ps.ComputerName)"": PSSession transport is not supported on this platform." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) - $PSCmdlet.WriteError($errorRecord) - } - } - } - - elseif ($ComputerName) - { - if ($Transport -eq 'CimSession') - { - foreach ($cn in $ComputerName) - { - if ($Source -eq 'CIM') - { - if (-not ($cs = New-CimSession -ComputerName $cn -Credential $Credential @errorParameters)) - { - inReportErrors -Errors $sessionErrors - continue - } - - try - { - $SourceSmartDataCIM = inGetSourceSmartDataCIM -CimSession $cs - $HostsSmartData = inGetSmartDataStructureCIM -SourceSmartDataCIM $SourceSmartDataCIM - - inGetDiskSmartInfo ` - -HostsSmartData $HostsSmartData ` - -Convert:$Convert ` - -Critical:$Critical ` - -DiskNumbers $DiskNumber ` - -DiskModels $DiskModel ` - -Devices $Device ` - -RequestedAttributes $RequestedAttributes ` - -AttributeProperties $AttributeProperty ` - -Quiet:$Quiet ` - -ShowHistory:$ShowHistory ` - -UpdateHistory:$UpdateHistory ` - -Archive:$Archive - } - finally - { - Remove-CimSession -CimSession $cs - } - } - # ComputerName, Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Source SmartCtl - # (Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk are all from remote computers) - elseif ($Source -eq 'SmartCtl') - { - $message = "ComputerName: ""$cn"": Transport parameter is not specified and its default value is ""CIMSession"". CIMSession transport only supports CIM source." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) - $PSCmdlet.WriteError($errorRecord) - } - } - } - elseif ($Transport -eq 'PSSession') - { - foreach ($cn in $ComputerName) - { - # non-existent computer name results in non-terminating error - # computername format error, e.g user@host (for -ComputerName, not -HostName) results in terminating error - # we need to suppress both types of cmdlet error messages and replace them with our own - try - { - if ($Credential) - { - $ps = New-PSSession -ComputerName $cn -Credential $Credential @errorParameters - } - else - { - $ps = New-PSSession -ComputerName $cn @errorParameters - } - } - catch { } - - if (-not $ps) - { - inReportErrors -Errors $sessionErrors - continue - } - - try - { - if ($Source -eq 'CIM') - { - $SourceSmartDataCIM = inGetSourceSmartDataCIM -PSSession $ps - $HostsSmartData = inGetSmartDataStructureCIM -SourceSmartDataCIM $SourceSmartDataCIM - } - elseif ($Source -eq 'SmartCtl') - { - $SourceSmartDataCtl = inGetSourceSmartDataCtl -PSSession $ps -SmartCtlOptions $SmartCtlOption - $HostsSmartData = inGetSmartDataStructureCtl -SourceSmartDataCtl $SourceSmartDataCtl - } - - inGetDiskSmartInfo ` - -HostsSmartData $HostsSmartData ` - -Convert:$Convert ` - -Critical:$Critical ` - -DiskNumbers $DiskNumber ` - -DiskModels $DiskModel ` - -Devices $Device ` - -RequestedAttributes $RequestedAttributes ` - -AttributeProperties $AttributeProperty ` - -Quiet:$Quiet ` - -ShowHistory:$ShowHistory ` - -UpdateHistory:$UpdateHistory ` - -Archive:$Archive - } - finally - { - Remove-PSSession -Session $ps - } - } - } - elseif ($Transport -eq 'SSHSession') - { - foreach ($cn in $ComputerName) - { - if (-not ($ps = New-PSSession -HostName $cn @errorParameters)) - { - inReportErrors -Errors $sessionErrors - continue - } - - try - { - if ($Source -eq 'CIM') - { - $SourceSmartDataCIM = inGetSourceSmartDataCIM -PSSession $ps - $HostsSmartData = inGetSmartDataStructureCIM -SourceSmartDataCIM $SourceSmartDataCIM - } - elseif ($Source -eq 'SmartCtl') - { - $SourceSmartDataCtl = inGetSourceSmartDataCtl -PSSession $ps -SmartCtlOptions $SmartCtlOption - $HostsSmartData = inGetSmartDataStructureCtl -SourceSmartDataCtl $SourceSmartDataCtl - } - - inGetDiskSmartInfo ` - -HostsSmartData $HostsSmartData ` - -Convert:$Convert ` - -Critical:$Critical ` - -DiskNumbers $DiskNumber ` - -DiskModels $DiskModel ` - -Devices $Device ` - -RequestedAttributes $RequestedAttributes ` - -AttributeProperties $AttributeProperty ` - -Quiet:$Quiet ` - -ShowHistory:$ShowHistory ` - -UpdateHistory:$UpdateHistory ` - -Archive:$Archive - } - finally - { - Remove-PSSession -Session $ps - } - } - } - elseif ($Transport -eq 'SSHClient') - { - foreach ($cn in $ComputerName) - { - # ComputerName, Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Transport SSHClient - # ComputerName, Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Transport SSHClient -Source CIM - # (Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk are all from remote computers) - - # Need this check, because for local queries the -Transport parameter is not used and do not throws an error. - # e.g. `Get-DiskSmartInfo -Transport SSHClient` or `Get-DiskSmartInfo -Transport SSHClient -Source` - # This is for conveniency reasons. - if ($Source -eq 'CIM') - { - $message = "ComputerName: ""$cn"": SSHClient transport does not support CIM source." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) - $PSCmdlet.WriteError($errorRecord) - } - elseif ($Source -eq 'SmartCtl') - { - $SourceSmartDataCtl = inGetSourceSmartDataSSHClientCtl -ComputerName $cn -SmartCtlOptions $SmartCtlOption -Sudo $SSHClientSudo -SSHClientOptions $SSHClientOption - $HostsSmartData = inGetSmartDataStructureCtl -SourceSmartDataCtl $SourceSmartDataCtl - } - - inGetDiskSmartInfo ` - -HostsSmartData $HostsSmartData ` - -Convert:$Convert ` - -Critical:$Critical ` - -DiskNumbers $DiskNumber ` - -DiskModels $DiskModel ` - -Devices $Device ` - -RequestedAttributes $RequestedAttributes ` - -AttributeProperties $AttributeProperty ` - -Quiet:$Quiet ` - -ShowHistory:$ShowHistory ` - -UpdateHistory:$UpdateHistory ` - -Archive:$Archive - } - } - } - # Localhost - else - { - if ($Source -eq 'CIM') - { - if (-not $IsLinux) - { - $SourceSmartDataCIM = inGetSourceSmartDataCIM - $HostsSmartData = inGetSmartDataStructureCIM -SourceSmartDataCIM $SourceSmartDataCIM - } - elseif ($IsLinux) - { - $message = "CIM source is not supported on this platform." - $exception = [System.Exception]::new($message) - $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) - $PSCmdlet.WriteError($errorRecord) - } - } - elseif ($Source -eq 'SmartCtl') - { - $SourceSmartDataCtl = inGetSourceSmartDataCtl -SmartCtlOptions $SmartCtlOption - $HostsSmartData = inGetSmartDataStructureCtl -SourceSmartDataCtl $SourceSmartDataCtl - } - - inGetDiskSmartInfo ` - -HostsSmartData $HostsSmartData ` - -Convert:$Convert ` - -Critical:$Critical ` - -DiskNumbers $DiskNumber ` - -DiskModels $DiskModel ` - -Devices $Device ` - -RequestedAttributes $RequestedAttributes ` - -AttributeProperties $AttributeProperty ` - -Quiet:$Quiet ` - -ShowHistory:$ShowHistory ` - -UpdateHistory:$UpdateHistory ` - -Archive:$Archive - } - } - - end - { - # Remove unnecessary System.Management.Automation.Runspaces.RemotingErrorRecord (CIMSession errors) objects - # or errors with exception System.Management.Automation.Remoting.PSRemotingTransportException (PSSession errors) from ErrorVariable - inClearRemotingErrorRecords - } -} +function Get-DiskSmartInfo +{ + [CmdletBinding(PositionalBinding=$false,DefaultParameterSetName='ComputerName')] + Param( + [Alias('PSComputerName')] + [Parameter(Position=0,ValueFromPipeline,ValueFromPipelineByPropertyName,ParameterSetName='ComputerName')] + [string[]]$ComputerName, + [Parameter(ParameterSetName='ComputerName')] + [ValidateSet('CimSession','PSSession','SSHSession','SSHClient')] + [string]$Transport, + [Parameter(ValueFromPipeline,ParameterSetName='Session')] + [CimSession[]]$CimSession, + [Parameter(ValueFromPipeline,ParameterSetName='Session')] + [System.Management.Automation.Runspaces.PSSession[]]$PSSession, + [ValidateSet('CIM','SmartCtl')] + [string]$Source, + [switch]$Convert, + [Alias('CriticalAttributesOnly')] + [switch]$Critical, + [Alias('Index','Number','DeviceId')] + [Parameter(ValueFromPipelineByPropertyName)] + [ArgumentCompleter([DiskCompleter])] + [int[]]$DiskNumber, + [Alias('Model')] + [ArgumentCompleter([DiskCompleter])] + [string[]]$DiskModel, + [string[]]$Device, + [ValidateRange(1, 255)] + [int[]]$AttributeID, + [ValidatePattern('^(0?[1-9A-F])|([1-9A-F])([0-9A-F])$')] + [string[]]$AttributeIDHex, + [ArgumentCompleter([AttributeNameCompleter])] + [string[]]$AttributeName, + [AttributeProperty[]]$AttributeProperty, + [switch]$Quiet, + [switch]$ShowHistory, + [switch]$UpdateHistory, + [switch]$Archive, + [Parameter(Position=1,ParameterSetName='ComputerName')] + [pscredential]$Credential, + [string]$SmartCtlOption, + [Parameter(ParameterSetName='ComputerName')] + [switch]$SSHClientSudo, + [Parameter(ParameterSetName='ComputerName')] + [string]$SSHClientOption + ) + + begin + { + # Restrictions + if ($IsMacOS) + { + $message = 'Platform is not supported.' + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::NotImplemented, $null) + $PSCmdlet.ThrowTerminatingError($errorRecord) + } + + if (-not $IsCoreCLR -and $Transport -eq 'SSHSession') + { + $message = 'PSSession with SSH transport is not supported in Windows PowerShell 5.1 and earlier.' + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::NotImplemented, $null) + $PSCmdlet.ThrowTerminatingError($errorRecord) + } + + if (-not $IsLinux) + { + # Get-DiskSmartInfo -Source SmartCtl -CimSession $cs + # Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Source SmartCtl -CimSession $cs + + # Get-DiskSmartInfo -Source SmartCtl -Transport CIMSession + # ComputerName, Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Source SmartCtl -Transport CIMSession + if ($Source -eq 'SmartCtl' -and ($CimSession -or $Transport -eq 'CIMSession')) + { + $message = 'CIMSession transport only supports CIM source.' + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) + $PSCmdlet.ThrowTerminatingError($errorRecord) + } + + # Get-DiskSmartInfo -Source SmartCtl -ComputerName $cn + # Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Source SmartCtl -ComputerName $cn + if ($Source -eq 'SmartCtl' -and -not $Transport -and $ComputerName) + { + $message = 'Transport parameter is not specified and its default value is "CIMSession". CIMSession transport only supports CIM source.' + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) + $PSCmdlet.ThrowTerminatingError($errorRecord) + } + + # Get-DiskSmartInfo -Transport SSHClient -Source CIM -ComputerName $cn + # Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Transport SSHClient -Source CIM -ComputerName $cn + if ($Transport -eq 'SSHClient' -and $Source -eq 'CIM' -and $ComputerName) + { + $message = 'SSHClient transport does not support CIM source.' + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) + $PSCmdlet.ThrowTerminatingError($errorRecord) + } + + # Get-DiskSmartInfo -Transport SSHClient -ComputerName $cn + # Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Transport SSHClient -ComputerName $cn + if ($Transport -eq 'SSHClient' -and -not $Source -and $ComputerName) + { + $message = 'Source parameter is not specified and its default value is "CIM". SSHClient transport does not support CIM source.' + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) + $PSCmdlet.ThrowTerminatingError($errorRecord) + } + } + + if ($IsLinux) + { + if ($Transport -eq 'CIMSession') + { + $message = 'CIMSession transport is not supported on this platform.' + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) + $PSCmdlet.ThrowTerminatingError($errorRecord) + } + elseif ($Transport -eq 'PSSession') + { + $message = 'PSSession transport is not supported on this platform.' + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) + $PSCmdlet.ThrowTerminatingError($errorRecord) + } + } + + # Notifications + if ($Credential -and -not $ComputerName -and -not $PSCmdlet.MyInvocation.ExpectingInput) + { + Write-Warning -Message 'The -Credential parameter is used only for connecting to computers, listed or bound to the -ComputerName parameter.' + } + elseif ($Credential -and (($Transport -eq 'SSHSession') -or ($IsLinux -and -not $Transport))) + { + Write-Warning -Message 'The -Credential parameter is not used with SSHSession transport.' + } + + if ($Credential -and $Transport -eq 'SSHClient') + { + Write-Warning -Message 'The -Credential parameter is not used with SSHClient transport.' + } + + if ($SSHClientSudo -and $Transport -ne 'SSHClient') + { + Write-Warning -Message 'The -SSHClientSudo parameter is only used with SSHClient transport.' + } + + if ($SSHClientOption -and $Transport -ne 'SSHClient') + { + Write-Warning -Message 'The -SSHClientOption parameter is only used with SSHClient transport.' + } + + if ($SmartCtlOption -and ((-not $IsLinux -and $Source -ne 'SmartCtl') -or ($IsLinux -and $Source -eq 'CIM'))) + { + Write-Warning -Message 'The -SmartCtlOption parameter is only used with SmartCtl source.' + } + + # Defaults + if ($PSCmdlet.ParameterSetName -eq 'ComputerName' -and -not $Transport) + { + if (-not $IsLinux) + { + $Transport = 'CimSession' + } + elseif ($IsLinux) + { + $Transport = 'SSHSession' + } + } + + if (-not $Source) + { + if (-not $IsLinux) + { + $Source = 'CIM' + } + elseif ($IsLinux) + { + $Source = 'SmartCtl' + } + } + + if ($AttributeProperty) + { + $AttributeProperty = $AttributeProperty | Select-Object -Unique + + if ('History' -in $AttributeProperty) + { + $ShowHistory = $true + } + + if ('Converted' -in $AttributeProperty) + { + $Convert = $true + } + } + + $errorParameters = @{ + ErrorVariable = 'sessionErrors' + ErrorAction = 'SilentlyContinue' + } + + $RequestedAttributes = @{AttributeIDs=$AttributeID; AttributeIDHexes=$AttributeIDHex; AttributeNames=$AttributeName} + } + + process + { + if ($PSCmdlet.ParameterSetName -eq 'Session') + { + foreach ($cs in $CimSession) + { + if (-not $IsLinux) + { + if ($Source -eq 'CIM') + { + $SourceSmartDataCIM = inGetSourceSmartDataCIM -CimSession $cs + $HostsSmartData = inGetSmartDataStructureCIM -SourceSmartDataCIM $SourceSmartDataCIM + + inGetDiskSmartInfo ` + -HostsSmartData $HostsSmartData ` + -Convert:$Convert ` + -Critical:$Critical ` + -DiskNumbers $DiskNumber ` + -DiskModels $DiskModel ` + -Devices $Device ` + -RequestedAttributes $RequestedAttributes ` + -AttributeProperties $AttributeProperty ` + -Quiet:$Quiet ` + -ShowHistory:$ShowHistory ` + -UpdateHistory:$UpdateHistory ` + -Archive:$Archive + } + + # CIMSession | Get-DiskSmartInfo -Source SmartCtl + elseif ($Source -eq 'SmartCtl') + { + $message = "ComputerName: ""$($cs.ComputerName)"": CIMSession only supports CIM source." + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) + $PSCmdlet.WriteError($errorRecord) + } + } + elseif ($IsLinux) + { + $message = "ComputerName: ""$($cs.ComputerName)"": CIMSession transport is not supported on this platform." + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) + $PSCmdlet.WriteError($errorRecord) + } + } + + foreach ($ps in $PSSession) + { + if (-not ($IsLinux -and $ps.Transport -ne 'SSH')) + { + if ($Source -eq 'CIM') + { + $SourceSmartDataCIM = inGetSourceSmartDataCIM -PSSession $ps + $HostsSmartData = inGetSmartDataStructureCIM -SourceSmartDataCIM $SourceSmartDataCIM + } + elseif ($Source -eq 'SmartCtl') + { + $SourceSmartDataCtl = inGetSourceSmartDataCtl -PSSession $ps -SmartCtlOptions $SmartCtlOption + $HostsSmartData = inGetSmartDataStructureCtl -SourceSmartDataCtl $SourceSmartDataCtl + } + + inGetDiskSmartInfo ` + -HostsSmartData $HostsSmartData ` + -Convert:$Convert ` + -Critical:$Critical ` + -DiskNumbers $DiskNumber ` + -DiskModels $DiskModel ` + -Devices $Device ` + -RequestedAttributes $RequestedAttributes ` + -AttributeProperties $AttributeProperty ` + -Quiet:$Quiet ` + -ShowHistory:$ShowHistory ` + -UpdateHistory:$UpdateHistory ` + -Archive:$Archive + } + else + { + $message = "ComputerName: ""$($ps.ComputerName)"": PSSession transport is not supported on this platform." + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) + $PSCmdlet.WriteError($errorRecord) + } + } + } + + elseif ($ComputerName) + { + if ($Transport -eq 'CimSession') + { + foreach ($cn in $ComputerName) + { + if ($Source -eq 'CIM') + { + if (-not ($cs = New-CimSession -ComputerName $cn -Credential $Credential @errorParameters)) + { + inReportErrors -Errors $sessionErrors + continue + } + + try + { + $SourceSmartDataCIM = inGetSourceSmartDataCIM -CimSession $cs + $HostsSmartData = inGetSmartDataStructureCIM -SourceSmartDataCIM $SourceSmartDataCIM + + inGetDiskSmartInfo ` + -HostsSmartData $HostsSmartData ` + -Convert:$Convert ` + -Critical:$Critical ` + -DiskNumbers $DiskNumber ` + -DiskModels $DiskModel ` + -Devices $Device ` + -RequestedAttributes $RequestedAttributes ` + -AttributeProperties $AttributeProperty ` + -Quiet:$Quiet ` + -ShowHistory:$ShowHistory ` + -UpdateHistory:$UpdateHistory ` + -Archive:$Archive + } + finally + { + Remove-CimSession -CimSession $cs + } + } + # ComputerName, Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Source SmartCtl + # (Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk are all from remote computers) + elseif ($Source -eq 'SmartCtl') + { + $message = "ComputerName: ""$cn"": Transport parameter is not specified and its default value is ""CIMSession"". CIMSession transport only supports CIM source." + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) + $PSCmdlet.WriteError($errorRecord) + } + } + } + elseif ($Transport -eq 'PSSession') + { + foreach ($cn in $ComputerName) + { + # non-existent computer name results in non-terminating error + # computername format error, e.g user@host (for -ComputerName, not -HostName) results in terminating error + # we need to suppress both types of cmdlet error messages and replace them with our own + try + { + if ($Credential) + { + $ps = New-PSSession -ComputerName $cn -Credential $Credential @errorParameters + } + else + { + $ps = New-PSSession -ComputerName $cn @errorParameters + } + } + catch { } + + if (-not $ps) + { + inReportErrors -Errors $sessionErrors + continue + } + + try + { + if ($Source -eq 'CIM') + { + $SourceSmartDataCIM = inGetSourceSmartDataCIM -PSSession $ps + $HostsSmartData = inGetSmartDataStructureCIM -SourceSmartDataCIM $SourceSmartDataCIM + } + elseif ($Source -eq 'SmartCtl') + { + $SourceSmartDataCtl = inGetSourceSmartDataCtl -PSSession $ps -SmartCtlOptions $SmartCtlOption + $HostsSmartData = inGetSmartDataStructureCtl -SourceSmartDataCtl $SourceSmartDataCtl + } + + inGetDiskSmartInfo ` + -HostsSmartData $HostsSmartData ` + -Convert:$Convert ` + -Critical:$Critical ` + -DiskNumbers $DiskNumber ` + -DiskModels $DiskModel ` + -Devices $Device ` + -RequestedAttributes $RequestedAttributes ` + -AttributeProperties $AttributeProperty ` + -Quiet:$Quiet ` + -ShowHistory:$ShowHistory ` + -UpdateHistory:$UpdateHistory ` + -Archive:$Archive + } + finally + { + Remove-PSSession -Session $ps + } + } + } + elseif ($Transport -eq 'SSHSession') + { + foreach ($cn in $ComputerName) + { + if (-not ($ps = New-PSSession -HostName $cn @errorParameters)) + { + inReportErrors -Errors $sessionErrors + continue + } + + try + { + if ($Source -eq 'CIM') + { + $SourceSmartDataCIM = inGetSourceSmartDataCIM -PSSession $ps + $HostsSmartData = inGetSmartDataStructureCIM -SourceSmartDataCIM $SourceSmartDataCIM + } + elseif ($Source -eq 'SmartCtl') + { + $SourceSmartDataCtl = inGetSourceSmartDataCtl -PSSession $ps -SmartCtlOptions $SmartCtlOption + $HostsSmartData = inGetSmartDataStructureCtl -SourceSmartDataCtl $SourceSmartDataCtl + } + + inGetDiskSmartInfo ` + -HostsSmartData $HostsSmartData ` + -Convert:$Convert ` + -Critical:$Critical ` + -DiskNumbers $DiskNumber ` + -DiskModels $DiskModel ` + -Devices $Device ` + -RequestedAttributes $RequestedAttributes ` + -AttributeProperties $AttributeProperty ` + -Quiet:$Quiet ` + -ShowHistory:$ShowHistory ` + -UpdateHistory:$UpdateHistory ` + -Archive:$Archive + } + finally + { + Remove-PSSession -Session $ps + } + } + } + elseif ($Transport -eq 'SSHClient') + { + foreach ($cn in $ComputerName) + { + # ComputerName, Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Transport SSHClient + # ComputerName, Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk | Get-DiskSmartInfo -Transport SSHClient -Source CIM + # (Win32_DiskDrive, MSFT_Disk, MSFT_PhysicalDisk are all from remote computers) + + # Need this check, because for local queries the -Transport parameter is not used and do not throws an error. + # e.g. `Get-DiskSmartInfo -Transport SSHClient` or `Get-DiskSmartInfo -Transport SSHClient -Source` + # This is for conveniency reasons. + if ($Source -eq 'CIM') + { + $message = "ComputerName: ""$cn"": SSHClient transport does not support CIM source." + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) + $PSCmdlet.WriteError($errorRecord) + } + elseif ($Source -eq 'SmartCtl') + { + $SourceSmartDataCtl = inGetSourceSmartDataSSHClientCtl -ComputerName $cn -SmartCtlOptions $SmartCtlOption -Sudo $SSHClientSudo -SSHClientOptions $SSHClientOption + $HostsSmartData = inGetSmartDataStructureCtl -SourceSmartDataCtl $SourceSmartDataCtl + } + + inGetDiskSmartInfo ` + -HostsSmartData $HostsSmartData ` + -Convert:$Convert ` + -Critical:$Critical ` + -DiskNumbers $DiskNumber ` + -DiskModels $DiskModel ` + -Devices $Device ` + -RequestedAttributes $RequestedAttributes ` + -AttributeProperties $AttributeProperty ` + -Quiet:$Quiet ` + -ShowHistory:$ShowHistory ` + -UpdateHistory:$UpdateHistory ` + -Archive:$Archive + } + } + } + # Localhost + else + { + if ($Source -eq 'CIM') + { + if (-not $IsLinux) + { + $SourceSmartDataCIM = inGetSourceSmartDataCIM + $HostsSmartData = inGetSmartDataStructureCIM -SourceSmartDataCIM $SourceSmartDataCIM + } + elseif ($IsLinux) + { + $message = 'CIM source is not supported on this platform.' + $exception = [System.Exception]::new($message) + $errorRecord = [System.Management.Automation.ErrorRecord]::new($exception, $message, [System.Management.Automation.ErrorCategory]::InvalidArgument, $null) + $PSCmdlet.WriteError($errorRecord) + } + } + elseif ($Source -eq 'SmartCtl') + { + $SourceSmartDataCtl = inGetSourceSmartDataCtl -SmartCtlOptions $SmartCtlOption + $HostsSmartData = inGetSmartDataStructureCtl -SourceSmartDataCtl $SourceSmartDataCtl + } + + inGetDiskSmartInfo ` + -HostsSmartData $HostsSmartData ` + -Convert:$Convert ` + -Critical:$Critical ` + -DiskNumbers $DiskNumber ` + -DiskModels $DiskModel ` + -Devices $Device ` + -RequestedAttributes $RequestedAttributes ` + -AttributeProperties $AttributeProperty ` + -Quiet:$Quiet ` + -ShowHistory:$ShowHistory ` + -UpdateHistory:$UpdateHistory ` + -Archive:$Archive + } + } + + end + { + # Remove unnecessary System.Management.Automation.Runspaces.RemotingErrorRecord (CIMSession errors) objects + # or errors with exception System.Management.Automation.Remoting.PSRemotingTransportException (PSSession errors) from ErrorVariable + inClearRemotingErrorRecords + } +} diff --git a/functions/DiskSmartInfo.functions.utility.ps1 b/functions/DiskSmartInfo.functions.utility.ps1 index e12a3c5..28ec9b7 100644 --- a/functions/DiskSmartInfo.functions.utility.ps1 +++ b/functions/DiskSmartInfo.functions.utility.ps1 @@ -42,11 +42,11 @@ function inSelectAttributeProperties if ($diskType -eq 'ATA') { - $attributeObject | Add-Member -TypeName "DiskSmartAttributeCustom" + $attributeObject | Add-Member -TypeName 'DiskSmartAttributeCustom' } elseif ($diskType -eq 'NVMe') { - $attributeObject | Add-Member -TypeName "DiskSmartAttributeNVMeCustom" + $attributeObject | Add-Member -TypeName 'DiskSmartAttributeNVMeCustom' } $attributeObject | Add-Member -MemberType ScriptMethod -Name FormatTable -Value $formatScriptBlock From c848e305736e03a4bc90a8d9ee3928d977bca347 Mon Sep 17 00:00:00 2001 From: sethvs Date: Thu, 19 Feb 2026 20:24:31 +0300 Subject: [PATCH 4/4] Update version --- DiskSmartInfo.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DiskSmartInfo.psd1 b/DiskSmartInfo.psd1 index 0288c58..95e10b7 100644 --- a/DiskSmartInfo.psd1 +++ b/DiskSmartInfo.psd1 @@ -4,7 +4,7 @@ RootModule = 'DiskSmartInfo.psm1' # Version number of this module. -ModuleVersion = '3.0' +ModuleVersion = '3.0.1' # Supported PSEditions CompatiblePSEditions = @('Core', 'Desktop')