Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Add Friendly Name, Opeational Status and Health Status for Virtual Disks to Invoke-IcingaCheckDiskHealth #390

Open
audiocoach opened this issue Feb 26, 2024 · 2 comments

Comments

@audiocoach
Copy link

For windows storage spaces virtual disks the performance part (avg. disk queue length, avg. disk queue length) of the Invoke-IcingaCheckDiskHealth is already working. It would be great to also include at least Friendly Name, Operational Status and Health Status.

@audiocoach
Copy link
Author

audiocoach commented Mar 29, 2024

Possible solution.

1. Modify Get-IcingaPhysicalDiskInfo.psm1

Add the following below Line 34

    $StorageSpacesDisks   = Get-IcingaWindowsInformation Win32_DiskDrive | Where-Object { $_.Model -eq "Microsoft Storage Space Device" }

Add the following below Line 289 bute above Line 291

        foreach ($disk in $StorageSpacesDisks) {
        [int]$DiskId   = $disk.DeviceId.ToString().Replace('\\.\PHYSICALDRIVE', '');
        [string]$DiskIdString   = $disk.DeviceId.ToString().Replace('\\.\PHYSICALDRIVE', '');

        if ($DiskIds.Count -ne 0) {
            if (-Not ($DiskIds -Contains $DiskId)) {
                continue;
            }
        }

        $AdditionalDiskData1 = Get-Disk -SerialNumber $disk.SerialNumber
        $AdditionalDiskData2 = Get-IcingaWindowsInformation MSFT_VirtualDisk -Namespace 'root\Microsoft\Windows\Storage' | Where-Object { $_.UniqueID -eq $AdditionalDiskData1.UniqueID }
        $Partitions = Get-CimAssociatedInstance -InputObject $disk -ResultClass Win32_DiskPartition;
        $DiskInfo = @{
            'AdapterSerialNumber'         = $AdditionalDiskData1.AdapterSerialNumber
            'Availability'                = $disk.Availability;
            'BytesPerSector'              = $disk.BytesPerSector;
            'Capabilities'                = $disk.Capabilities;
            'CapabilityDescriptions'      = $disk.CapabilityDescriptions;
            'Caption'                     = $disk.Caption;
            'CompressionMethod'           = $disk.CompressionMethod;
            'ConfigManagerErrorCode'      = $disk.ConfigManagerErrorCode;
            'ConfigManagerUserConfig'     = $disk.ConfigManagerUserConfig;
            'CreationClassName'           = $disk.CreationClassName;
            'DefaultBlockSize'            = $disk.DefaultBlockSize;
            'Description'                 = $disk.Description;
            'DeviceID'                    = $disk.DeviceID;
            'DriveReference'              = @{ }; # Set later on partition check
            'ErrorCleared'                = $disk.ErrorCleared;
            'ErrorDescription'            = $disk.ErrorDescription;
            'ErrorMethodology'            = $disk.ErrorMethodology;
            'FirmwareRevision'            = $disk.FirmwareRevision;
            'FriendlyName'                = $AdditionalDiskData1.FriendlyName;
            'Index'                       = $disk.Index;
            'InstallDate'                 = $disk.InstallDate;
            'InterfaceType'               = $disk.InterfaceType;
            'IsBoot'                      = $AdditionalDiskData1.IsBoot
            'IsClustered'                 = $AdditionalDiskData1.IsClustered;
            'IsHighlyAvailable'           = $disk.IsHighlyAvailable;
            'IsOffline'                   = $AdditionalDiskData1.IsOffline;
            'IsReadOnly'                  = $AdditionalDiskData1.IsReadOnly;
            'IsScaleOut'                  = $AdditionalDiskData1.isScaleOut;
            'IsSystem'                    = $AdditionalDiskData1.IsSystem;
            'LastErrorCode'               = $disk.LastErrorCode;
            'Manufacturer'                = $AdditionalDiskData1.Manufacturer;
            'MaxBlockSize'                = 0; # 0 because we later count the block size based on the amount of partitions
            'MaxMediaSize'                = $disk.MaxMediaSize;
            'MediaLoaded'                 = $disk.MediaLoaded;
            'MinBlockSize'                = $disk.MinBlockSize;
            'Model'                       = $disk.Model;
            'Name'                        = $disk.Name;
            'NeedsCleaning'               = $disk.NeedsCleaning;
            'NumberOfMediaSupported'      = $disk.NumberOfMediaSupported;
            'PartitionLayout'             = @{ }; # Set later on partition check
            'Partitions'                  = $disk.Partitions;
            'PartitionStyle'              = $AdditionalDiskData1.PartitionStyle
            'PhysicalLocation'            = $AdditionalDiskData1.Location;
            'PhysicalSectorSize'          = $AdditionalDiskData1.PhysicalSectorSize;
            'PNPDeviceID'                 = $disk.PNPDeviceID;
            'PowerManagementCapabilities' = $disk.PowerManagementCapabilities;
            'PowerManagementSupported'    = $disk.PowerManagementSupported;
            'SCSIBus'                     = $disk.SCSIBus;
            'SCSILogicalUnit'             = $disk.SCSILogicalUnit;
            'SCSIPort'                    = $disk.SCSIPort;
            'SCSITargetId'                = $disk.SCSITargetId;
            'SectorsPerTrack'             = $disk.SectorsPerTrack;
            'SerialNumber'                = $disk.SerialNumber;
            'Signature'                   = $disk.Signature;
            'Size'                        = $disk.Size;
            'Status'                      = $disk.Status;
            'StatusInfo'                  = $disk.StatusInfo;
            'SystemCreationClassName'     = $disk.SystemCreationClassName;
            'SystemName'                  = $disk.SystemName;
            'TotalCylinders'              = $disk.TotalCylinders;
            'TotalHeads'                  = $disk.TotalHeads;
            'TotalSectors'                = $disk.TotalSectors;
            'TotalTracks'                 = $disk.TotalTracks;
            'TracksPerCylinder'           = $disk.TracksPerCylinder;
            'UniqueID'                    = $AdditionalDiskData1.UniqueID;
        }

                $MaxBlocks = 0;

        foreach ($partition in $Partitions) {
            $DriveLetter            = $null;
            [string]$PartitionIndex = $partition.Index;

            if ($PartitionInformation.ContainsKey($DiskIdString) -And $PartitionInformation[$DiskIdString].Partitions.ContainsKey($PartitionIndex)) {
                $DriveLetter = $PartitionInformation[$DiskIdString].Partitions[$PartitionIndex];

                $DiskInfo.DriveReference.Add(
                    $DriveLetter, $partition.Index
                );
            }

            $DiskInfo.PartitionLayout.Add(
                $PartitionIndex,
                @{
                    'NumberOfBlocks'   = $Partition.NumberOfBlocks;
                    'BootPartition'    = $Partition.BootPartition;
                    'PrimaryPartition' = $Partition.PrimaryPartition;
                    'Size'             = $Partition.Size;
                    'Index'            = $Partition.Index;
                    'DiskIndex'        = $Partition.DiskIndex;
                    'DriveLetter'      = $DriveLetter;
                    'Bootable'         = $Partition.Bootable;
                    'Name'             = [string]::Format('Disk #{0}, Partition #{1}', $DiskId, $PartitionIndex);
                    'StartingOffset'   = $Partition.StartingOffset;
                    'Status'           = $Partition.Status;
                    'StatusInfo'       = $Partition.StatusInfo;
                    'Type'             = $Partition.Type;
                }
            )

            foreach ($logical_disk in $LogicalDisk){
                if ($logical_disk.DeviceId -eq $DriveLetter) {
                    if ($null -ne $LogicalDisk) {
                        $UsedSpace = 0;

                        if ([string]::IsNullOrEmpty($DiskInfo.PartitionLayout[$PartitionIndex].Size) -eq $FALSE -And [string]::IsNullOrEmpty($logical_disk.FreeSpace) -eq $FALSE) {
                            $UsedSpace = $DiskInfo.PartitionLayout[$PartitionIndex].Size - $logical_disk.FreeSpace;
                        }

                        $DiskInfo.PartitionLayout[$PartitionIndex].Add(
                            'FreeSpace', $logical_disk.FreeSpace
                        );
                        $DiskInfo.PartitionLayout[$PartitionIndex].Add(
                            'UsedSpace', $UsedSpace
                        );
                        $DiskInfo.PartitionLayout[$PartitionIndex].Add(
                            'VolumeName', $logical_disk.VolumeName
                        );
                        $DiskInfo.PartitionLayout[$PartitionIndex].Add(
                            'FileSystem', $logical_disk.FileSystem
                        );
                        $DiskInfo.PartitionLayout[$PartitionIndex].Add(
                            'VolumeSerialNumber', $logical_disk.VolumeSerialNumber
                        );
                        $DiskInfo.PartitionLayout[$PartitionIndex].Add(
                            'Description', $logical_disk.Description
                        );
                        $DiskInfo.PartitionLayout[$PartitionIndex].Add(
                            'Access', $logical_disk.Access
                        );
                        $DiskInfo.PartitionLayout[$PartitionIndex].Add(
                            'SupportsFileBasedCompression', $logical_disk.SupportsFileBasedCompression
                        );
                        $DiskInfo.PartitionLayout[$PartitionIndex].Add(
                            'SupportsDiskQuotas', $logical_disk.SupportsDiskQuotas
                        );
                        $DiskInfo.PartitionLayout[$PartitionIndex].Add(
                            'Compressed', $logical_disk.Compressed
                        );
                    }

                    break;
                }

            $MaxBlocks += $Partition.NumberOfBlocks;
            $DiskInfo.MaxBlockSize = $MaxBlocks;

            }

            break;
        }


        $DiskInfo.Add('OperationalStatus', @{ });
        $DiskInfo.Add(
            'BusType',
            @{
                'value' = $AdditionalDiskData1.BusType;
                'name'  = $AdditionalDiskData1.BusType;
            }
        );
        $DiskInfo.Add(
            'HealthStatus',
            @{
                'Value' = $AdditionalDiskData2.HealthStatus;
                'Name'  = (Get-IcingaProviderEnumData -Enum $ProviderEnums -Key 'DiskHealthStatus' -Index $AdditionalDiskData2.HealthStatus);
            }
        );
        if ($null -ne $AdditionalDiskData2.OperationalStatus) {
            $OperationalStatus = @{ };

            foreach ($entry in $AdditionalDiskData2.OperationalStatus) {
                if (Test-Numeric $entry) {
                    Add-IcingaHashtableItem -Hashtable $OperationalStatus -Key ([int]$entry) -Value (Get-IcingaProviderEnumData -Enum $ProviderEnums -Key 'DiskOperationalStatus' -Index $entry) | Out-Null;
                } else {
                    if ($ProviderEnums.DiskOperationalStatus.Values -Contains $entry) {
                        foreach ($opStatus in $ProviderEnums.DiskOperationalStatus.Keys) {
                            $opStatusValue = (Get-IcingaProviderEnumData -Enum $ProviderEnums -Key 'DiskOperationalStatus' -Index $opStatus);
                            if ($opStatusValue.ToLower() -eq ([string]$entry).ToLower()) {
                                Add-IcingaHashtableItem -Hashtable $OperationalStatus -Key ([int]$opStatus) -Value $entry | Out-Null;
                                break;
                            }
                        }
                    }
                }
            }

            $DiskInfo.OperationalStatus = $OperationalStatus;
        } 
        else {
        $DiskInfo.OperationalStatus= @{ 0 = 'Unknown'; };
        }

        $DiskInfo.Add(
            'MediaType',
            @{
                'Value' = $AdditionalDiskData2.MediaType;
                'Name'  = (Get-IcingaProviderEnumData -Enum $ProviderEnums -Key 'DiskMediaType' -Index $AdditionalDiskData2.MediaType);
            }
        );


        $PhysicalDiskData.Add($DiskId, $diskinfo);
    }

2. Modify Icinga_ProviderEnums.psm1

Add the following to the [hashtable]$DiskOperationalStatus

    18     = 'Power Mode';
    19     = 'Relocating';
    0xD002 = 'Detached';
    0xD003 = 'Incomplete';

Add the following to the [hashtable]$DiskOperationalStatusName

    'Power Mode'                 = 18;
    'Relocating'                 = 19;
    'Detached'                   = 0xD002;
    'Incomplete'                 = 0xD003;

@Aleksey-Maksimov
Copy link

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants