1 #!powershell
2 
3 # Copyright: (c) 2017, Liran Nisanov <lirannis@gmail.com>
4 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5 
6 #Requires -Module Ansible.ModuleUtils.Legacy
7 
8 ########
9 
Remove-Pagefile($path, $whatif)10 Function Remove-Pagefile($path, $whatif)
11 {
12     Get-CIMInstance Win32_PageFileSetting | Where-Object { $_.Name -eq $path } | Remove-CIMInstance -WhatIf:$whatif
13 }
14 
Get-Pagefile($path)15 Function Get-Pagefile($path)
16 {
17     Get-CIMInstance Win32_PageFileSetting | Where-Object { $_.Name -eq $path }
18 }
19 
20 ########
21 
22 $params = Parse-Args $args -supports_check_mode $true
23 $check_mode = Get-AnsibleParam -obj $params -name '_ansible_check_mode' -type 'bool' -default $false
24 
25 $automatic = Get-AnsibleParam -obj $params -name "automatic" -type "bool"
26 $drive = Get-AnsibleParam -obj $params -name "drive" -type "str"
27 $fullPath = $drive + ":\pagefile.sys"
28 $initialSize = Get-AnsibleParam -obj $params -name "initial_size" -type "int"
29 $maximumSize = Get-AnsibleParam -obj $params -name "maximum_size" -type "int"
30 $override =  Get-AnsibleParam -obj $params -name "override" -type "bool" -default $true
31 $removeAll = Get-AnsibleParam -obj $params -name "remove_all" -type "bool" -default $false
32 $state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "query" -validateset "present","absent","query"
33 $systemManaged = Get-AnsibleParam -obj $params -name "system_managed" -type "bool" -default $false
34 $test_path = Get-AnsibleParam -obj $params -name "test_path" -type "bool" -default $true
35 
36 $result = @{
37     changed = $false
38 }
39 
40 if ($removeAll) {
41     $currentPageFiles = Get-CIMInstance Win32_PageFileSetting
42     if ($null -ne $currentPageFiles) {
43         $currentPageFiles | Remove-CIMInstance -WhatIf:$check_mode > $null
44         $result.changed = $true
45     }
46 }
47 
48 if ($null -ne $automatic) {
49     # change autmoatic managed pagefile
50     try {
51         $computerSystem = Get-CIMInstance -Class win32_computersystem
52     } catch {
53         Fail-Json $result "Failed to query WMI computer system object $($_.Exception.Message)"
54     }
55     if ($computerSystem.AutomaticManagedPagefile -ne $automatic) {
56         if (-not $check_mode) {
57             try {
58             	$computerSystem | Set-CimInstance -Property @{automaticmanagedpagefile="$automatic"} > $null
59             } catch {
60                 Fail-Json $result "Failed to set AutomaticManagedPagefile $($_.Exception.Message)"
61             }
62         }
63         $result.changed = $true
64     }
65 }
66 
67 if ($state -eq "absent") {
68     # Remove pagefile
69     if ($null -ne (Get-Pagefile $fullPath))
70     {
71         try {
72             Remove-Pagefile $fullPath -whatif:$check_mode
73         } catch {
74             Fail-Json $result "Failed to remove pagefile $($_.Exception.Message)"
75         }
76         $result.changed = $true
77     }
78 } elseif ($state -eq "present") {
79     # Remove current pagefile
80     if ($override) {
81         if ($null -ne (Get-Pagefile $fullPath))
82         {
83             try {
84                 Remove-Pagefile $fullPath -whatif:$check_mode
85             } catch {
86                 Fail-Json $result "Failed to remove current pagefile $($_.Exception.Message)"
87             }
88             $result.changed = $true
89         }
90     }
91 
92     # Make sure drive is accessible
93     if (($test_path) -and (-not (Test-Path -LiteralPath "${drive}:"))) {
94         Fail-Json $result "Unable to access '${drive}:' drive"
95     }
96 
97     $curPagefile = Get-Pagefile $fullPath
98 
99     # Set pagefile
100     if ($null -eq $curPagefile) {
101         try {
102             $pagefile = New-CIMInstance -Class Win32_PageFileSetting -Arguments @{name = $fullPath;} -WhatIf:$check_mode
103         } catch {
104             Fail-Json $result "Failed to create pagefile $($_.Exception.Message)"
105         }
106         if (-not ($systemManaged -or $check_mode)) {
107             try {
108                 $pagefile | Set-CimInstance -Property @{ InitialSize = $initialSize; MaximumSize = $maximumSize}
109             } catch {
110                 $originalExceptionMessage = $($_.Exception.Message)
111                 # Try workaround before failing
112                 try {
113                     Remove-Pagefile $fullPath -whatif:$check_mode
114                 } catch {
115                     Fail-Json $result "Failed to remove pagefile before workaround $($_.Exception.Message) Original exception: $originalExceptionMessage"
116                 }
117                 try {
118                     $pagingFilesValues = (Get-ItemProperty -LiteralPath "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management").PagingFiles
119                 } catch {
120                     Fail-Json $result "Failed to get pagefile settings from the registry for workaround $($_.Exception.Message) Original exception: $originalExceptionMessage"
121                 }
122                 $pagingFilesValues += "$fullPath $initialSize $maximumSize"
123                 try {
124                     Set-ItemProperty -LiteralPath "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" "PagingFiles" $pagingFilesValues
125                 } catch {
126                     Fail-Json $result "Failed to set pagefile settings to the registry for workaround $($_.Exception.Message) Original exception: $originalExceptionMessage"
127                 }
128             }
129         }
130         $result.changed = $true
131     }else
132     {
133         if ((-not $check_mode) -and
134             -not ($systemManaged) -and
135             -not ( ($curPagefile.InitialSize -eq 0) -and ($curPagefile.maximumSize -eq 0) ) -and
136             ( ($curPagefile.InitialSize -ne $initialSize) -or ($curPagefile.maximumSize -ne $maximumSize) )
137            )
138         {
139             $curPagefile.InitialSize = $initialSize
140             $curPagefile.MaximumSize = $maximumSize
141             try {
142                 $curPagefile.Put() | out-null
143             } catch {
144                 $originalExceptionMessage = $($_.Exception.Message)
145                 # Try workaround before failing
146                 try {
147                     Remove-Pagefile $fullPath -whatif:$check_mode
148                 } catch {
149                     Fail-Json $result "Failed to remove pagefile before workaround $($_.Exception.Message) Original exception: $originalExceptionMessage"
150                 }
151                 try {
152                     $pagingFilesValues = (Get-ItemProperty -LiteralPath "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management").PagingFiles
153                 } catch {
154                     Fail-Json $result "Failed to get pagefile settings from the registry for workaround $($_.Exception.Message) Original exception: $originalExceptionMessage"
155                 }
156                 $pagingFilesValues += "$fullPath $initialSize $maximumSize"
157                 try {
158                     Set-ItemProperty -LiteralPath "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name "PagingFiles" -Value $pagingFilesValues
159                 } catch {
160                     Fail-Json $result "Failed to set pagefile settings to the registry for workaround $($_.Exception.Message) Original exception: $originalExceptionMessage"
161                 }
162             }
163             $result.changed = $true
164         }
165     }
166 } elseif ($state -eq "query") {
167     $result.pagefiles = @()
168 
169     if ($null -eq $drive) {
170         try {
171             $pagefiles = Get-CIMInstance Win32_PageFileSetting
172         } catch {
173             Fail-Json $result "Failed to query all pagefiles $($_.Exception.Message)"
174         }
175     } else {
176         try {
177             $pagefiles = Get-Pagefile $fullPath
178         } catch {
179             Fail-Json $result "Failed to query specific pagefile $($_.Exception.Message)"
180         }
181     }
182 
183     # Get all pagefiles
184     foreach ($currentPagefile in $pagefiles) {
185         $currentPagefileObject = @{
186             name = $currentPagefile.Name
187             initial_size = $currentPagefile.InitialSize
188             maximum_size = $currentPagefile.MaximumSize
189             caption = $currentPagefile.Caption
190             description = $currentPagefile.Description
191         }
192         $result.pagefiles += ,$currentPagefileObject
193     }
194 
195     # Get automatic managed pagefile state
196     try {
197         $result.automatic_managed_pagefiles = (Get-CIMInstance -Class win32_computersystem).AutomaticManagedPagefile
198     } catch {
199         Fail-Json $result "Failed to query automatic managed pagefile state $($_.Exception.Message)"
200     }
201 }
202 Exit-Json $result
203