Skip to content

Instantly share code, notes, and snippets.

@LuanVSO
Last active April 30, 2023 02:41
Show Gist options
  • Save LuanVSO/d3e8dca9ad89e6e3b9b83fdc6dc5f0d4 to your computer and use it in GitHub Desktop.
Save LuanVSO/d3e8dca9ad89e6e3b9b83fdc6dc5f0d4 to your computer and use it in GitHub Desktop.
convert folder or single isos, cues and gdi to chd
<#PSScriptInfo
.VERSION 0.1.0
.GUID 0fbb9235-e965-40c4-8b57-f85cfb19f823
.AUTHOR Luan Vitor Simião Oliveira
.COPYRIGHT Luan Vitor Simião Oliveira
.TAGS chd convert iso cue gdi 7z
.LICENSEURI https://creativecommons.org/licenses/by/4.0/
.PROJECTURI https://gist.github.com/LuanVSO/d3e8dca9ad89e6e3b9b83fdc6dc5f0d4
.RELEASENOTES initial version
#>
<#
.DESCRIPTION
convert folder or single iso, cue and gdi to chd
inspired by https://github.com/undeadindustries/cuetochd/blob/master/cuetochd.ps1
but rewritten to work with chdman, 7z and NanaZipC.exe that are on the Path
and to avoid doing manual string manipulation as much as possible
#>
param (
[Parameter(Mandatory = $true,
Position = 0)]
[Alias("PSPath")]
[ValidateNotNullOrEmpty()]
[string]$inputPath,
[Parameter(Mandatory = $true,
Position = 1)]
[ValidateNotNullOrEmpty()]
[string]$outputPath
)
$workdir = join-path $env:TMP 'chd-workfolder'
mkdir $workdir -Force
mkdir $outputPath -force | out-null
$ErrorActionPreference = "Stop"
function expand-archive7zWrapper {
param (
[ValidateNotNullOrEmpty()]
[Parameter(Mandatory = $true,
Position = 0,
HelpMessage = "Path to the archive to extract.")]
[string]$archivePath,
[ValidateNotNullOrEmpty()]
[Parameter(Mandatory = $true,
Position = 1,
HelpMessage = "Path to the location to extract file.")]
[string]$destinationPath
)
$extractCmd = Get-Command 7z.exe || Get-Command NanaZipC.exe || throw "can't find 7z.exe or NanaZipC.exe, please install 7z then add it to the path."
Test-Path $archivePath -PathType Leaf || throw "Path $archivePath does not exist."
& $extractCmd e $archivePath "-o$destinationPath" -y && Remove-Item -LiteralPath $archivePath
}
function remove-fileOrFolder ([ValidateNotNullOrEmpty()][System.IO.FileInfo]$file) {
if ($file.directory.BaseName -eq $file.BaseName) {
# pass with -literalpath to work around [] globing
return remove-item -LiteralPath $file.DirectoryName -Recurse -Force
}
# can't use -LiteralPath here because it doesn't work with wildcards
$sanitizedpath = (join-path $file.DirectoryName $file.BaseName) -replace '[\[\]]' ,'`$&'
Remove-Item "$sanitizedpath*"
}
function convert {
param (
[ValidateNotNullOrEmpty()]
[System.IO.FileInfo]$file,
[ValidateNotNullOrEmpty()]
[string]$out
)
switch ($file.extension) {
({ $_ -in ".rar", ".zip", ".7z" }) {
# this way it isn't case sensitive
$destinationPath = join-path $workdir $file.BaseName
expand-archive7zWrapper $file.FullName $destinationPath
recurse $destinationPath
}
({ $_ -in ".cue", ".gdi", ".iso" }) {
$chdman = Get-Command chdman.exe || throw "can't find chdman.exe, please install chdman then add it to the path."
& $chdman createcd -i $file.FullName -o (join-path $out "$($file.BaseName).chd") -f && remove-fileOrFolder $file
}
".bin" { Write-Verbose "Skipping $file. probably part of a cue/bin set." }
Default { Write-Verbose "Skipping $file. We don't know what to do with that type." }
}
}
function recurse {
param (
[ValidateNotNullOrEmpty()]
[alias("PSPath")]
[System.IO.DirectoryInfo]$folder
)
# have to pass the folder via -LiteralPath to work around [] globing
$files = Get-ChildItem -LiteralPath $folder
foreach ($fileItem in $files) {
if ($fileitem -is [System.IO.DirectoryInfo]) {
recurse $fileItem
continue
}
convert $fileItem -out $outputPath
}
}
if (test-path -path $inputPath -PathType Container) {
return recurse $inputPath
}
convert $inputPath -out $outputPath
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment