Does chkdsk /r for VHDs make sense?
-
Saturday, April 07, 2012 11:20 PM
Hello!
I had a RAID corruption on Hyper-V Server 2008 R2.
I'm going to mount several dynamically expanding VHDs on the host in order to run chkdsk against them.
Does it make any sense to run
chkdsk driveletter: /f /r /x
rather than
chkdsk driveletter: /f /x
since the physical sector condition is managed by the RAID controller and the Hyper-V host!?
Thank you!
L.
All Replies
-
Sunday, April 08, 2012 12:51 AM
Hi asklucas, since you mention you're going to mount several VHD's to the storage I suggest better to check within the VHD itself. Apart from that you can find more information from below mention article written by Ben Armstrong (http://blogs.msdn.com/b/virtual_pc_guy/archive/2009/01/07/how-do-i-fix-a-corrupted-virtual-hard-disk.aspx)
Thanks,
Susantha- Edited by susanthasilvaMVP Sunday, April 08, 2012 12:53 AM
- Proposed As Answer by Vincent HuModerator Monday, April 09, 2012 6:21 AM
-
Monday, April 09, 2012 6:24 AMModerator
Hi,You can run chkdsk.By the way, you can also check the following post.Vincent Hu
TechNet Community Support
- Marked As Answer by asklucas Tuesday, April 10, 2012 8:10 AM
-
Tuesday, April 10, 2012 8:12 AM
Thank you for your help!
It states:
<quote>I would recommend that you run a full fledged chkdsk /r on the disk in case corruption is found.
We can find corruption by running chkdsk <drive_letter> or check id the dirty bit is set using the command fsutil dirty query <drive_letter>.
In case corruption is detected, I would recommend running a chkdsk /r. Why i would recommend this is simple, if chkdsk finds some files in lost clusters, it would attempt to recover them and would put them in a folder titled found.xxx where xxx=001,002 etc.
</quote> -
Tuesday, April 10, 2012 8:22 AM
Thank you!
Virtual PC Guy doesn't explain , which chkdsk parameters to use, but it's a very interesting post!
I ended up running
chkdsk driveletter: /f /r /x
on the VHDs mounted in the parent partition.
I created a quick-and-dirty script for that purpose, it also defrags and compacts the VHDs.
Only use it for emergencies, as it's quick-and-dirty and relies on the diskpart list volume command to query (only the first!) drive letter of the attached disk.
' Hyper-V VHD Maintenance Script ' LPET ' 2012-04-09 Option Explicit Dim path_file_VHDs path_file_VHDs = Array( _ "D:\VHDs\firstdisk.vhd", _ "D:\VHDs\seconddisk.vhd", _ "D:\VHDs\thirddisk.vhd" _ ) Main Sub Main Dim path_file_VHD For Each path_file_VHD In path_file_VHDs WScript.Echo( "==============================================================================") WScript.Echo( "Processing VHD:") WScript.Echo( path_file_VHD) WScript.Echo( ISO_date( Now()) & " " & ISO_time( Now())) WScript.Echo( "------------------------------------------------------------------------------") Dim attached_drive_letter attached_drive_letter = attach_VHD( path_file_VHD) check_VHD( attached_drive_letter) defrag_VHD( attached_drive_letter) detach_VHD( path_file_VHD) compact_VHD( path_file_VHD) attached_drive_letter = "" Next End Sub Function attach_VHD( vhd_path) WScript.Echo( "attach_VHD( " & vhd_path & ")") Dim oShell Dim oScriptExec Dim oStdOut Dim oStdIn Dim strElement Dim sOut Dim sLine Set oShell = CreateObject( "WScript.Shell") Set oScriptExec = oShell.Exec( "diskpart") Set oStdOut = oScriptExec.StdOut Set oStdIn = oScriptExec.StdIn oStdIn.write vbCrLf WScript.Echo "select vdisk file=" & vhd_path oStdIn.write "select vdisk file=" & vhd_path & vbCrLf WScript.Echo "attach vdisk" oStdIn.write "attach vdisk" & vbCrLf WScript.Sleep( 15000) WScript.Echo "list volume" oStdIn.write "list volume" & vbCrLf WScript.Echo "exit" oStdIn.write "exit" & vbCrLf Do While Not oScriptExec.StdOut.AtEndOfStream sLine = oScriptExec.StdOut.ReadLine WScript.Echo sLine If InStr( sLine, "Volume 5 ") Then sOut = Trim( Right( Left( sLine, 18), 5)) & ":" End If Loop WScript.Echo sOut oStdIn.close() attach_VHD = sOut End Function Function check_VHD( drive_letter) WScript.Echo( "check_VHD( " & drive_letter & ")") Dim oShell Dim oScriptExec Dim command_line command_line = "chkdsk.exe " & drive_letter & " /f /r /x" Set oShell = CreateObject( "WScript.Shell") Set oScriptExec = oShell.Exec( command_line) Do While Not oScriptExec.StdOut.AtEndOfStream WScript.Echo( oScriptExec.StdOut.ReadLine) Loop End Function Function defrag_VHD( drive_letter) WScript.Echo( "defrag_VHD( " & drive_letter & ")") Dim oShell Dim oScriptExec Dim command_line command_line = "defrag.exe " & drive_letter & " /h /u /v" Set oShell = CreateObject( "WScript.Shell") Set oScriptExec = oShell.Exec( command_line) Do While Not oScriptExec.StdOut.AtEndOfStream WScript.Echo( oScriptExec.StdOut.ReadLine) Loop End Function Function detach_VHD( vhd_path) WScript.Echo( "detach_VHD( " & vhd_path & ")") Dim oShell Dim oScriptExec Dim oStdOut Dim oStdIn Dim strElement Dim sOut Dim sLine Set oShell = CreateObject( "WScript.Shell") Set oScriptExec = oShell.Exec( "diskpart") Set oStdOut = oScriptExec.StdOut Set oStdIn = oScriptExec.StdIn oStdIn.write vbCrLf WScript.Echo "select vdisk file=" & vhd_path oStdIn.write "select vdisk file=" & vhd_path & vbCrLf WScript.Echo "detach vdisk" oStdIn.write "detach vdisk" & vbCrLf WScript.Echo "exit" oStdIn.write "exit" & vbCrLf Do While Not oScriptExec.StdOut.AtEndOfStream sLine = oScriptExec.StdOut.ReadLine WScript.Echo sLine If instr( sLine, "successfully") Then sOut = sLine & vbCrLf End If Loop WScript.Echo sOut oStdIn.close() End Function Function compact_VHD( VHDName) WScript.Echo( "compact_VHD( " & VHDName & ")") Dim HyperVServer Dim Msvm_ImageManagementService Dim Result Dim Job Dim InParam Dim OutParam Dim WMI_Service 'Set Hyper-V Server as being local HyperVServer = "." 'Get an instance of the WMI Service in the virtualization namespace. Set WMI_Service = GetObject( "winmgmts:\\" & HyperVServer & "\root\virtualization") 'Get the Msvm_ImageManagementService object Set Msvm_ImageManagementService = WMI_Service.ExecQuery( "SELECT * FROM Msvm_ImageManagementService").ItemIndex(0) 'Setup the input parameter list Set InParam = Msvm_ImageManagementService.Methods_( "CompactVirtualHardDisk").InParameters.SpawnInstance_() InParam.Path = VHDName 'Execute the method and store the results in OutParam Set OutParam = Msvm_ImageManagementService.ExecMethod_( "CompactVirtualHardDisk", InParam) 'Check to see If the job completed synchronously If( OutParam.ReturnValue = 0 ) Then Wscript.Echo "The virtual hard disk has been compacted." ElseIf( OutParam.ReturnValue <> 4096 ) Then Wscript.Echo "The virtual hard disk has not been compacted." Else 'Get the job object Set Job = WMI_Service.Get( OutParam.Job) 'Wait for the job to complete (3 == starting, 4 == running) While ( Job.JobState = 3 ) Or ( Job.JobState = 4 ) Wscript.Echo "Compacting. " & Job.PercentComplete & " % complete" WScript.Sleep( 20000) 'Refresh the job object Set Job = WMI_Service.Get( OutParam.Job) Wend 'Provide details If the job fails (7 == complete) If( Job.JobState <> 7 ) Then Wscript.Echo "The virtual hard disk has not been compacted." Wscript.Echo "ErrorCode: " & Job.ErrorCode Wscript.Echo "ErrorDescription: " & Job.ErrorDescription Else Wscript.Echo "The virtual hard disk has been compacted." End If End If End Function Function ISO_date( strNow) Dim strDD, strMM, strYYYY strYYYY = DatePart( "yyyy", strNow) strMM = Right( "0" & DatePart( "m", strNow), 2) strDD = Right( "0" & DatePart( "d", strNow), 2) ISO_date = strYYYY & "-" & strMM & "-" & strDD End Function Function ISO_time( strNow) ISO_time = Right( "0" & Hour( strNow), 2) & ":" & Right( "0" & Minute( strNow), 2) & ":" & Right( "0" & Second( strNow), 2) End Function
-
Tuesday, April 10, 2012 8:24 AM
You have to change the volume number depending on how many other (physical) disks are attached to the parent partition:
Do While Not oScriptExec.StdOut.AtEndOfStream sLine = oScriptExec.StdOut.ReadLine WScript.Echo sLine If InStr( sLine, "Volume 5 ") Then sOut = Trim( Right( Left( sLine, 18), 5)) & ":" End If Loop

