0

I'm trying to find a way to create a checksum/hash of CD or DVD using PowerShell. I know Get-Filehash works very well on files, but I can't figure out how to do it for optical media. I was thinking I might be able to use Get-Content to get the bitstream and pipe it to Get-Filehash, but running Get-Content -Path D:\ (where D: is the disc) return an "Access to the path 'D:\'is denied. Get-Volume only seems to return an object with properties, not the bitstream.

I already have an ISO image file for the disc. Am trying to get the checksum on the whole original disc to compare to the ISO to make sure it was ripped correctly.

Any suggestions or pointers?

Nathan
  • 766
  • 2
  • 9
  • 19

3 Answers3

0

From your example, Get-Content -Path D:\ fails because you're not pointing to a file. From the Get-Content documentation:

-Path

Specifies the path to an item where Get-Content gets the content. Wildcard characters are permitted. The paths must be paths to items, not to containers. For example, you must specify a path to one or more files, not a path to a directory.

I.e., the optical drive isn't the issue for that cmdlet; you'll see the same error if you tried that on your C:/ drive.

From the question I'm not sure if your optical drive contains the extracted ISO or just the ISO, but something like this should get you started:

Get-ChildItem -Path d:\ -Recurse -File | foreach { 
    Get-FileHash $_.FullName; 
}
kuujinbo
  • 9,272
  • 3
  • 44
  • 57
  • Thanks for pointing out the problem with Get-Content. I did try it `get-content -Path D:\ -Encoding Byte -Raw` too, since I wasn't getting a particular file, but no luck there. I appreciate the starting point, but I don't think it's what I'm looking for. I'd like to get one checksum for the entire disc, not one for each file on the disc. I guess you can call the disc an extracted ISO; I'm working with various data discs people have burned. – Nathan Jan 25 '20 at 00:25
  • @Nathan - The ISO is a single file. I don't think you can compare the checksum of the single original ISO against a collection of files (I think that's what you meant when you said "_the entire disc_") unless you combine the files from the optical disk into a ISO and then run a checksum. – kuujinbo Jan 25 '20 at 00:35
  • "combine the files from the optical disk into a ISO and then run a checksum" kind of. I was looking into that, but keeping it in-stream and piping it to `Get-FileHash` to be able to verify the ISO was a bit-for-bit copy of the disc. Thanks! – Nathan Jan 25 '20 at 00:45
  • It seem PowerShell won't let you open raw devices. I've been able to successfully do this with Python by using `open('\\.\d:', 'rb')`, where `d:` is the drive name. I can't find a way for PowerShell to open that path. If you have access to Cygwin you can use `sha1sum /dev/scd0` (you can use any `shaXsum` command). So far I haven't been able to find any native PowerShell method. Ref for Python Script: [link](https://arstechnica.com/civis/viewtopic.php?f=15&t=1216159) – Peter Feb 11 '21 at 14:50
0

If I understand the question properly, you would like to get a hashvalue for everything on the CD (get the checksum on the whole original disc).

For this you can use the helper function below:

function Get-FolderHash {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
        [string]$Path,

        [ValidateSet('SHA1','SHA256','SHA384','SHA512','MD5')]
        [string]$Algorithm = 'MD5'
    )
    # create a new temporary file
    $temp=[System.IO.Path]::GetTempFileName()

    Get-ChildItem -Path $Path -File -Recurse | 
        Get-FileHash -Algorithm $Algorithm | 
        Select-Object -ExpandProperty Hash | 
        Out-File -FilePath $temp -NoNewline -Encoding ascii

    $hash = Get-FileHash -Path $temp -Algorithm $Algorithm
    $hash.Path = $Path

    Remove-Item -Path $temp

    return $hash
}

Get-FolderHash D:\

Hope that helps

Theo
  • 57,719
  • 8
  • 24
  • 41
  • Thank you, @Theo. This is what I was looking for, but I'm not sure it's what I needed after all. This calculates a checksum of all the checksums. But, that MD5 doesn't equal the MD5 of the ISO file created from the disc in D:\. Upon reflection, that makes sense, the iso would have filesystem info and blank sectors that are part of the ISO that the solution above doesn't account for. There may not be a way to do what I was hoping, from what I've read PowerShell isn't the best tool for creating an ISO and I think that's what I need to do, create an ISO instream and get its checksum... – Nathan Jan 25 '20 at 15:46
0

I came up with the following method:

function Hash-Media([string]$drive, [string]$algorithm){
     <#
     .SYNOPSIS
         Hashes the entire drive letter using the provided algorithm
     .PARAMETER  $drive
         The drive letter, eg 'd:'
     .PARAMETER  $algorithm
         Any algorithm acceptable by Get-FileHash, eg SHA1, SHA256, etc
     .EXAMPLE
         PS> Hash-Media e: SHA256
         43E2B7D5142592222FFA39F7AB15706911B8D14AAF0186D2A44CA07581F5FEBA
     #>

     
     
     $raw_stream = [System.IO.File]::Open('\\.\' + $drive, 'open', 'Read', 'Read')
     $hash = Get-FileHash -InputStream $raw_stream -Algorithm $algorithm
     return $hash.Hash
}

This returns the same value as checking the ISO file directly before it was burned.

Peter
  • 61
  • 2
  • Thank you! What program did you use to create the ISO? I've used two different programs and get the same hash on those files, but neither matches on the hash for the disk when I use this function. – Nathan Feb 20 '21 at 17:43
  • Personally, I use mkisofs (Linux/Cygwin) typically. Some applications honor a .iso file, some don't. At work we have had good luck with Roxio. Other applications (like Starburn) modify the metadata on disc when burning, so the hash will never match. DVDs and Blurays seem to work, CDRs don't. Also make sure you use DAO or SAO when burning the media which can close the disc at time of the burn. Closing the disc after it is burned will change the hash. You can use dd to make an iso from media or modify the above by witing the stream to a file instead sending it to Get-FileHash. – Peter Feb 23 '21 at 03:28