我正在尝试使用Windows 7中的Windows Power Shell创建和访问卷影复制快照。我发现我可以通过之前的superuser question使用以下内容创建快照:
(Get-WmiObject -list win32_shadowcopy).create("C:\","ClientAccessible")
我无法找到任何文档,表明可以将卷影副本设置为“Exposed”,以便可以使用WMI
将其映射到驱动器号。在同一问题中链接的article显示使用联结访问快照的黑客攻击。
当我尝试访问符号链接时,我得到以下内容:
PS C:\Windows\system32> ls C:\shadowcopy
Get-ChildItem : The parameter is incorrect.
At line:1 char:3
+ ls <<<< C:\shadowcopy
+ CategoryInfo : ReadError: (C:\shadowcopy:String) [Get-ChildItem], IOException
+ FullyQualifiedErrorId : DirIOError,Microsoft.PowerShell.Commands.GetChildItemCommand
尝试直接访问快照提供以下内容:
PS C:\Windows\system32> ls '\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy14'
Get-ChildItem : Paths that begin with \\?\GlobalRoot are internal to the kernel and should not be opened by managed applications.
At line:1 char:3
+ ls <<<< '\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy14'
+ CategoryInfo : NotSpecified: (:) [Get-ChildItem], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.GetChildItemCommand
如何从powershell脚本访问VSS快照?
答案 0 :(得分:25)
你是如何创建符号链接的?如该文章所述,您必须使用尾部反斜杠指定设备路径:
$s1 = (Get-WmiObject -List Win32_ShadowCopy).Create("C:\", "ClientAccessible")
$s2 = Get-WmiObject Win32_ShadowCopy | Where-Object { $_.ID -eq $s1.ShadowID }
$d = $s2.DeviceObject + "\" # <-- this here
cmd /c mklink /d C:\shadowcopy "$d"
在此之后,我能够访问挂载到C:\shadowcopy
的卷影副本。
要卸载卷影副本调用$s2.Delete()
,正如@KeyszerS在评论中指出的那样。
答案 1 :(得分:2)
因此,使用此处提供的信息和此处https://docs.microsoft.com/en-us/previous-versions/windows/desktop/vsswmi/create-method-in-class-win32-shadowcopy的官方Microsoft文档,我创建了一些解决此问题的powershell函数/ cmdlet。随机说明,从powershell 5开始,新项目具有symbolicLink的itemType,但是当我尝试将目标作为影子快照进行创建时,它失败了,提示该路径不存在,因此mklink工具仍然是要解决的问题。
function New-ShadowLink {
[CmdletBinding()]
param (
$linkPath="$($ENV:SystemDrive)\ShadowCopy"
)
begin {
Write-Verbose "Creating a snapshot of $($ENV:SystemDrive)\"
$class=[WMICLASS]"root\cimv2:win32_shadowcopy";
$result = $class.create("$ENV:SystemDrive\", "ClientAccessible");
Write-Verbose "Getting the full target path for a symlink to the shadow snapshot"
$shadow = Get-CimInstance -ClassName Win32_ShadowCopy | Where-Object ID -eq $result.ShadowID
$target = "$($shadow.DeviceObject)\";
}
process {
Write-Verbose "Creating SymLink to shadowcopy at $linkPath"
Invoke-Expression -Command "cmd /c mklink /d '$linkPath' '$target'";
}
end {
Write-Verbose "Created link to shadowcopy snapshot of $($ENV:SystemDrive)\ at $linkPath";
Write-Verbose "Returning shadowcopy snapshot object"
return $shadow;
}
}
function Remove-ShadowLink {
[CmdletBinding()]
param (
$shadow,
$linkPath="$($ENV:SystemDrive)\ShadowCopy"
)
begin {
Write-verbose "Removing shadow copy link at $linkPath"
}
process {
Write-Verbose "Deleting the shadowcopy snapshot"
$shadow.Delete();
Write-Verbose "Deleting the now empty folder"
Try {
Remove-Item -Force -Recurse $linkPath -ErrorAction Stop;
}
catch {
Invoke-Expression -Command "cmd /c rmdir /S /Q '$linkPath'";
}
}
end {
Write-Verbose "Shadow link and snapshot have been removed";
return;
}
}
可以通过复制粘贴两个功能然后像这样运行它们来利用这些功能
$shadow = New-ShadowLink -Verbose;
ls C:\ShadowCopy # would show snapshot version of c drive
Remove-ShadowLink -shadow $shadow -Verbose;
ls C:\ShadowCopy # will give error as it doesn't exist
$s = New-ShadowLink -verbose
VERBOSE: Creating a snapshot of C:\
VERBOSE: Getting the full target path for a symlink to the shadow snapshot
VERBOSE: Creating SymLink to shadowcopy at C:\ShadowCopy
VERBOSE: Created link to shadowcopy snapshot of C:\ at C:\ShadowCopy
VERBOSE: Returning shadowcopy snapshot object
PS C:\> ls C:\ShadowCopy
Directory: C:\ShadowCopy
#ommitted my C drive listing, but it would be here
PS C:\> Remove-ShadowLink -shadow $s -Verbose
VERBOSE: Removing shadow copy link at C:\ShadowCopy
VERBOSE: Deleting the shadowcopy snapshot
VERBOSE: Deleting the now empty folder
VERBOSE: Shadow link and snapshot have been removed
PS C:\> ls C:\ShadowCopy
ls : Cannot find path 'C:\ShadowCopy' because it does not exist.
答案 2 :(得分:0)
这是因为Invoke-Expression
中的New-ShadowLink
返回了一个字符串。如果您将该行修改为:
Invoke-Expression -Command "cmd /c mklink /d '$linkPath' '$target'" | Out-Null
它将解决问题。
答案 3 :(得分:0)
尝试将 $ shadow.Delete()替换为 Remove-CimInstance -InputObject $ shadow
这对我有用
在我遇到类似错误之前:
$ shadow.Delete()给我错误:
错误提示方法[Microsoft.Management.Infrastructure.CimInstance]没有子程序 宁末梅托多·拉马多(Dénéte)。 英文名称:42Carácter:9 + $ shadow.Delete(); + ~~~~~~~~~~~~~~~~ + CategoryInfo:InvalidOperation:(Delete:String)[],RuntimeException + FullyQualifiedErrorId:MethodNotFound