mirror of https://github.com/ansible/ansible.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
6.9 KiB
PowerShell
201 lines
6.9 KiB
PowerShell
#!powershell
|
|
|
|
# Copyright: (c) 2019, Varun Chopra (@chopraaa) <v@chopraaa.com>
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
#AnsibleRequires -CSharpUtil Ansible.Basic
|
|
#AnsibleRequires -OSVersion 6.2
|
|
|
|
Set-StrictMode -Version 2
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$spec = @{
|
|
options = @{
|
|
drive_letter = @{ type = "str" }
|
|
path = @{ type = "str" }
|
|
label = @{ type = "str" }
|
|
new_label = @{ type = "str" }
|
|
file_system = @{ type = "str"; choices = "ntfs", "refs", "exfat", "fat32", "fat" }
|
|
allocation_unit_size = @{ type = "int" }
|
|
large_frs = @{ type = "bool" }
|
|
full = @{ type = "bool"; default = $false }
|
|
compress = @{ type = "bool" }
|
|
integrity_streams = @{ type = "bool" }
|
|
force = @{ type = "bool"; default = $false }
|
|
}
|
|
mutually_exclusive = @(
|
|
,@('drive_letter', 'path', 'label')
|
|
)
|
|
required_one_of = @(
|
|
,@('drive_letter', 'path', 'label')
|
|
)
|
|
supports_check_mode = $true
|
|
}
|
|
|
|
$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec)
|
|
|
|
$drive_letter = $module.Params.drive_letter
|
|
$path = $module.Params.path
|
|
$label = $module.Params.label
|
|
$new_label = $module.Params.new_label
|
|
$file_system = $module.Params.file_system
|
|
$allocation_unit_size = $module.Params.allocation_unit_size
|
|
$large_frs = $module.Params.large_frs
|
|
$full_format = $module.Params.full
|
|
$compress_volume = $module.Params.compress
|
|
$integrity_streams = $module.Params.integrity_streams
|
|
$force_format = $module.Params.force
|
|
|
|
# Some pre-checks
|
|
if ($null -ne $drive_letter -and $drive_letter -notmatch "^[a-zA-Z]$") {
|
|
$module.FailJson("The parameter drive_letter should be a single character A-Z")
|
|
}
|
|
if ($integrity_streams -eq $true -and $file_system -ne "refs") {
|
|
$module.FailJson("Integrity streams can be enabled only on ReFS volumes. You specified: $($file_system)")
|
|
}
|
|
if ($compress_volume -eq $true) {
|
|
if ($file_system -eq "ntfs") {
|
|
if ($null -ne $allocation_unit_size -and $allocation_unit_size -gt 4096) {
|
|
$module.FailJson("NTFS compression is not supported for allocation unit sizes above 4096")
|
|
}
|
|
}
|
|
else {
|
|
$module.FailJson("Compression can be enabled only on NTFS volumes. You specified: $($file_system)")
|
|
}
|
|
}
|
|
|
|
function Get-AnsibleVolume {
|
|
param(
|
|
$DriveLetter,
|
|
$Path,
|
|
$Label
|
|
)
|
|
|
|
if ($null -ne $DriveLetter) {
|
|
try {
|
|
$volume = Get-Volume -DriveLetter $DriveLetter
|
|
} catch {
|
|
$module.FailJson("There was an error retrieving the volume using drive_letter $($DriveLetter): $($_.Exception.Message)", $_)
|
|
}
|
|
}
|
|
elseif ($null -ne $Path) {
|
|
try {
|
|
$volume = Get-Volume -Path $Path
|
|
} catch {
|
|
$module.FailJson("There was an error retrieving the volume using path $($Path): $($_.Exception.Message)", $_)
|
|
}
|
|
}
|
|
elseif ($null -ne $Label) {
|
|
try {
|
|
$volume = Get-Volume -FileSystemLabel $Label
|
|
} catch {
|
|
$module.FailJson("There was an error retrieving the volume using label $($Label): $($_.Exception.Message)", $_)
|
|
}
|
|
}
|
|
else {
|
|
$module.FailJson("Unable to locate volume: drive_letter, path and label were not specified")
|
|
}
|
|
|
|
return $volume
|
|
}
|
|
|
|
function Format-AnsibleVolume {
|
|
param(
|
|
$Path,
|
|
$Label,
|
|
$FileSystem,
|
|
$Full,
|
|
$UseLargeFRS,
|
|
$Compress,
|
|
$SetIntegrityStreams,
|
|
$AllocationUnitSize
|
|
)
|
|
$parameters = @{
|
|
Path = $Path
|
|
Full = $Full
|
|
}
|
|
if ($null -ne $UseLargeFRS) {
|
|
$parameters.Add("UseLargeFRS", $UseLargeFRS)
|
|
}
|
|
if ($null -ne $SetIntegrityStreams) {
|
|
$parameters.Add("SetIntegrityStreams", $SetIntegrityStreams)
|
|
}
|
|
if ($null -ne $Compress){
|
|
$parameters.Add("Compress", $Compress)
|
|
}
|
|
if ($null -ne $Label) {
|
|
$parameters.Add("NewFileSystemLabel", $Label)
|
|
}
|
|
if ($null -ne $FileSystem) {
|
|
$parameters.Add("FileSystem", $FileSystem)
|
|
}
|
|
if ($null -ne $AllocationUnitSize) {
|
|
$parameters.Add("AllocationUnitSize", $AllocationUnitSize)
|
|
}
|
|
|
|
Format-Volume @parameters -Confirm:$false | Out-Null
|
|
|
|
}
|
|
|
|
$ansible_volume = Get-AnsibleVolume -DriveLetter $drive_letter -Path $path -Label $label
|
|
$ansible_file_system = $ansible_volume.FileSystem
|
|
$ansible_volume_size = $ansible_volume.Size
|
|
$ansible_volume_alu = (Get-CimInstance -ClassName Win32_Volume -Filter "DeviceId = '$($ansible_volume.path.replace('\','\\'))'" -Property BlockSize).BlockSize
|
|
|
|
$ansible_partition = Get-Partition -Volume $ansible_volume
|
|
|
|
if (-not $force_format -and $null -ne $allocation_unit_size -and $ansible_volume_alu -ne 0 -and $null -ne $ansible_volume_alu -and $allocation_unit_size -ne $ansible_volume_alu) {
|
|
$module.FailJson("Force format must be specified since target allocation unit size: $($allocation_unit_size) is different from the current allocation unit size of the volume: $($ansible_volume_alu)")
|
|
}
|
|
|
|
foreach ($access_path in $ansible_partition.AccessPaths) {
|
|
if ($access_path -ne $Path) {
|
|
if ($null -ne $file_system -and
|
|
-not [string]::IsNullOrEmpty($ansible_file_system) -and
|
|
$file_system -ne $ansible_file_system)
|
|
{
|
|
if (-not $force_format)
|
|
{
|
|
$no_files_in_volume = (Get-ChildItem -LiteralPath $access_path -ErrorAction SilentlyContinue | Measure-Object).Count -eq 0
|
|
if($no_files_in_volume)
|
|
{
|
|
$module.FailJson("Force format must be specified since target file system: $($file_system) is different from the current file system of the volume: $($ansible_file_system.ToLower())")
|
|
}
|
|
else
|
|
{
|
|
$module.FailJson("Force format must be specified to format non-pristine volumes")
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$pristine = -not $force_format
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($force_format) {
|
|
if (-not $module.CheckMode) {
|
|
Format-AnsibleVolume -Path $ansible_volume.Path -Full $full_format -Label $new_label -FileSystem $file_system -SetIntegrityStreams $integrity_streams -UseLargeFRS $large_frs -Compress $compress_volume -AllocationUnitSize $allocation_unit_size
|
|
}
|
|
$module.Result.changed = $true
|
|
}
|
|
else {
|
|
if ($pristine) {
|
|
if ($null -eq $new_label) {
|
|
$new_label = $ansible_volume.FileSystemLabel
|
|
}
|
|
# Conditions for formatting
|
|
if ($ansible_volume_size -eq 0 -or
|
|
$ansible_volume.FileSystemLabel -ne $new_label) {
|
|
if (-not $module.CheckMode) {
|
|
Format-AnsibleVolume -Path $ansible_volume.Path -Full $full_format -Label $new_label -FileSystem $file_system -SetIntegrityStreams $integrity_streams -UseLargeFRS $large_frs -Compress $compress_volume -AllocationUnitSize $allocation_unit_size
|
|
}
|
|
$module.Result.changed = $true
|
|
}
|
|
}
|
|
}
|
|
|
|
$module.ExitJson()
|