1
- function Get-VolumeShadowCopy
2
- {
3
- <#
4
- . SYNOPSIS
5
-
6
- Lists the device paths of all local volume shadow copies.
7
-
8
- PowerSploit Function: Get-VolumeShadowCopy
9
- Author: Matthew Graeber (@mattifestation)
10
- License: BSD 3-Clause
11
- Required Dependencies: None
12
- Optional Dependencies: None
13
- Version: 2.0.0
14
- #>
15
-
16
- $UserIdentity = ([Security.Principal.WindowsPrincipal ][Security.Principal.WindowsIdentity ]::GetCurrent())
17
-
18
- if (-not $UserIdentity.IsInRole ([Security.Principal.WindowsBuiltInRole ]' Administrator' ))
19
- {
20
- Throw ' You must run Get-VolumeShadowCopy from an elevated command prompt.'
21
- }
22
-
23
- Get-WmiObject - Namespace root\cimv2 - Class Win32_ShadowCopy | ForEach-Object { $_.DeviceObject }
24
- }
25
-
26
- function New-VolumeShadowCopy
27
- {
28
- <#
29
- . SYNOPSIS
30
-
31
- Creates a new volume shadow copy.
32
-
33
- PowerSploit Function: New-VolumeShadowCopy
34
- Author: Jared Atkinson (@jaredcatkinson)
35
- License: BSD 3-Clause
36
- Required Dependencies: None
37
- Optional Dependencies: None
38
- Version: 2.0.0
39
-
40
- . DESCRIPTION
41
-
42
- New-VolumeShadowCopy creates a volume shadow copy for the specified volume.
43
-
44
- . PARAMETER Volume
45
-
46
- Volume used for the shadow copy. This volume is sometimes referred to as the original volume.
47
- The Volume parameter can be specified as a volume drive letter, mount point, or volume globally unique identifier (GUID) name.
48
-
49
- . PARAMETER Context
50
-
51
- Context that the provider uses when creating the shadow. The default is "ClientAccessible".
52
-
53
- . EXAMPLE
54
-
55
- New-VolumeShadowCopy -Volume C:\
56
-
57
- Description
58
- -----------
59
- Creates a new VolumeShadowCopy of the C drive
60
- #>
61
- Param (
62
- [Parameter (Mandatory = $True )]
63
- [ValidatePattern (' ^\w:\\' )]
64
- [String ]
65
- $Volume ,
66
-
67
- [Parameter (Mandatory = $False )]
68
- [ValidateSet (" ClientAccessible" )]
69
- [String ]
70
- $Context = " ClientAccessible"
71
- )
72
-
73
- $UserIdentity = ([Security.Principal.WindowsPrincipal ][Security.Principal.WindowsIdentity ]::GetCurrent())
74
-
75
- if (-not $UserIdentity.IsInRole ([Security.Principal.WindowsBuiltInRole ]' Administrator' ))
76
- {
77
- Throw ' You must run Get-VolumeShadowCopy from an elevated command prompt.'
78
- }
79
-
80
- # Save VSS Service initial state
81
- $running = (Get-Service - Name VSS).Status
82
-
83
- $class = [WMICLASS ]" root\cimv2:win32_shadowcopy"
84
-
85
- $return = $class.create (" $Volume " , " $Context " )
86
-
87
- switch ($return.returnvalue )
88
- {
89
- 1 {Write-Error " Access denied." ; break }
90
- 2 {Write-Error " Invalid argument." ; break }
91
- 3 {Write-Error " Specified volume not found." ; break }
92
- 4 {Write-Error " Specified volume not supported." ; break }
93
- 5 {Write-Error " Unsupported shadow copy context." ; break }
94
- 6 {Write-Error " Insufficient storage." ; break }
95
- 7 {Write-Error " Volume is in use." ; break }
96
- 8 {Write-Error " Maximum number of shadow copies reached." ; break }
97
- 9 {Write-Error " Another shadow copy operation is already in progress." ; break }
98
- 10 {Write-Error " Shadow copy provider vetoed the operation." ; break }
99
- 11 {Write-Error " Shadow copy provider not registered." ; break }
100
- 12 {Write-Error " Shadow copy provider failure." ; break }
101
- 13 {Write-Error " Unknown error." ; break }
102
- default {break }
103
- }
104
-
105
- # If VSS Service was Stopped at the start, return VSS to "Stopped" state
106
- if ($running -eq " Stopped" )
107
- {
108
- Stop-Service - Name VSS
109
- }
110
- }
111
-
112
- function Remove-VolumeShadowCopy
113
- {
114
- <#
115
- . SYNOPSIS
116
-
117
- Deletes a volume shadow copy.
118
-
119
- PowerSploit Function: Remove-VolumeShadowCopy
120
- Author: Jared Atkinson (@jaredcatkinson)
121
- License: BSD 3-Clause
122
- Required Dependencies: None
123
- Optional Dependencies: None
124
- Version: 2.0.0
125
-
126
- . DESCRIPTION
127
-
128
- Remove-VolumeShadowCopy deletes a volume shadow copy from the system.
129
-
130
- . PARAMETER InputObject
131
-
132
- Specifies the Win32_ShadowCopy object to remove
133
-
134
- . PARAMETER DevicePath
135
-
136
- Specifies the volume shadow copy 'DeviceObject' path. This path can be retrieved with the Get-VolumeShadowCopy PowerSploit function or with the Win32_ShadowCopy object.
137
-
138
- . EXAMPLE
139
-
140
- Get-VolumeShadowCopy | Remove-VolumeShadowCopy
141
-
142
- Description
143
- -----------
144
- Removes all volume shadow copy
145
-
146
- . EXAMPLE
147
-
148
- Remove-VolumeShadowCopy -DevicePath '\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy4'
149
-
150
- Description
151
- -----------
152
- Removes the volume shadow copy at the 'DeviceObject' path \\?\GLOBALROOT\DeviceHarddiskVolumeShadowCopy4
153
- #>
154
- [CmdletBinding (SupportsShouldProcess = $True )]
155
- Param (
156
- [Parameter (Mandatory = $True , ValueFromPipeline = $True )]
157
- [ValidatePattern (' ^\\\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy[0-9]{1,3}$' )]
158
- [String ]
159
- $DevicePath
160
- )
161
-
162
- PROCESS
163
- {
164
- if ($PSCmdlet.ShouldProcess (" The VolumeShadowCopy at DevicePath $DevicePath will be removed" ))
165
- {
166
- (Get-WmiObject - Namespace root\cimv2 - Class Win32_ShadowCopy | Where-Object {$_.DeviceObject -eq $DevicePath }).Delete()
167
- }
168
- }
169
- }
170
-
171
- function Mount-VolumeShadowCopy
172
- {
173
- <#
174
- . SYNOPSIS
175
-
176
- Mounts a volume shadow copy.
177
-
178
- PowerSploit Function: Mount-VolumeShadowCopy
179
- Author: Matthew Graeber (@mattifestation)
180
- License: BSD 3-Clause
181
- Required Dependencies: None
182
- Optional Dependencies: None
183
- Version: 2.0.0
184
-
185
- . DESCRIPTION
186
-
187
- Mount-VolumeShadowCopy mounts a volume shadow copy volume by creating a symbolic link.
188
-
189
- . PARAMETER Path
190
-
191
- Specifies the path to which the symbolic link for the mounted volume shadow copy will be saved.
192
-
193
- . PARAMETER DevicePath
194
-
195
- Specifies the volume shadow copy 'DeviceObject' path. This path can be retrieved with the Get-VolumeShadowCopy PowerSploit function or with the Win32_ShadowCopy object.
196
-
197
- . EXAMPLE
198
-
199
- Get-VolumeShadowCopy | Mount-VolumeShadowCopy -Path C:\VSS
200
-
201
- Description
202
- -----------
203
- Create a mount point in 'C:\VSS' for each volume shadow copy volume
204
-
205
- . EXAMPLE
206
-
207
- Mount-VolumeShadowCopy -Path C:\VSS -DevicePath '\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy4'
208
-
209
- . EXAMPLE
210
-
211
- Get-WmiObject Win32_ShadowCopy | % { $_.DeviceObject -Path C:\VSS -DevicePath $_ }
212
- #>
213
-
214
- Param (
215
- [Parameter (Mandatory = $True )]
216
- [ValidateNotNullOrEmpty ()]
217
- [String ]
218
- $Path ,
219
-
220
- [Parameter (Mandatory = $True , ValueFromPipeline = $True )]
221
- [ValidatePattern (' ^\\\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy[0-9]{1,3}$' )]
222
- [String []]
223
- $DevicePath
224
- )
225
-
226
- BEGIN
227
- {
228
- $UserIdentity = ([Security.Principal.WindowsPrincipal ][Security.Principal.WindowsIdentity ]::GetCurrent())
229
-
230
- if (-not $UserIdentity.IsInRole ([Security.Principal.WindowsBuiltInRole ]' Administrator' ))
231
- {
232
- Throw ' You must run Get-VolumeShadowCopy from an elevated command prompt.'
233
- }
234
-
235
- # Validate that the path exists before proceeding
236
- Get-ChildItem $Path - ErrorAction Stop | Out-Null
237
-
238
- $DynAssembly = New-Object System.Reflection.AssemblyName(' VSSUtil' )
239
- $AssemblyBuilder = [AppDomain ]::CurrentDomain.DefineDynamicAssembly($DynAssembly , [Reflection.Emit.AssemblyBuilderAccess ]::Run)
240
- $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule (' VSSUtil' , $False )
241
-
242
- # Define [VSS.Kernel32]::CreateSymbolicLink method using reflection
243
- # (i.e. none of the forensic artifacts left with using Add-Type)
244
- $TypeBuilder = $ModuleBuilder.DefineType (' VSS.Kernel32' , ' Public, Class' )
245
- $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod (' CreateSymbolicLink' ,
246
- ' kernel32.dll' ,
247
- ([Reflection.MethodAttributes ]::Public -bor [Reflection.MethodAttributes ]::Static ),
248
- [Reflection.CallingConventions ]::Standard,
249
- [Bool ],
250
- [Type []]@ ([String ], [String ], [UInt32 ]),
251
- [Runtime.InteropServices.CallingConvention ]::Winapi,
252
- [Runtime.InteropServices.CharSet ]::Auto)
253
- $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute ].GetConstructor(@ ([String ]))
254
- $SetLastError = [Runtime.InteropServices.DllImportAttribute ].GetField(' SetLastError' )
255
- $SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor ,
256
- @ (' kernel32.dll' ),
257
- [Reflection.FieldInfo []]@ ($SetLastError ),
258
- @ ($true ))
259
- $PInvokeMethod.SetCustomAttribute ($SetLastErrorCustomAttribute )
260
-
261
- $Kernel32Type = $TypeBuilder.CreateType ()
262
- }
263
-
264
- PROCESS
265
- {
266
- foreach ($Volume in $DevicePath )
267
- {
268
- $Volume -match ' ^\\\\\?\\GLOBALROOT\\Device\\(?<LinkName>HarddiskVolumeShadowCopy[0-9]{1,3})$' | Out-Null
269
-
270
- $LinkPath = Join-Path $Path $Matches.LinkName
271
-
272
- if (Test-Path $LinkPath )
273
- {
274
- Write-Warning " '$LinkPath ' already exists."
275
- continue
276
- }
277
-
278
- if (-not $Kernel32Type ::CreateSymbolicLink($LinkPath , " $ ( $Volume ) \" , 1 ))
279
- {
280
- Write-Error " Symbolic link creation failed for '$Volume '."
281
- continue
282
- }
283
-
284
- Get-Item $LinkPath
285
- }
286
- }
287
-
288
- END
289
- {
290
-
291
- }
292
- }
0 commit comments