首页 > 解决方案 > 在通过 GUI [powershell] 访问之前无法访问卷影复制

问题描述

我正在编写一个简单的 powershell 脚本,它将自动从 Windows 文件服务器到另一个远程 Windows 服务器的异地备份。文件可能正在使用中,因此为了让 Robocopy 成功复制它们,我需要从该特定驱动器的最后一个可用卷影副本中复制文件。

我可以用 Powershell 找到最后一个 Shadow Copy 就好了;问题是我实际上无法“引用”它(挂载它)以访问卷影副本上的文件。

但是,如果我首先通过 Windows 资源管理器 GUI访问 Shadow Copy 的内容,这种“神奇”的变化

然后突然之间,我可以很好地访问卷影副本并将内容复制到远程备份服务器。

这是有问题的代码:

#Find the latest Shadow copy
$HDDriveID = (Get-WmiObject win32_volume -filter "DriveLetter='E:'").DeviceID
$LastShadowCopy = Get-WmiObject win32_shadowcopy | Where-Object {$_.VolumeName -eq $HDDriveID} | Sort-Object InstallDate | Select-Object -Last 1

# And parse the path so that we can mount it
$arr = $LastShadowCopy.InstallDate.Split('+').Split('.')
$VolumeShadowCopytime = [DateTime]::ParseExact($arr[0], 'yyyyMMddHHmmss', $null)
$UTCTime = $VolumeShadowCopytime.AddHours(-[int]$arr[2]/60)
$VolumeShadowCopyPath = "\\127.0.0.1\E$\@GMT-" + (Get-Date $UTCTime).ToString("yyyy.MM.dd-HH.mm.ss") + "\"

# Then, let's actually mount it:
New-PSDrive -Name Y -PSProvider FileSystem -Root $VolumeShadowCopyPath

如果我在不通过 GUI 访问最后一个卷影副本的情况下运行脚本的这一部分,我会收到以下错误:

New-PSDrive : The specified drive root "\\127.0.0.1\E$\@GMT-2018.06.27-05.00.09\" either does not exist, or it is not a folder.
At [scriptlocation]\BackupToAzureDrive.ps1:21 char:1
+ New-PSDrive -Name Y -PSProvider FileSystem -Root $VolumeShadowCopyPat ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ReadError: (Y:PSDriveInfo) [New-PSDrive], IOException
    + FullyQualifiedErrorId : DriveRootError,Microsoft.PowerShell.Commands.NewPSDriveCommand

同样,当我通过 Windows 资源管理器打开卷影副本时(显然?)Windows 正确引用了它,我就不会收到此类错误。卷影复制安装没有任何问题,我可以访问文件和文件夹。

我不是 Powershell 专家,也不是很热衷于它。我被这个问题困扰了好几天了。有谁知道如何解决这个问题和/或知道解决方法?

标签: powershellwindows-server-2012-r2volume-shadow-service

解决方案


在这里查看这个 stackoverflow 问题后,我得到了答案。我之前遇到过这个答案,但我驳回了它,因为它建议使用mklink来“映射”一个 VS Copy 而不是原生的New-PSDrive。事实上,我浏览答案太快了,错过了重要的建议。我的错。感谢第一次回答的人,Ansgar Wiechers

无论如何,似乎引用影子副本的正确方法是首先选择所需的影子副本,然后访问DeviceObject属性。这样,映射特定影子副本所需的代码减少到三行(是的,它很可能会进一步减少(并转换为 CIM 而不是 WMI)):

#Find the latest Shadow copy
$HDDriveID = (Get-WmiObject win32_volume -filter "DriveLetter='E:'").DeviceID
$LastShadowCopy = Get-WmiObject win32_shadowcopy | Where-Object {$_.VolumeName -eq $HDDriveID} | Sort-Object InstallDate | Select-Object -Last 1
# Then mount it:
New-PSDrive -Name Y -PSProvider FileSystem -Root ($LastShadowCopy.DeviceObject + "\")

完美运行。同样,行为与以前一致:一旦我使用上面的代码引用(并映射到驱动器号)特定的卷影副本,我可以再次使用“\127.0.0.1\E$\@GMT-2018.06.27-05.00. 09\" . 无论如何,这并不重要,因为一旦我将卷影副本映射到驱动器号,我显然可以通过该驱动器号访问内容。

无论如何,我对解决方案感到满意。尽管已经提出并回答了这个问题,但我认为如果我不只是链接到现有问题,它可能会对遇到同样问题的人有所帮助。


推荐阅读