1 #!powershell
2
3 # Copyright: (c) 2019, Micah Hunsberger
4 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5
6 #AnsibleRequires -CSharpUtil Ansible.Basic
7
8 Set-StrictMode -Version 2
9
10 $spec = @{
11 options = @{
12 path = @{ type = 'path'; required = $true }
13 state = @{ type = 'str'; default = 'present'; choices = 'absent', 'present' }
14 recurse = @{ type = 'bool'; default = $false }
15 force = @{ type = 'bool'; default = $true }
16 }
17 supports_check_mode = $true
18 }
19
20 $module = [Ansible.Basic.AnsibleModule]::Create($args, $spec)
21
22 $path = $module.Params.path
23 $state = $module.Params.state
24 $recurse = $module.Params.recurse
25 $force = $module.Params.force
26
27 $module.Result.rc = 0
28
29 if(-not (Test-Path -LiteralPath $path)) {
30 $module.FailJson("Path to item, $path, does not exist.")
31 }
32
33 $item = Get-Item -LiteralPath $path -Force # Use -Force for hidden files
34 if (-not $item.PSIsContainer -and $recurse) {
35 $module.Warn("The recurse option has no effect when path is not a folder.")
36 }
37
38 $cim_params = @{
39 ClassName = 'Win32_LogicalDisk'
=()40 Filter = "DeviceId='$($item.PSDrive.Name):'"
41 Property = @('FileSystem', 'SupportsFileBasedCompression')
42 }
43 $drive_info = Get-CimInstance @cim_params
44 if ($drive_info.SupportsFileBasedCompression -eq $false) {
45 $module.FailJson("Path, $path, is not on a filesystemi '$($drive_info.FileSystem)' that supports file based compression.")
46 }
47
Get-ReturnCodeMessage()48 function Get-ReturnCodeMessage {
49 param(
50 [int]$code
51 )
52 switch ($code) {
53 0 { return "The request was successful." }
54 2 { return "Access was denied." }
55 8 { return "An unspecified failure occurred." }
56 9 { return "The name specified was not valid." }
57 10 { return "The object specified already exists." }
58 11 { return "The file system is not NTFS." }
59 12 { return "The platform is not Windows." }
60 13 { return "The drive is not the same." }
61 14 { return "The directory is not empty." }
62 15 { return "There has been a sharing violation." }
63 16 { return "The start file specified was not valid." }
64 17 { return "A privilege required for the operation is not held." }
65 21 { return "A parameter specified is not valid." }
66 }
67 }
68
Get-EscapedFileNamenull69 function Get-EscapedFileName {
70 param(
71 [string]$FullName
72 )
73 return $FullName.Replace("\","\\").Replace("'","\'")
74 }
75
76 $is_compressed = ($item.Attributes -band [System.IO.FileAttributes]::Compressed) -eq [System.IO.FileAttributes]::Compressed
77 $needs_changed = $is_compressed -ne ($state -eq 'present')
78
79 if($force -and $recurse -and $item.PSIsContainer) {
80 if (-not $needs_changed) {
81 # Check the subfolders and files
82 $entries_to_check = $item.EnumerateFileSystemInfos("*", [System.IO.SearchOption]::AllDirectories)
83 foreach ($entry in $entries_to_check) {
84 $is_compressed = ($entry.Attributes -band [System.IO.FileAttributes]::Compressed) -eq [System.IO.FileAttributes]::Compressed
85 if ($is_compressed -ne ($state -eq 'present')) {
86 $needs_changed = $true
87 break
88 }
89 }
90 }
91 }
92
93 if($needs_changed) {
94 $module.Result.changed = $true
95 if ($item.PSIsContainer) {
96 $cim_obj = Get-CimInstance -ClassName 'Win32_Directory' -Filter "Name='$(Get-EscapedFileName -FullName $item.FullName)'"
97 } else {
98 $cim_obj = Get-CimInstance -ClassName 'CIM_LogicalFile' -Filter "Name='$(Get-EscapedFileName -FullName $item.FullName)'"
99 }
100 if($state -eq 'present') {
101 if(-not $module.CheckMode) {
102 $ret = Invoke-CimMethod -InputObject $cim_obj -MethodName 'CompressEx' -Arguments @{ Recursive = $recurse }
103 $module.Result.rc = $ret.ReturnValue
104 }
105 } else {
106 if(-not $module.CheckMode) {
107 $ret = $ret = Invoke-CimMethod -InputObject $cim_obj -MethodName 'UnCompressEx' -Arguments @{ Recursive = $recurse }
108 $module.Result.rc = $ret.ReturnValue
109 }
110 }
111 }
112
113 $module.Result.msg = Get-ReturnCodeMessage -code $module.Result.rc
114 if($module.Result.rc -ne 0) {
115 $module.FailJson($module.Result.msg)
116 }
117
118 $module.ExitJson()
119