0

I'm looking for a command in Windows (either cmd or powershell) which will allow me to get which exact type of bus interface my storage device have, not only the type, but also the revision (SATA3, SATA4, NVME2.0 and so on).

For example:

> wmic diskdrive get InterfaceRevision
InterfaceRevision
SATA3
SATA4
NVME2.0
Guy Markman
  • 426
  • 1
  • 4
  • 14
  • 2
    AFAIK, there is no `InterfaceRevision` property in any WMI namespace (windows 10, .NET Framework 4.5.1). Try https://github.com/vinaypamnani/wmie2 – JosefZ Oct 29 '22 at 19:06
  • @JosefZ It doesn't have to be in WMI, it can be any other way. Do you have if there is any equivalent of wmie2 for python? – Guy Markman Oct 29 '22 at 19:18
  • You can run wmic from powershell. You can send output to clipboard and then use Get-ClipBoard in powershell. See : https://learn.microsoft.com/en-us/windows/win32/wmisdk/wmic – jdweng Oct 29 '22 at 21:32
  • @jdweng Yes, but sadly wmic doesn't have any method to find which interface type and revision the disk have – Guy Markman Oct 29 '22 at 22:20
  • It is in the registry and can be obtained device manager : https://www.crucial.com/support/articles-faq-ssd/find-firmware-revision-windows. You can get info from ManagementObject in c# using following : https://stackoverflow.com/questions/2333149/how-to-fast-get-hardware-id-in-c. The c# code can be easily converted to powershell commands. If you need to figure out how to do something in Powershell you can always look at the c# code and translate. – jdweng Oct 29 '22 at 23:19

1 Answers1

2

This will get you the bus but not the version.


Function Get-MaxLength {

<#
.SYNOPSIS
   Finds the length of the longest item in collection.

.DESCRIPTION
   Use this Function to get the length of the longest item in a
   collection for use in format strings or other places where
   needed.

.PARAMETER TestObj
    The qualified object to be tested. See example!

.Parameter MinLen
    The minimum length of the item (if using for formatting) which
    should be the Label (title) length. Note if the object item
    being tested does not have a Length property you MUST specify
    the label length!

.OUTPUTS
    Returns a numerical value

.EXAMPLE
   $NameLen = Get-MaxLength -TestObj $DotNet.PSChildName
   $VerLen  = Get-MaxLength -TestObj $DotNet.Version
   $RNLen   = Get-MaxLength -TestObj $DotNet.Release -MinLen 11

     #--- .Net Information ---

 $fmtDotNet =
  @{Expression={$_.PSChildName};Label=".Net Type";Width=$NameLen},
  @{Expression={$_.Version};Label="Version No:";Width=$VerLen},
  @{Expression={$_.Release};Label="Release No:";Width=$RNLen}

  $Dotnet | Format-Table $fmtDotNet
#>

  Param(
    [Parameter(Mandatory=$True)]
     [object] $TestObj,
    [Parameter(Mandatory=$False)]
     [int] $MinLen = 0,
    [Parameter(Mandatory=$False)]
     [int] $MaxLen = 0
  )

   $ErrorActionPreference = "SilentlyContinue"

   foreach ($x in $TestObj) {
     If ($x.Trim().length -gt $MinLen) {
       $MinLen = $x.Trim().length
     }
   }

   If ($MaxLen -ne 0) {
     If ($MinLen -gt $MaxLen) {
       $MinLen = $MaxLen
     }
   }

   $ErrorActionPreference = "Continue"

   Return ,$MinLen

} #End Function -----------  Get-MaxLength  -------------------

Function PhysicalDiskTab {

  #Physical Drive Info

  $PhyDiskInfo = Get-Disk  | Where-Object {$_.size -gt 0 } |
                 Sort-Object -Property DiskNumber

  $SSD = $False

  $AMArgs = @{Type  = 'NoteProperty'
              Name  = 'SSD'
              Value = 'No'}
  $PhyDiskInfo | Add-Member @AMArgs

  $AMArgs = @{Type  = 'NoteProperty'
              Name  = 'Speed'
              Value = '0'}
  $PhyDiskInfo | Add-Member @AMArgs

  $GCIArgs = @{
     NameSpace    = "root\Microsoft\Windows\Storage"
     Class        = "MSFT_PhysicalDisk"
     ErrorAction  = "SilentlyContinue"
  }
  $RotateSpeed = Get-CimInstance @GCIArgs |
    Select-Object -Property  DeviceID,@{Name="Speed/RPMs";
      Expression={(&{If($_.MediaType -eq 0) {[Int]0}
            Else {$_.SpindleSpeed/600000 -f "#,###"}})}} |
      Sort-Object DeviceID

ForEach ($x in $phydiskinfo) {

  ForEach ($Device in $RotateSpeed) {
      If ($x.number -eq $Device.DeviceID) {
        If ($Device.'Speed/RPMs' -eq 0) {
            $SSD   = $True
          $x.SSD = "Yes"
        }  #End If
        Else {
         $x.Speed = $([Int]$Device.'SPeed/RPMs') -f "#,###"
        }
      }  #End If ($x.number...
  }      #End ForEach ($Device

} #End ForEach $x

$DNLen =
  Get-MaxLength -TestObj $PhyDiskInfo.Model        -MinLen 4
$SNLen =
  Get-MaxLength -TestObj $PhyDiskInfo.SerialNumber -MinLen 13

$fmtPhyDisk1 =
   @{Expression={ '{0:N0}' -f $_.Number};
       Label="Drive`n No.";Width=5;Align='Center'},
   @{Expression={$_.Model};Label="`nName";Width=$DNLen},
   @{Expression={$_.SSD};Label="`nSSD";Width=3;Align='left'},
   @{Expression={ '{0:#,000.00}' -f ($_.Size/1gb)};
       Label="Disk Size`n / GB";Width=9;align='right'},
   @{Expression={$_.NumberOfPartitions};
       Label="Parti`ntions";Width=5},
   @{Expression={$_.PartitionStyle};Label="GPT`nMBR";Width=3},
   @{Expression={(&{If ($_.IsBoot) {"Yes"} else {""}})};
       Label="`nBoot";Width=5;Align="Left"},
   @{Expression={(&{If ($_.BusType.GetType().Name -eq 'UInt16'){
       (& {Switch ($_.BusType) {
            0 {"Unknown"}
            1 {"SCSI"}
            2 {"ATAPI"}
            3 {"ATA"}
            4 {"1394"}
            5 {"SSA"}
            6 {"Fibre Channel"}
            7 {"USB"}
            8 {"RAID"}
            9 {"iSCSI"}
           10 {"SAS"}
           11 {"SATA"}
           12 {"SD"}
           13 {"MMC"}
           14 {"MAX"}
           15 {"File Backed Virtual"}
           16 {"Storage Spaces"}
           17 {"NVMe"}
           18 {"MS Reserved"}
           Default {"Unknown"}}})}
         Else{$_.BusType}})};Label="`nData Bus";Width=20}

  $fmtPhyDisk2 =
     @{Expression={ '{0:N0}' -f $_.Number};
         Label="Drive`n No.";Width=5;Align='Center'},
     @{Expression={$_.Model};Label="`nName";Width=$DNLen},
     @{Expression={$_.SerialNumber.Trim()};
         Label="`nSerial Number";Width=$SNLen;Align='left'},
     @{Expression={
        (&{If ($_.HealthStatus.GetType().Name -eq 'UInt16'){
         (& {Switch ($_.HealthStatus) {
              0      {"Healthy"}
              1      {"Warning"}
              2      {"Unhealthy"}
             Default {"Unknown"}}})}
           Else{$_.HealthStatus}})};Label="`nStatus";Width=7},
     @{Expression={$_.Speed};
         Label="Rotation`n  RPMs  ";Width=8;Align='Right'}

  $PhyDiskInfo1 = $PhyDiskInfo |
           Format-Table -Property $fmtPhyDisk1 -Wrap |
           Out-String   -Width $OStrWidth

  $PhyDiskInfo2 = $PhyDiskInfo |
           Format-Table -Property $fmtPhyDisk2 -Wrap |
           Out-String   -Width $OStrWidth

  $PhyDiskTitle  = "Physical Disk Information:" | Out-String

  Return ,$($PhyDiskTitle  + $PhyDiskInfo1 + $PhyDiskInfo2)

} #End Function ---------------- PhysicalDiskTab --------------

$OStrWidth = 79
PhysicalDiskTab

Output:

Physical Disk Information:

Drive                               Disk Size Parti GPT                        
 No.  Name                      SSD      / GB tions MBR Boot  Data Bus         
----- -----                     --- --------- ----- --- ----- ---------        
  0   Samsung SSD 960           Yes    232.89     4 GPT Yes   NVMe             
  1   Samsung SSD 850 PRO 256GB Yes    238.47     2 GPT       SATA             
  2   Samsung SSD 850 PRO 256GB Yes    238.47     1 GPT       SATA             



Drive                                                        Rotation
 No.  Name                      Serial Number        Status    RPMs  
----- -----                     --------------       ------- --------
  0   Samsung SSD 960           0025_3853_81B0_B2EB. Healthy        0
  1   Samsung SSD 850 PRO 256GB S39KNX0J687882W      Healthy        0
  2   Samsung SSD 850 PRO 256GB S39KNX0J688151N      Healthy        0

This code was pulled from my CMsLocalPCInfoW10 program which can be downloaded from my shared OneDrive library.

RetiredGeek
  • 2,980
  • 1
  • 7
  • 21
  • Hi, thank you very much for it. While I do sadly need the bus version, I would use many parts of it for my code. Thank you very much – Guy Markman Oct 30 '22 at 11:18