Added new module win_disk_facts (#32935)

* Added module new win_disk_facts

* Corrected examples section

* Added integration tests

* Added some disk properties

* Removed whitspaces

* Extended docu

* Changed header

* Added partition, volume and physical disk output

* Removed MediaType property of phys. disk

* Added return values

Added virtual disk, volume and physical disk output

* Added docu for return values

* Removed whitespaces

* Improved and added values

- Added virtual disk return values
- Improved code

* Updated docu

* Removed whitespaces

* Removed check

* Improved code and docu

* Changed integration test

* Changed integration test

* Changed integration test

* Changed integration test

* corrected typo

* Added admin test because CIM is not available with user rights

* Changed unit prefix from decimal to binary
This commit is contained in:
Marc Tschapek 2017-12-20 12:53:19 +01:00 committed by Jordan Borean
parent 4a4da2b774
commit b3ff93e129
5 changed files with 813 additions and 0 deletions

View file

@ -0,0 +1,190 @@
#!powershell
# Copyright: (c) 2017, Marc Tschapek <marc.tschapek@itelligence.de>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
#Requires -Module Ansible.ModuleUtils.Legacy
#AnsibleRequires -OSVersion 6.2
$ErrorActionPreference = "Stop"
Set-StrictMode -Version 2.0
# Create a new result object
$result = @{
changed = $false
ansible_facts = @{
total_disks = 0
disks = @()
}
}
# Functions
function Test-Admin {
$CurrentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
$IsAdmin = $CurrentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
return $IsAdmin
}
# Check admin rights
if (-not (Test-Admin)) {
$result.Remove("total_disks")
$result.Remove("disks")
Fail-Json -obj $result -message "Cmdlet was not started with elevated rights"
}
# Search disks
try {
$disks = Get-Disk
} catch {
Fail-Json -obj $result -message "Failed to search the disks on the target: $($_.Exception.Message)"
}
[int32]$diskcount = $disks | Measure-Object | Select-Object -ExpandProperty Count
$result.ansible_facts.total_disks = $diskcount
foreach ($disk in $disks) {
$disk_info = @{}
$pdisk = Get-PhysicalDisk -ErrorAction SilentlyContinue | Where-Object {
$_.DeviceId -eq $disk.Number
}
if ($pdisk) {
$disk_info["physical_disk"] += @{
size = "$($pSize = "{0:N3}" -f ($pdisk.Size / 1GB))$($pSize)GiB"
allocated_size = "$($pAllocSize = "{0:N3}" -f ($pdisk.AllocatedSize / 1GB))$($pAllocSize)GiB"
device_id = $pdisk.DeviceId
friendly_name = $pdisk.FriendlyName
operational_status = $pdisk.OperationalStatus
health_status = $pdisk.HealthStatus
bus_type = $pdisk.BusType
usage_type = $pdisk.Usage
supported_usages = $pdisk.SupportedUsages
spindle_speed = "$($pdisk.SpindleSpeed)rpm"
firmware_version = $pdisk.FirmwareVersion
physical_location = $pdisk.PhysicalLocation
manufacturer = $pdisk.Manufacturer
model = $pdisk.Model
can_pool = $pdisk.CanPool
indication_enabled = $pdisk.IsIndicationEnabled
partial = $pdisk.IsPartial
serial_number = $pdisk.SerialNumber
object_id = $pdisk.ObjectId
unique_id = $pdisk.UniqueId
}
if ([single]"$([System.Environment]::OSVersion.Version.Major).$([System.Environment]::OSVersion.Version.Minor)" -ge 6.3) {
$disk_info.physical_disk.media_type = $pdisk.MediaType
}
if (-not $pdisk.CanPool) {
$disk_info.physical_disk.cannot_pool_reason = $pdisk.CannotPoolReason
}
$vdisk = Get-VirtualDisk -PhysicalDisk $pdisk -ErrorAction SilentlyContinue
if ($vdisk) {
$disk_info["virtual_disk"] += @{
size = "$($vDSize = "{0:N3}" -f ($vdisk.Size / 1GB))$($vDSize)GiB"
allocated_size = "$($vDAllocSize = "{0:N3}" -f ($vdisk.AllocatedSize / 1GB))$($vDAllocSize)GiB"
footprint_on_pool = "$($vDPrint = "{0:N3}" -f ($vdisk.FootprintOnPool / 1GB))$($vDPrint)GiB"
name = $vdisk.name
friendly_name = $vdisk.FriendlyName
operational_status = $vdisk.OperationalStatus
health_status = $vdisk.HealthStatus
provisioning_type = $vdisk.ProvisioningType
allocation_unit_size = "$($vdisk.AllocationUnitSize / 1KB)KiB"
media_type = $vdisk.MediaType
parity_layout = $vdisk.ParityLayout
access = $vdisk.Access
detached_reason = $vdisk.DetachedReason
write_cache_size = "$($vdisk.WriteCacheSize)s/byte/bytes/"
fault_domain_awareness = $vdisk.FaultDomainAwareness
inter_leave = "$($vDLeave = "{0:N3}" -f ($vdisk.InterLeave / 1KB))$($vDLeave)KiB"
deduplication_enabled = $vdisk.IsDeduplicationEnabled
enclosure_aware = $vdisk.IsEnclosureAware
manual_attach = $vdisk.IsManualAttach
snapshot = $vdisk.IsSnapshot
tiered = $vdisk.IsTiered
physical_sector_size = "$($vdisk.PhysicalSectorSize / 1KB)KiB"
logical_sector_size = "$($vdisk.LogicalSectorSize)s/byte/bytes/"
available_copies = $vdisk.NumberOfAvailableCopies
columns = $vdisk.NumberOfColumns
groups = $vdisk.NumberOfGroups
physical_disk_redundancy = $vdisk.PhysicalDiskRedundancy
read_cache_size = $vdisk.ReadCacheSize
request_no_spof = $vdisk.RequestNoSinglePointOfFailure
resiliency_setting_name = $vdisk.ResiliencySettingName
object_id = $vdisk.ObjectId
unique_id_format = $vdisk.UniqueIdFormat
unique_id = $vdisk.UniqueId
}
}
}
$disk_info.number = $disk.Number
$disk_info.size = "$($disk.Size / 1GB)GiB"
$disk_info.bus_type = $disk.BusType
$disk_info.friendly_name = $disk.FriendlyName
$disk_info.partition_style = $disk.PartitionStyle
$disk_info.partition_count = $disk.NumberOfPartitions
$disk_info.operational_status = $disk.OperationalStatus
$disk_info.sector_size = "$($disk.PhysicalSectorSize)s/byte/bytes/"
$disk_info.read_only = $disk.IsReadOnly
$disk_info.bootable = $disk.IsBoot
$disk_info.system_disk = $disk.IsSystem
$disk_info.clustered = $disk.IsClustered
$disk_info.manufacturer = $disk.Manufacturer
$disk_info.model = $disk.Model
$disk_info.firmware_version = $disk.FirmwareVersion
$disk_info.location = $disk.Location
$disk_info.serial_number = $disk.SerialNumber
$disk_info.unique_id = $disk.UniqueId
$disk_info.guid = $disk.Guid
$disk_info.path = $disk.Path
$parts = Get-Partition -DiskNumber $($disk.Number) -ErrorAction SilentlyContinue
if ($parts) {
$disk_info["partitions"] += @()
foreach ($part in $parts) {
$partition_info = @{
number = $part.PartitionNumber
size = "$($pSize = "{0:N3}" -f ($part.Size /1GB))$($pSize)GiB"
type = $part.Type
drive_letter = $part.DriveLetter
transition_state = $part.TransitionState
offset = $part.Offset
hidden = $part.IsHidden
shadow_copy = $part.IsShadowCopy
guid = $part.Guid
access_paths = $part.AccessPaths
}
if ($disks.PartitionStyle -eq "GPT") {
$partition_info.gpt_type = $part.GptType
$partition_info.no_default_driveletter = $part.NoDefaultDriveLetter
} elseif ($disks.PartitionStyle -eq "MBR") {
$partition_info.mbr_type = $part.MbrType
$partition_info.active = $part.IsActive
}
$vols = Get-Volume -Partition $part -ErrorAction SilentlyContinue
if ($vols) {
$partition_info["volumes"] += @()
foreach ($vol in $vols) {
$volume_info = @{
size = "$($vSize = "{0:N3}" -f ($vol.Size / 1GB))$($vSize)GiB"
size_remaining = "$($vSizeRe = "{0:N3}" -f ($vol.SizeRemaining / 1GB))$($vSizeRe)GiB"
type = $vol.FileSystem
label = $vol.FileSystemLabel
health_status = $vol.HealthStatus
drive_type = $vol.DriveType
object_id = $vol.ObjectId
path = $vol.Path
}
if ([System.Environment]::OSVersion.Version.Major -ge 10) {
$volume_info.allocation_unit_size = "$($vol.AllocationUnitSize /1KB)KiB"
} else {
$volPath = ($vol.Path.TrimStart("\\?\")).TrimEnd("\")
$BlockSize = (Get-CimInstance -Query "SELECT BlockSize FROM Win32_Volume WHERE DeviceID like '%$volPath%'" -ErrorAction SilentlyContinue | Select-Object BlockSize).BlockSize
$volume_info.allocation_unit_size = "$($BlockSize / 1KB)KiB"
}
$partition_info.volumes += $volume_info
}
}
$disk_info.partitions += $partition_info
}
}
$result.ansible_facts.disks += $disk_info
}
# Return result
Exit-Json -obj $result

View file

@ -0,0 +1,592 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2017, Marc Tschapek <marc.tschapek@itelligence.de>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: win_disk_facts
version_added: '2.5'
short_description: Show the attached disks and disk information of the target host
description:
- With the module you can retrieve and output detailed information about the attached disks of the target and
it's volumes and partitions if existent.
requirements:
- Windows 8.1 / Windows 2012 (NT 6.2)
author:
- Marc Tschapek (@marqelme)
notes:
- In order to understand all the returned properties and values please visit the following site and open the respective MSFT class
U(https://msdn.microsoft.com/en-us/library/windows/desktop/hh830612.aspx)
'''
EXAMPLES = r'''
- name: get disk facts
win_disk_facts:
- name: output first disk size
debug:
var: ansible_facts.disks[0].size
- name: get disk facts
win_disk_facts:
- name: output second disk serial number
debug:
var: ansible_facts.disks[0].serial_number
'''
RETURN = r'''
ansible_facts:
description: Dictionary containing all the detailed information about the disks of the target.
returned: always
type: complex
contains:
total_disks:
description: Count of found disks on the target.
returned: if disks were found
type: int
sample: 3
disks:
description: Detailed information about one particular disk.
returned: if disks were found
type: list
contains:
number:
description: Disk number of the particular disk.
returned: always
type: int
sample: 0
size:
description: Size in Gibibyte of the particular disk.
returned: always
type: string
sample: "100GiB"
bus_type:
description: Bus type of the particular disk.
returned: always
type: string
sample: "SCSI"
friendly_name:
description: Friendly name of the particular disk.
returned: always
type: string
sample: "Red Hat VirtIO SCSI Disk Device"
partition_style:
description: Partition style of the particular disk.
returned: always
type: string
sample: "MBR"
partition_count:
description: Number of partitions on the particular disk.
returned: always
type: int
sample: 4
operational_status:
description: Operational status of the particular disk.
returned: always
type: string
sample: "Online"
sector_size:
description: Sector size in byte of the particular disk.
returned: always
type: string
sample: "512s/byte/bytes/"
read_only:
description: Read only status of the particular disk.
returned: always
type: string
sample: "true"
bootable:
description: Information whether the particular disk is a bootable disk.
returned: always
type: string
sample: "false"
system_disk:
description: Information whether the particular disk is a system disk.
returned: always
type: string
sample: "true"
clustered:
description: Information whether the particular disk is clustered (part of a failover cluster).
returned: always
type: string
sample: "false"
manufacturer:
description: Manufacturer of the particular disk.
returned: always
type: string
sample: "Red Hat"
model:
description: Model specification of the particular disk.
returned: always
type: string
sample: "VirtIO"
firmware_version:
description: Firmware version of the particular disk.
returned: always
type: string
sample: "0001"
location:
description: Location of the particular disk on the target.
returned: always
type: string
sample: "PCIROOT(0)#PCI(0400)#SCSI(P00T00L00)"
serial_number:
description: Serial number of the particular disk on the target.
returned: always
type: string
sample: "b62beac80c3645e5877f"
unique_id:
description: Unique ID of the particular disk on the target.
returned: always
type: string
sample: "3141463431303031"
guid:
description: GUID of the particular disk on the target.
returned: if existent
type: string
sample: "{efa5f928-57b9-47fc-ae3e-902e85fbe77f}"
path:
description: Path of the particular disk on the target.
returned: always
type: string
sample: "\\\\?\\scsi#disk&ven_red_hat&prod_virtio#4&23208fd0&1&000000#{<id>}"
partitions:
description: Detailed information about one particular partition on the specified disk.
returned: if existent
type: list
contains:
number:
description: Number of the particular partition.
returned: always
type: int
sample: 1
size:
description:
- Size in Gibibyte of the particular partition.
- Accurate to three decimal places.
returned: always
type: string
sample: "0.031GiB"
type:
description: Type of the particular partition.
returned: always
type: string
sample: "IFS"
gpt_type:
description: gpt type of the particular partition.
returned: if partition_style property of the particular disk has value "GPT"
type: string
sample: "{e3c9e316-0b5c-4db8-817d-f92df00215ae}"
no_default_driveletter:
description: Information whether the particular partition has a default drive letter or not.
returned: if partition_style property of the particular disk has value "GPT"
type: string
sample: "true"
mbr_type:
description: mbr type of the particular partition.
returned: if partition_style property of the particular disk has value "MBR"
type: int
sample: 7
active:
description: Information whether the particular partition is an active partition or not.
returned: if partition_style property of the particular disk has value "MBR"
type: string
sample: "true"
drive_letter:
description: Drive letter of the particular partition.
returned: if existent
type: string
sample: "C"
transition_state:
description: Transition state of the particular partition.
returned: always
type: int
sample: 1
offset:
description: Offset of the particular partition.
returned: always
type: int
sample: 368050176
hidden:
description: Information whether the particular partition is hidden or not.
returned: always
type: string
sample: "true"
shadow_copy:
description: Information whether the particular partition is a shadow copy of another partition.
returned: always
type: string
sample: "false"
guid:
description: GUID of the particular partition.
returned: if existent
type: string
sample: "{302e475c-6e64-4674-a8e2-2f1c7018bf97}"
access_paths:
description: Access paths of the particular partition.
returned: if existent
type: string
sample: "\\\\?\\Volume{85bdc4a8-f8eb-11e6-80fa-806e6f6e6963}\\"
volumes:
description: Detailed information about one particular volume on the specified partition.
returned: if existent
type: list
contains:
size:
description:
- Size in Gibibyte of the particular volume.
- Accurate to three decimal places.
returned: always
type: string
sample: "0,342GiB"
size_remaining:
description:
- Remaining size in Gibibyte of the particular volume.
- Accurate to three decimal places.
returned: always
type: string
sample: "0,146GiB"
type:
description: File system type of the particular volume.
returned: always
type: string
sample: "NTFS"
label:
description: File system label of the particular volume.
returned: always
type: string
sample: "System Reserved"
health_status:
description: Health status of the particular volume.
returned: always
type: string
sample: "Healthy"
drive_type:
description: Drive type of the particular volume.
returned: always
type: string
sample: "Fixed"
allocation_unit_size:
description: Allocation unit size in Kibibyte of the particular volume.
returned: always
type: string
sample: "64KiB"
object_id:
description: Object ID of the particular volume.
returned: always
type: string
sample: "\\\\?\\Volume{85bdc4a9-f8eb-11e6-80fa-806e6f6e6963}\\"
path:
description: Path of the particular volume.
returned: always
type: string
sample: "\\\\?\\Volume{85bdc4a9-f8eb-11e6-80fa-806e6f6e6963}\\"
physical_disk:
description: Detailed information about physical disk properties of the particular disk.
returned: if existent
type: complex
contains:
media_type:
description: Media type of the particular physical disk.
returned: always
type: string
sample: "UnSpecified"
size:
description:
- Size in Gibibyte of the particular physical disk.
- Accurate to three decimal places.
returned: always
type: string
sample: "200GiB"
allocated_size:
description:
- Allocated size in Gibibyte of the particular physical disk.
- Accurate to three decimal places.
returned: always
type: string
sample: "100GiB"
device_id:
description: Device ID of the particular physical disk.
returned: always
type: string
sample: "0"
friendly_name:
description: Friendly name of the particular physical disk.
returned: always
type: string
sample: "PhysicalDisk0"
operational_status:
description: Operational status of the particular physical disk.
returned: always
type: string
sample: "OK"
health_status:
description: Health status of the particular physical disk.
returned: always
type: string
sample: "Healthy"
bus_type:
description: Bus type of the particular physical disk.
returned: always
type: string
sample: "SCSI"
usage_type:
description: Usage type of the particular physical disk.
returned: always
type: string
sample: "Auto-Select"
supported_usages:
description: Supported usage types of the particular physical disk.
returned: always
type: complex
contains:
Count:
description: Count of supported usage types.
returned: always
type: int
sample: 5
value:
description: List of supported usage types.
returned: always
type: string
sample: "Auto-Select, Hot Spare"
spindle_speed:
description: Spindle speed in rpm of the particular physical disk.
returned: always
type: string
sample: "4294967295rpm"
physical_location:
description: Physical location of the particular physical disk.
returned: always
type: string
sample: "Integrated : Adapter 3 : Port 0 : Target 0 : LUN 0"
manufacturer:
description: Manufacturer of the particular physical disk.
returned: always
type: string
sample: "SUSE"
model:
description: Model of the particular physical disk.
returned: always
type: string
sample: "Xen Block"
can_pool:
description: Information whether the particular physical disk can be added to a storage pool.
returned: always
type: string
sample: "false"
cannot_pool_reason:
description: Information why the particular physical disk can not be added to a storage pool.
returned: if can_pool property has value false
type: string
sample: "Insufficient Capacity"
indication_enabled:
description: Information whether indication is enabled for the particular physical disk.
returned: always
type: string
sample: "True"
partial:
description: Information whether the particular physical disk is partial.
returned: always
type: string
sample: "False"
serial_number:
description: Serial number of the particular physical disk.
returned: always
type: string
sample: "b62beac80c3645e5877f"
object_id:
description: Object ID of the particular physical disk.
returned: always
type: string
sample: '{1}\\\\HOST\\root/Microsoft/Windows/Storage/Providers_v2\\SPACES_PhysicalDisk.ObjectId=\"{<object_id>}:PD:{<pd>}\"'
unique_id:
description: Unique ID of the particular physical disk.
returned: always
type: string
sample: "3141463431303031"
virtual_disk:
description: Detailed information about virtual disk properties of the particular disk.
returned: if existent
type: complex
contains:
size:
description:
- Size in Gibibyte of the particular virtual disk.
- Accurate to three decimal places.
returned: always
type: string
sample: "300GiB"
allocated_size:
description:
- Allocated size in Gibibyte of the particular virtual disk.
- Accurate to three decimal places.
returned: always
type: string
sample: "100GiB"
footprint_on_pool:
description:
- Footprint on pool in Gibibyte of the particular virtual disk.
- Accurate to three decimal places.
returned: always
type: string
sample: "100GiB"
name:
description: Name of the particular virtual disk.
returned: always
type: string
sample: "vDisk1"
friendly_name:
description: Friendly name of the particular virtual disk.
returned: always
type: string
sample: "Prod2 Virtual Disk"
operational_status:
description: Operational status of the particular virtual disk.
returned: always
type: string
sample: "OK"
health_status:
description: Health status of the particular virtual disk.
returned: always
type: string
sample: "Healthy"
provisioning_type:
description: Provisioning type of the particular virtual disk.
returned: always
type: string
sample: "Thin"
allocation_unit_size:
description: Allocation unit size in Kibibyte of the particular virtual disk.
returned: always
type: string
sample: "4KiB"
media_type:
description: Media type of the particular virtual disk.
returned: always
type: string
sample: "Unspecified"
parity_layout:
description: Parity layout of the particular virtual disk.
returned: if existent
type: int
sample: 1
access:
description: Access of the particular virtual disk.
returned: always
type: string
sample: "Read/Write"
detached_reason:
description: Detached reason of the particular virtual disk.
returned: always
type: string
sample: "None"
write_cache_size:
description: Write cache size in byte of the particular virtual disk.
returned: always
type: string
sample: "100s/byte/bytes/"
fault_domain_awareness:
description: Fault domain awareness of the particular virtual disk.
returned: always
type: string
sample: "PhysicalDisk"
inter_leave:
description:
- Inter leave in Kibibyte of the particular virtual disk.
- Accurate to three decimal places.
returned: always
type: string
sample: "100KiB"
deduplication_enabled:
description: Information whether deduplication is enabled for the particular virtual disk.
returned: always
type: string
sample: "True"
enclosure_aware:
description: Information whether the particular virtual disk is enclosure aware.
returned: always
type: string
sample: "False"
manual_attach:
description: Information whether the particular virtual disk is manual attached.
returned: always
type: string
sample: "True"
snapshot:
description: Information whether the particular virtual disk is a snapshot.
returned: always
type: string
sample: "False"
tiered:
description: Information whether the particular virtual disk is tiered.
returned: always
type: string
sample: "True"
physical_sector_size:
description: Physical sector size in Kibibyte of the particular virtual disk.
returned: always
type: string
sample: "4KiB"
logical_sector_size:
description: Logical sector size in byte of the particular virtual disk.
returned: always
type: string
sample: "512s/byte/bytes/"
available_copies:
description: Number of the available copies of the particular virtual disk.
returned: if existent
type: int
sample: 1
columns:
description: Number of the columns of the particular virtual disk.
returned: always
type: int
sample: 2
groups:
description: Number of the groups of the particular virtual disk.
returned: always
type: int
sample: 1
physical_disk_redundancy:
description: Type of the physical disk redundancy of the particular virtual disk.
returned: always
type: int
sample: 1
read_cache_size:
description: Read cache size in byte of the particular virtual disk.
returned: always
type: int
sample: 0
request_no_spof:
description: Information whether the particular virtual disk requests no single point of failure.
returned: always
type: string
sample: "True"
resiliency_setting_name:
description: Type of the physical disk redundancy of the particular virtual disk.
returned: always
type: int
sample: 1
object_id:
description: Object ID of the particular virtual disk.
returned: always
type: string
sample: '{1}\\\\HOST\\root/Microsoft/Windows/Storage/Providers_v2\\SPACES_VirtualDisk.ObjectId=\"{<object_id>}:VD:{<vd>}\"'
unique_id:
description: Unique ID of the particular virtual disk.
returned: always
type: string
sample: "260542E4C6B01D47A8FA7630FD90FFDE"
unique_id_format:
description: Unique ID format of the particular virtual disk.
returned: always
type: string
sample: "Vendor Specific"
'''

View file

@ -0,0 +1 @@
windows/ci/group2

View file

@ -0,0 +1,13 @@
# NOTE: The win_disk_facts module only works on Win2012R2+
- name: check whether storage module is available (windows 2008 r2 or later)
raw: PowerShell -Command Import-Module Storage
register: win_feature_has_storage_module
ignore_errors: true
- name: Only run tests when Windows is capable
when: (win_feature_has_storage_module|success) and (ansible_powershell_version is defined) and (ansible_powershell_version >= 3)
block:
- name: Test in normal mode
include: tests.yml

View file

@ -0,0 +1,17 @@
- name: get disk facts on the target
win_disk_facts:
register: disks_found
- name: assert disk facts
assert:
that:
- disks_found.changed == false
- disks_found.ansible_facts.disks[0].size is defined
- disks_found.ansible_facts.disks[0].number is defined
- disks_found.ansible_facts.disks[0].operational_status is defined
- disks_found.ansible_facts.disks[0].read_only is defined
- disks_found.ansible_facts.disks[0].clustered is defined
- disks_found.ansible_facts.disks[0].location is defined
- disks_found.ansible_facts.disks[0].guid is defined
- disks_found.ansible_facts.disks[0].path is defined
- disks_found.ansible_facts.disks[0].bootable is defined