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 Win32_ShadowCopy | ForEach-Object { $_.DeviceObject }
24
+ }
25
+
26
+ function Mount-VolumeShadowCopy
27
+ {
28
+ <#
29
+ . SYNOPSIS
30
+
31
+ Mounts a volume shadow copy.
32
+
33
+ PowerSploit Function: Mount-VolumeShadowCopy
34
+ Author: Matthew Graeber (@mattifestation)
35
+ License: BSD 3-Clause
36
+ Required Dependencies: None
37
+ Optional Dependencies: None
38
+ Version: 2.0.0
39
+
40
+ . DESCRIPTION
41
+
42
+ Mount-VolumeShadowCopy mounts a volume shadow copy volume by creating a symbolic link.
43
+
44
+ . PARAMETER Path
45
+
46
+ Specifies the path to which the symbolic link for the mounted volume shadow copy will be saved.
47
+
48
+ . PARAMETER DevicePath
49
+
50
+ Specifies the volume shadow copy 'DeviceObject' path. This path can be retrieved with the Get-VolumeShadowCopy PowerSploit function or with the Win32_ShadowCopy object.
51
+
52
+ . EXAMPLE
53
+
54
+ Get-VolumeShadowCopy | Mount-VolumeShadowCopy -Path C:\VSS
55
+
56
+ Description
57
+ -----------
58
+ Create a mount point in 'C:\VSS' for each volume shadow copy volume
59
+
60
+ . EXAMPLE
61
+
62
+ Mount-VolumeShadowCopy -Path C:\VSS -DevicePath '\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy4'
63
+
64
+ . EXAMPLE
65
+
66
+ Get-WmiObject Win32_ShadowCopy | % { $_.DeviceObject -Path C:\VSS -DevicePath $_ }
67
+ #>
68
+
69
+ Param (
70
+ [Parameter (Mandatory = $True )]
71
+ [ValidateNotNullOrEmpty ()]
72
+ [String ]
73
+ $Path ,
74
+
75
+ [Parameter (Mandatory = $True , ValueFromPipeline = $True )]
76
+ [ValidatePattern (' ^\\\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy[0-9]{1,3}$' )]
77
+ [String []]
78
+ $DevicePath
79
+ )
80
+
81
+ BEGIN
82
+ {
83
+ $UserIdentity = ([Security.Principal.WindowsPrincipal ][Security.Principal.WindowsIdentity ]::GetCurrent())
84
+
85
+ if (-not $UserIdentity.IsInRole ([Security.Principal.WindowsBuiltInRole ]' Administrator' ))
86
+ {
87
+ Throw ' You must run Get-VolumeShadowCopy from an elevated command prompt.'
88
+ }
89
+
90
+ # Validate that the path exists before proceeding
91
+ Get-ChildItem $Path - ErrorAction Stop | Out-Null
92
+
93
+ $DynAssembly = New-Object System.Reflection.AssemblyName(' VSSUtil' )
94
+ $AssemblyBuilder = [AppDomain ]::CurrentDomain.DefineDynamicAssembly($DynAssembly , [Reflection.Emit.AssemblyBuilderAccess ]::Run)
95
+ $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule (' VSSUtil' , $False )
96
+
97
+ # Define [VSS.Kernel32]::CreateSymbolicLink method using reflection
98
+ # (i.e. none of the forensic artifacts left with using Add-Type)
99
+ $TypeBuilder = $ModuleBuilder.DefineType (' VSS.Kernel32' , ' Public, Class' )
100
+ $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod (' CreateSymbolicLink' ,
101
+ ' kernel32.dll' ,
102
+ ([Reflection.MethodAttributes ]::Public -bor [Reflection.MethodAttributes ]::Static ),
103
+ [Reflection.CallingConventions ]::Standard,
104
+ [Bool ],
105
+ [Type []]@ ([String ], [String ], [UInt32 ]),
106
+ [Runtime.InteropServices.CallingConvention ]::Winapi,
107
+ [Runtime.InteropServices.CharSet ]::Auto)
108
+ $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute ].GetConstructor(@ ([String ]))
109
+ $SetLastError = [Runtime.InteropServices.DllImportAttribute ].GetField(' SetLastError' )
110
+ $SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor ,
111
+ @ (' kernel32.dll' ),
112
+ [Reflection.FieldInfo []]@ ($SetLastError ),
113
+ @ ($true ))
114
+ $PInvokeMethod.SetCustomAttribute ($SetLastErrorCustomAttribute )
115
+
116
+ $Kernel32Type = $TypeBuilder.CreateType ()
117
+ }
118
+
119
+ PROCESS
120
+ {
121
+ foreach ($Volume in $DevicePath )
122
+ {
123
+ $Volume -match ' ^\\\\\?\\GLOBALROOT\\Device\\(?<LinkName>HarddiskVolumeShadowCopy[0-9]{1,3})$' | Out-Null
124
+
125
+ $LinkPath = Join-Path $Path $Matches.LinkName
126
+
127
+ if (Test-Path $LinkPath )
128
+ {
129
+ Write-Warning " '$LinkPath ' already exists."
130
+ continue
131
+ }
132
+
133
+ if (-not $Kernel32Type ::CreateSymbolicLink($LinkPath , " $ ( $Volume ) \" , 1 ))
134
+ {
135
+ Write-Error " Symbolic link creation failed for '$Volume '."
136
+ continue
137
+ }
138
+
139
+ Get-Item $LinkPath
140
+ }
141
+ }
142
+
143
+ END
144
+ {
145
+
146
+ }
147
+ }
0 commit comments