PowerShell脚本运行后Diskpart中断驱动器号

我构build了一个使用Diskpart挂载(附加)VHD的脚本,清除了一些系统文件,然后卸载(分离)它。 它使用一个foreach循环,并假设使用相同的驱动器号来清理多个VHD。 但是,在第一个VHD失败之后。 我还注意到,当我尝试手动附加一个带有diskpart的VHD时,diskpart成功,磁盘pipe理器显示正确的驱动器盘符,但在同一个PoSH实例中,我无法连接(设置位置)该驱动器。 如果我在第一次打开PoSH的时候做了一个手动的磁盘分区,那么在这个实例中,我可以附加和分离所有我想要的,并且每次都得到驱动器盘符,但是当我运行脚本的时候,使用。 有什么我需要做的重置脚本中的diskpart? 这是我正在使用的脚本的一个片段。

$test="" $Test2="" $MsgBoxObj = New-Object -ComObject wscript.shell $all = @() $obj = New-Object System.Collections.ArrayList $hash = @{} function Mount-VHD { [CmdletBinding()] param ( [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$false)] [string]$Path, [Parameter(Position=1,Mandatory=$false,ValueFromPipeline=$false)] [string]$DL, [string]$DiskpartScript = "$env:SystemDrive\DiskpartScript.txt", [switch]$Rescan ) begin { function InvokeDiskpart { Diskpart.exe /s $DiskpartScript } ## Validate Operating System Version ## if (Get-WmiObject win32_OperatingSystem -Filter "Version < '6.1'") {throw "The script operation requires at least Windows 7 or Windows Server 2008 R2."} } process{ ## Diskpart Script Content ## Here-String statement purposefully not indented ## @" $(if ($Rescan) {'Rescan'}) Select VDisk File="$Path" `nAttach VDisk Exit "@ | Out-File -FilePath $DiskpartScript -Encoding ASCII -Force InvokeDiskpart Start-Sleep -Seconds 3 @" Select VDisk File="$Path"`nSelect partition 1 `nAssign Letter="$DL" Exit "@ | Out-File -FilePath $DiskpartScript -Encoding ASCII -Force InvokeDiskpart } end { Remove-Item -Path $DiskpartScript -Force ; "" Write-Host "The VHD ""$Path"" has been successfully mounted." ; "" } } function Dismount-VHD { [CmdletBinding()] param ( [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$false)] [string]$Path, [switch]$Remove, [switch]$NoConfirm, [string]$DiskpartScript = "$env:SystemDrive\DiskpartScript.txt", [switch]$Rescan ) begin { function InvokeDiskpart { Diskpart.exe /s $DiskpartScript } function RemoveVHD { switch ($NoConfirm) { $false { ## Prompt for confirmation to delete the VHD file ## "" ; Write-Warning "Are you sure you want to delete the file ""$Path""?" $Prompt = Read-Host "Type ""YES"" to continue or anything else to break" if ($Prompt -ceq 'YES') { Remove-Item -Path $Path -Force "" ; Write-Host "VHD ""$Path"" deleted!" ; "" } else { "" ; Write-Host "Script terminated without deleting the VHD file." ; "" } } $true { ## Confirmation prompt suppressed ## Remove-Item -Path $Path -Force "" ; Write-Host "VHD ""$Path"" deleted!" ; "" } } } ## Validate Operating System Version ## if (Get-WmiObject win32_OperatingSystem -Filter "Version < '6.1'") {throw "The script operation requires at least Windows 7 or Windows Server 2008 R2."} } process{ ## DiskPart Script Content ## Here-String statement purposefully not indented ## @" $(if ($Rescan) {'Rescan'}) Select VDisk File="$Path"`nDetach VDisk Exit "@ | Out-File -FilePath $DiskpartScript -Encoding ASCII -Force InvokeDiskpart [gc]::collect() Start-Sleep -Seconds 15 reg unload hklm\DesktopVM reg unload hklm\DesktopSoft } end { if ($Remove) {RemoveVHD} Remove-Item -Path $DiskpartScript -Force ; "" } } Function mount-it {param($source, $privatename) #Import-Module "F:\Scripts\LJ_Cleanup\mount.psm1" # Script to use a mounted VHD to clean off the LJ service footprint $error.clear() set-location I: $Test=$? If ($test -ne $true){ [System.Windows.Forms.Application]::DoEvents() $localtest=hostname $localname=$source.substring(2,15) if ($localtest -ne $localname) { net use N: $source $script:mountpoint="N:\$privatename" } else { $split1 = $source.split("/$") $split2 = $source.split("$") $locallocation = $split1[3] + ":" + $split2[1] $script:mountpoint="$locallocation\$privatename" } Mount-VHD $mountpoint I $error.clear() set-location "I:\Windows" $Test=$? If ($test -eq $true){ write-host "**Disk Mount Successful**" Return $mountpoint [System.Windows.Forms.Application]::DoEvents() } else { write-host "**ALERT: The Disk mounted has no bootable partition. Please close application and check the Image.**" Dismount-VHD $mountpoint if ($mountpoint.substring(0,1) -eq "N") { net use N: /delete } Set-Location F: $Script:Cancelit=1 Return $Cancelit } } else { Write-host "**ALERT: There was a problem Mounting the vDisk. Please close application and check the Disk Manager on the server to ensure the I: drive is available.**" $Script:Cancelit=1 Return $Cancelit } }#End Function Function mount-Continue{param($location, $Disk, $server1) #Import-Module "F:\Scripts\LJ_Cleanup\mount.psm1" # Script to use a mounted VHD to clean off the AppV service footprint $error.clear() set-location I: $Test=$? If ($test -ne $true){ net use /persistent:no #net use * /d write-host "Mounting VHD from $destination" $localtest=hostname if ($localtest -ne $server1) { net use N: $location $Script:MC = "N:\$Disk" } else { $Script:MC = "F:\vdisks\$disk" } Mount-VHD $MC I $error.clear() set-location "I:\Windows" $Test=$? If ($test -eq $true) { Write-host "**Disk Mount Successful**" Return $Disk } else { Write-host "**ALERT: The Disk mounted has no bootable partition. Manually clean image and click ok to continue.**" $MsgBoxObj.Popup('**ALERT: The Disk mounted has no bootable partition. Manually clean image and click ok to continue.**') Return $Disk } } else { write-host "**ALERT: There was a problem Mounting the vDisk. Manually clean image and click ok to continue.**" $MsgBoxObj.Popup('**ALERT: The Disk mounted has no bootable partition. Manually clean image and click ok to continue.**') Return $Disk } }#End Function Function Dismount-it{ param ($Disk) set-location F: Dismount-VHD $disk if ($Disk.substring(0,1) -eq "N") { net use N: /delete } $error.clear() set-location "I:\Windows" $Test=$? If ($test -ne $true) { Write-host " **Disk Successful Unmounted**" return } else { Write-host "**ALERT: There was a problem unmounting the vDisk. Please close application and troubleshoot.**" $Script:Cancelit=1 Return $Cancelit } }#End Function Function Dismount-Continue{ set-location F: Dismount-VHD $MC if ($MC.substring(0,1) -eq "N") { net use N: /delete } $error.clear() set-location "I:\Windows" $Test=$? If ($test -ne $true){ Write-host " `r**Disk Successful Unmounted**" return } else { Write-host "**ALERT: There was a problem unmounting the vDisk. Manually clean image and click ok to continue.**" $MsgBoxObj.Popup('**ALERT: There was a problem unmounting the vDisk. Manually clean image and click ok to continue.**') Return $Disk } }#End Function Mount-it "\\server1pvs1\g$\vdisks" "image - private.vhd" dir Dismount-it $mountpoint dir Mount-it "\\server1pvs1\g$\vdisks" "image - private.vhd" dir Dismount-it $mountpoint 

更新:新的psdrive不允许你挂载一个VHD(或至less我还没有find一种方法)。 我发现的是我上面描述的问题源于使用testingpath。 不要相信我,试试这个:打开一个powershell会话并挂载你的vhd(使用gui或者diskpart),它们运行一个'test-path I:\'(或者其他任何作为驱动器盘符出现的) “真”(这是你想要的)。 我卸下磁盘并再次运行'test-path I:\'并得到“false”。 还是很好的反馈。 我再次安装磁盘(或另一个磁盘)并运行“testingpath我:\”它回来为“假”(应为“真”),您不能导航到PowerShell实例内的驱动器号。 如果我打开一个新的会议,我可以导航到我:很好。

这里有很多东西在玩。 最重要的是,Powershell不会像Windows资源pipe理器那样运行在同一个环境中 – 所以它不知道在那里连接的驱动器,反之亦然。

其次,摆脱diskpart并使用Powershell自己的设施。 看看“新PSDrive”( http://technet.microsoft.com/en-us/library/hh849829.aspx )的一个开始。

第三,这些操作可能是asynchronous的,并且可能会让脚本等待一段时间,直到驱动器号被删除/连接。 (不会手动发生,因为与脚本执行相比,速度足够慢)。