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