powershell - 在通过 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 专家,也不是很热衷于它。我被这个问题困扰了好几天了。有谁知道如何解决这个问题和/或知道解决方法?
解决方案
在这里查看这个 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\" . 无论如何,这并不重要,因为一旦我将卷影副本映射到驱动器号,我显然可以通过该驱动器号访问内容。
无论如何,我对解决方案感到满意。尽管已经提出并回答了这个问题,但我认为如果我不只是链接到现有问题,它可能会对遇到同样问题的人有所帮助。
推荐阅读
- python - Django ORM 使用哪些运算符来访问对象中的字段?
- python - 排除字符串列表中的相似度
- flutter - Flutter:从选项卡将一些字符串传递到特定选项卡并在选项卡栏中显示该特定选项卡
- apache-kafka - Header Kafka 中的相关 ID
- java - Spring with Thymeleaf - 在 UI 中显示角色数组
- android - 如何在android中使用多部分数据发送文件
- java - 如果同一类的对象相同
- sql - 删除 SQL Server 中特定特殊字符后的所有内容
- javascript - 反应原始与构建
- python - icon_url 不是不和谐机器人的有效语法