我正在编写一个简单的Powershell脚本,该脚本可以自动从Windows文件服务器到另一个远程Windows服务器的异地备份。文件可能正在使用中,因此为了让 Robocopy 成功复制它们,我需要从该特定驱动器的最后一个可用卷影副本中复制文件。
我可以用Powershell找到最后一个卷影副本;问题是我实际上无法"引用"它(挂载它(以访问卷影副本上的文件。
但是,如果我首先通过Windows资源管理器GUI访问卷影副本的内容,则"神奇地"会发生变化
然后突然之间,我可以很好地访问卷影副本并将内容复制到远程备份服务器。
这是有问题的代码:
#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.1E$@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.1E$@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大师,也不是很热衷于它。我已经被这个问题困住了好几天了。有没有人知道如何解决这个问题和/或知道解决方法?
在这里看到这个堆栈溢出问题后,我得到了答案。我之前遇到过这个答案,但我驳回了它,因为它建议使用mklink来"映射"VS 副本,而不是本机New-PSDrive。事实上,我太快地浏览了答案,错过了关键的建议。我的坏。向第一次回答这个问题的人致敬,安斯加尔·维彻斯。
无论如何,引用卷影副本的正确方法是首先选择所需的卷影副本,然后访问设备对象属性。这样,映射特定卷影副本所需的代码减少到三行(是的,它很可能可以进一步减少(并转换为 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\">的形式。无论如何,这并不重要,因为一旦我将卷影副本映射到驱动器号,我显然可以通过此驱动器号访问内容。
无论如何,我对解决方案感到满意。尽管已经提出并回答了该问题,但我认为如果我不只是链接到现有问题,它可能会帮助遇到相同问题的人。