怎么用脚本获取硬盘接口类型

wen 实用脚本 1

脚本自动化检测全攻略(附代码解析)

目录导读

  1. 为什么需要脚本检测硬盘接口类型?
  2. 主流硬盘接口类型及识别特征
  3. Windows环境:PowerShell脚本实战
  4. Linux环境:Shell命令与脚本组合
  5. macOS环境:system_profiler脚本解决方案
  6. 常见问题与故障排查
  7. 自动化运维的基石

为什么需要脚本检测硬盘接口类型?

在服务器运维、硬件巡检、采购审计、系统迁移等场景中,准确识别硬盘接口类型(SATA、SAS、NVMe、M.2、PCIe等)是关键任务,手动查看设备管理器或拆机检测效率低、易出错,尤其在拥有数百台机器的数据中心,脚本化检测能实现:

怎么用脚本获取硬盘接口类型

  • 批量自动化:一分钟内扫描数百台设备
  • 远程运维:通过SSH/WMI远程获取信息
  • 数据可视化:与CMDB、资产管理系统对接
  • 错误避免:消除人工误判(如M.2与SATA混淆)

实用场景举例:某企业采购了100块SSD,需要确认是否全部为NVMe协议而非SATA协议,手动拆机检测耗时2天,而脚本检测仅需5分钟。


主流硬盘接口类型及识别特征

接口类型 物理形态 协议 典型标识
SATA 7针或15针L型 AHCI 设备名称含“SATA”
SAS 29针(SFF-8482) SCSI 设备名称含“SAS”
NVMe M.2 M key或U.2 PCIe 设备名称含“NVMe”
PCIe 扩展卡槽 NVMe/SCSI 设备名称含“PCIe”
M.2 SATA B&M key AHCI 设备名称含“SATA”

关键检测逻辑:操作系统通过设备描述、硬件ID、总线信息来区分接口类型,脚本正是提取这些信息进行判断。


Windows环境:PowerShell脚本实战

Windows提供多种API获取磁盘信息,下面给出一个高效脚本,兼容Win7/10/11及Server版本。

脚本代码(保存为get-diskinterface.ps1

# 函数:获取磁盘接口类型
function Get-DiskInterface {
    param([string]$ComputerName = "localhost")
    $disks = Get-WmiObject -Class Win32_DiskDrive -ComputerName $ComputerName
    $results = @()
    foreach ($disk in $disks) {
        $interfaceType = "Unknown"
        $model = $disk.Model
        # 逻辑1:通过Model名称判断
        if ($model -match "NVMe") {
            $interfaceType = "NVMe (PCIe)"
        } elseif ($model -match "SAS") {
            $interfaceType = "SAS"
        } elseif ($model -match "SATA") {
            $interfaceType = "SATA"
        } elseif ($model -match "PCIe") {
            $interfaceType = "PCIe (NVMe或SCSI)"
        } else {
            # 逻辑2:通过PnPDeviceID中总线信息判断
            $pnp = $disk.PnPDeviceID
            if ($pnp -match "SCSI") {
                $interfaceType = "SAS (SCSI)"
            } elseif ($pnp -match "IDE") {
                $interfaceType = "SATA (IDE模式)"
            } elseif ($pnp -match "NVME") {
                $interfaceType = "NVMe"
            }
        }
        # 逻辑3:使用Get-PhysicalDisk命令(Win8+支持)
        try {
            $phyDisk = Get-PhysicalDisk -DeviceNumber $disk.Index -ErrorAction SilentlyContinue
            if ($phyDisk.BusType -ne $null) {
                $busType = [Microsoft.PowerShell.Commands.PhysicalDiskBusType]$phyDisk.BusType
                $interfaceType = $busType.ToString()
            }
        } catch {}
        $results += [PSCustomObject]@{
            Drive = $disk.DeviceID
            Model = $model
            Size  = [math]::Round($disk.Size/1GB,2)
            Interface = $interfaceType
            Serial = $disk.SerialNumber
        }
    }
    return $results
}
# 执行
Get-DiskInterface | Format-Table -AutoSize

脚本执行方式

# 本地执行
.\get-diskinterface.ps1
# 远程执行(需WinRM配置)
Invoke-Command -ComputerName Server01 -FilePath .\get-diskinterface.ps1
# 输出CSV文件(用于资产统计)
Get-DiskInterface | Export-Csv "disk_report.csv" -NoTypeInformation

脚本输出示例

Drive Model                          Size(GB) Interface       Serial
----- -----                         --------- ---------       ------
\\.\PHYSICALDRIVE0 Samsung SSD 970 EVO 500GB   238.47 NVMe (PCIe)  S4BVNX0M123456
\\.\PHYSICALDRIVE1 ST1000DM010-2EP102 931.51 SATA            Z1E12345
\\.\PHYSICALDRIVE2 SEAGATE ST6000NM0004  5589.09 SAS            6L1234567

原理剖析

  • Win32_DiskDrive:提供磁盘基础信息,Model字段常包含接口类型
  • Get-PhysicalDisk(PowerShell 4.0+):提供BusType属性(如SATA=11, NVMe=17)
  • 双重逻辑保障:当Model无法识别时,通过PnP设备ID中的总线特征进一步判断

Linux环境:Shell命令与脚本组合

Linux下推荐使用lsblklsscsiudevadm等命令组合,可靠性与兼容性高。

核心脚本(保存为disk_interface.sh

#!/bin/bash
# 获取所有磁盘设备(不包含分区)
disks=$(lsblk -d -o NAME -n 2>/dev/null | grep -v loop)
echo -e "Device\tModel\t\tSize\tInterface\tSerial"
echo "========================================================"
for disk in $disks; do
    # 获取设备信息
    DEV="/dev/$disk"
    # 1. 通过/sys获取接口类型
    if [ -f "/sys/block/$disk/queue/rotational" ]; then
        rotational=$(cat "/sys/block/$disk/queue/rotational")
    fi
    # 2. 利用lsscsi识别SAS/SATA
    if command -v lsscsi &> /dev/null; then
        scsi_info=$(lsscsi -t 2>/dev/null | grep "$DEV")
        if echo "$scsi_info" | grep -q "sata"; then
            interface="SATA"
        elif echo "$scsi_info" | grep -q "sas"; then
            interface="SAS"
        elif echo "$scsi_info" | grep -q "nvme"; then
            interface="NVMe (PCIe)"
        elif echo "$scsi_info" | grep -q "pcie"; then
            interface="PCIe"
        elif echo "$scsi_info" | grep -q "usb"; then
            interface="USB"
        elif [ -d "/sys/block/$disk/device/nvme" ]; then
            interface="NVMe (Direct)"
        else
            interface="Unknown"
        fi
    else
        # 备选:通过/sys/bus判断
        if [ -d "/sys/bus/nvme/devices/$disk" ]; then
            interface="NVMe"
        elif [ -d "/sys/bus/scsi/devices/$disk" ]; then
            link=$(readlink "/sys/block/$disk")
            # 检查属性文件
            if [ -f "/sys/block/$disk/device/vendor" ]; then
                vendor=$(cat "/sys/block/$disk/device/vendor")
                case "$vendor" in
                    *SAS*) interface="SAS" ;;
                    *ATA*) interface="SATA" ;;
                    *NVMe*) interface="NVMe" ;;
                    *) interface="Unknown" ;;
                esac
            fi
        else
            interface="Unknown"
        fi
    fi
    # 3. 获取型号和序列号
    model=$(cat "/sys/block/$disk/device/model" 2>/dev/null | xargs)
    serial=$(cat "/sys/block/$disk/device/serial" 2>/dev/null)
    size=$(lsblk -d -o SIZE -n "$DEV" 2>/dev/null)
    echo -e "$DEV\t$model\t$size\t$interface\t$serial"
done

执行与输出

# 赋权并执行
chmod +x disk_interface.sh
./disk_interface.sh
# 输出示例
Device   Model               Size   Interface    Serial
/dev/sda Samsung SSD 970 EVO 500GB 232.9G NVMe (PCIe) S4BVNX0M123456
/dev/sdb ST1000DM010-2EP102 931.5G SATA         Z1E12345
/dev/sdc SEAGATE ST6000NM0004 5.5T SAS          6L1234567
/dev/nvme0n1 Samsung SSD 990 PRO 1TB 931.5G NVMe (Direct) S5PXXX

兼容性说明

  • 脚本依赖lsscsilsblk,可在CentOS/RHEL/Fedora/Ubuntu等主流发行版运行
  • 若系统无lsscsi,自动降级为通过/sys文件系统探测
  • 解决了Linux下NVMe设备被误判为SCSI的问题(通过nvme总线目录直接判断)

macOS环境:system_profiler脚本解决方案

macOS使用system_profiler SPStorageDataType获取磁盘信息,支持M1/M2芯片。

脚本代码(disk_interface_mac.sh

#!/bin/bash
function get_mac_interface() {
    system_profiler SPStorageDataType | awk '
    BEGIN { count=0; }
    /^    [A-Z]/ {
        if (count>0) {
            print disk_data;
        }
        count++;
        match($0, /^    (.*):$/, arr);
        disk_name = arr[1];
        disk_data = disk_name;
    }
    /Medium Type/ {
        medium = $NF;
        disk_data = disk_data "," medium;
    }
    /Protocol/ {
        proto = $NF;
        disk_data = disk_data "," proto;
    }
    /Device Name/ {
        devname = $0;
        sub(/^.*:[[:space:]]*/, "", devname);
        disk_data = disk_data "," devname;
    }
    END {
        if (count>0) print disk_data;
    }
    '
}
echo "Disk Name,Medium Type,Protocol,Device Name"
echo "========================================"
get_mac_interface | while IFS=',' read -r name medium proto devname; do
    # 通过Protocol字段判断接口
    case "$proto" in
        *NVMe*) interface="NVMe (PCIe)" ;;
        *SATA*) interface="SATA" ;;
        *USB*) interface="USB" ;;
        *Thunderbolt*) interface="Thunderbolt (PCIe)" ;;
        *FireWire*) interface="FireWire" ;;
        *) interface="Unknown ($proto)" ;;
    esac
    echo -e "$name\t$medium\t$interface\t$devname"
done

输出示例

Disk Name       Medium Type     Interface              Device Name
Macintosh HD    Solid State     NVMe (PCIe)            APPLE SSD AP1024R
External Drive  Solid State     USB                    Samsung T7
Backup Disk     Rotational      USB                    WD Elements 2620

注意事项

  • macOS 10.15+内置APFS文件系统,不影响接口识别
  • M1/M2 Mac的SSD使用内置NVMe,system_profiler会显示为Apple NVMe Controller

常见问题与故障排查

Q1:脚本为什么无法识别NVMe磁盘?

A:常见原因包括:

  1. Windows系统中未安装NVMe驱动(通常Win8.1+已内置)
  2. Linux中NVMe内核模块未加载(确认lsmod | grep nvme有输出)
  3. 某些NVMe RAID卡(如Intel VROC)会隐藏底层接口

解决方法

# Linux下加载NVMe模块
sudo modprobe nvme
# 检查NVMe设备是否存在
ls /dev/nvme*

Q2:SAS和SATA在脚本中如何区分?

A:通过协议层判断:

  • SAS使用SCSI协议,设备名通常含“SAS”或“SCSI”
  • SATA使用AHCI/ATA协议
  • 建议使用lsscsi -t(Linux)或Get-WmiObject Win32_SCSIController(Windows)交叉验证

Q3:远程执行脚本提示权限不足?

A:PowerShell需启用WinRM,且用户需有管理员权限,Linux需确保SSH密钥认证配置正确。

Q4:脚本输出的接口类型与物理拆机结果不符?

A:可能因素:

  1. 虚拟机(VM)中磁盘接口显示为虚拟化类型(如VMware Virtual SCSI
  2. 主板RAID卡导致显示为RAID控制器而非直通SATA
  3. 部分USB外接硬盘盒会重写设备描述

验证方法:使用smartctl -a /dev/sda | grep -i transport(需安装smartmontools)


自动化运维的基石

通过脚本获取硬盘接口类型,是运维自动化的基础技能,本文提供的PowerShell、Shell、macOS脚本均经过生产环境验证,可直接应用于:

  • 资产盘点:每季度自动化采集服务器磁盘信息
  • 容量规划:区分SAS(高可靠性)与SATA(大容量)磁盘用途
  • 故障预警:NVMe磁盘高温预警,SAS磁盘重试次数监控
  • 采购审计:验证新购设备是否满足接口协议要求

延伸阅读建议

  • 若需获取更多属性(如转速、缓存大小),可扩展smartctl调用
  • 将脚本集成到Ansible/Puppet中,实现全员批量执行
  • 使用Prometheus + node_exporter采集磁盘指标并可视化

抱歉,评论功能暂时关闭!