diff --git a/ISORebuilder.bat b/ISORebuilder.bat new file mode 100644 index 0000000..5a0d0ec --- /dev/null +++ b/ISORebuilder.bat @@ -0,0 +1,4 @@ +@echo off +(NET FILE||(powershell -windowstyle hidden -command Start-Process '%0' -Verb runAs -ArgumentList '%* '&EXIT /B))>NUL 2>&1 +pushd "%~dp0" && cd %~dp0 +Powershell -executionPolicy Bypass -File ".\bin\isorebuilder.ps1" %* \ No newline at end of file diff --git a/README.md b/README.md index c0176ed..4a91b9e 100644 --- a/README.md +++ b/README.md @@ -40,4 +40,6 @@ synchronicity - wimlib murphy78 - original script -nosferati87, NiFu, s1ave77, and any other MDL forums members contributed in the ESD project \ No newline at end of file +nosferati87, NiFu, s1ave77, and any other MDL forums members contributed in the ESD project + +@tfwboredom - updated esddecrypt for 14361+ esds \ No newline at end of file diff --git a/bin/ESDDecrypter.ps1 b/bin/ESDDecrypter.ps1 index 23c7edd..f5e488a 100644 --- a/bin/ESDDecrypter.ps1 +++ b/bin/ESDDecrypter.ps1 @@ -1,4 +1,4 @@ -[CmdletBinding()] +[CmdletBinding()] param ( [ValidateScript({($_ -ge 0) -and ($_ -le 3)})] [int] $Scheme = 0, @@ -983,8 +983,8 @@ function Convert-ESD ( Output ([out.level] 'Info') 'Generating ISO...' $BootData='2#p0,e,bMedia\boot\etfsboot.com#pEF,e,bMedia\efi\Microsoft\boot\efisys.bin' - & "cmd" "/c" ".\bin\cdimage.exe" "-bootdata:$BootData" "-o" "-h" "-m" "-u2" "-udfver102" "-t$timestamp" "-l$($ISOInfos.VolumeLabel)" ".\Media" """$($Destination)\$($ISOInfos.FileName)"""<# | ForEach-Object -Process { - if ($count -eq 11) {Write-Host ''} + & "cmd" "/c" ".\bin\cdimage.exe" "-bootdata:$BootData" "-o" "-m" "-u2" "-udfver102" "-t$timestamp" "-l$($ISOInfos.VolumeLabel)" ".\Media" """$($Destination)\$($ISOInfos.FileName)"""<# | ForEach-Object -Process { + if ($count -eq 11) {Write-Host ''} if ($count -eq 30) {Write-Host ''} $count++ } #> diff --git a/bin/Get-DirStats.ps1 b/bin/Get-DirStats.ps1 new file mode 100644 index 0000000..9a84dc9 --- /dev/null +++ b/bin/Get-DirStats.ps1 @@ -0,0 +1,156 @@ +# Get-DirStats.ps1 +# Written by Bill Stewart (bstewart@iname.com) +# Outputs file system directory statistics. + +#requires -version 2 + +<# +.SYNOPSIS +Outputs file system directory statistics. + +.DESCRIPTION +Outputs file system directory statistics (number of files and the sum of all file sizes) for one or more directories. + +.PARAMETER Path +Specifies a path to one or more file system directories. Wildcards are not permitted. The default path is the current directory (.). + +.PARAMETER LiteralPath +Specifies a path to one or more file system directories. Unlike Path, the value of LiteralPath is used exactly as it is typed. + +.PARAMETER Only +Outputs statistics for a directory but not any of its subdirectories. + +.PARAMETER Every +Outputs statistics for every directory in the specified path instead of only the first level of directories. + +.PARAMETER FormatNumbers +Formats numbers in the output object to include thousands separators. + +.PARAMETER Total +Outputs a summary object after all other output that sums all statistics. +#> + +[CmdletBinding(DefaultParameterSetName="Path")] +param( + [parameter(Position=0,Mandatory=$false,ParameterSetName="Path",ValueFromPipeline=$true)] + $Path=(get-location).Path, + [parameter(Position=0,Mandatory=$true,ParameterSetName="LiteralPath")] + [String[]] $LiteralPath, + [Switch] $Only, + [Switch] $Every, + [Switch] $FormatNumbers, + [Switch] $Total +) + +begin { + $ParamSetName = $PSCmdlet.ParameterSetName + if ( $ParamSetName -eq "Path" ) { + $PipelineInput = ( -not $PSBoundParameters.ContainsKey("Path") ) -and ( -not $Path ) + } + elseif ( $ParamSetName -eq "LiteralPath" ) { + $PipelineInput = $false + } + + # Script-level variables used with -Total. + [UInt64] $script:totalcount = 0 + [UInt64] $script:totalbytes = 0 + + # Returns a [System.IO.DirectoryInfo] object if it exists. + function Get-Directory { + param( $item ) + + if ( $ParamSetName -eq "Path" ) { + if ( Test-Path -Path $item -PathType Container ) { + $item = Get-Item -Path $item -Force + } + } + elseif ( $ParamSetName -eq "LiteralPath" ) { + if ( Test-Path -LiteralPath $item -PathType Container ) { + $item = Get-Item -LiteralPath $item -Force + } + } + if ( $item -and ($item -is [System.IO.DirectoryInfo]) ) { + return $item + } + } + + # Filter that outputs the custom object with formatted numbers. + function Format-Output { + process { + $_ | Select-Object Path, + @{Name="Files"; Expression={"{0:N0}" -f $_.Files}}, + @{Name="Size"; Expression={"{0:N0}" -f $_.Size}} + } + } + + # Outputs directory statistics for the specified directory. With -recurse, + # the function includes files in all subdirectories of the specified + # directory. With -format, numbers in the output objects are formatted with + # the Format-Output filter. + function Get-DirectoryStats { + param( $directory, $recurse, $format ) + + Write-Progress -Activity "Get-DirStats.ps1" -Status "Reading '$($directory.FullName)'" + $files = $directory | Get-ChildItem -Force -Recurse:$recurse | Where-Object { -not $_.PSIsContainer } + if ( $files ) { + Write-Progress -Activity "Get-DirStats.ps1" -Status "Calculating '$($directory.FullName)'" + $output = $files | Measure-Object -Sum -Property Length | Select-Object ` + @{Name="Path"; Expression={$directory.FullName}}, + @{Name="Files"; Expression={$_.Count; $script:totalcount += $_.Count}}, + @{Name="Size"; Expression={$_.Sum; $script:totalbytes += $_.Sum}} + } + else { + $output = "" | Select-Object ` + @{Name="Path"; Expression={$directory.FullName}}, + @{Name="Files"; Expression={0}}, + @{Name="Size"; Expression={0}} + } + if ( -not $format ) { $output } else { $output | Format-Output } + } +} + +process { + # Get the item to process, no matter whether the input comes from the + # pipeline or not. + if ( $PipelineInput ) { + $item = $_ + } + else { + if ( $ParamSetName -eq "Path" ) { + $item = $Path + } + elseif ( $ParamSetName -eq "LiteralPath" ) { + $item = $LiteralPath + } + } + + # Write an error if the item is not a directory in the file system. + $directory = Get-Directory -item $item + if ( -not $directory ) { + Write-Error -Message "Path '$item' is not a directory in the file system." -Category InvalidType + return + } + + # Get the statistics for the first-level directory. + Get-DirectoryStats -directory $directory -recurse:$false -format:$FormatNumbers + # -Only means no further processing past the first-level directory. + if ( $Only ) { return } + + # Get the subdirectories of the first-level directory and get the statistics + # for each of them. + $directory | Get-ChildItem -Force -Recurse:$Every | + Where-Object { $_.PSIsContainer } | ForEach-Object { + Get-DirectoryStats -directory $_ -recurse:(-not $Every) -format:$FormatNumbers + } +} + +end { + # If -Total specified, output summary object. + if ( $Total ) { + $output = "" | Select-Object ` + @{Name="Path"; Expression={""}}, + @{Name="Files"; Expression={$script:totalcount}}, + @{Name="Size"; Expression={$script:totalbytes}} + if ( -not $FormatNumbers ) { $output } else { $output | Format-Output } + } +} diff --git a/bin/RenameISOs.ps1 b/bin/RenameISOs.ps1 index 58ead16..cf2289e 100644 --- a/bin/RenameISOs.ps1 +++ b/bin/RenameISOs.ps1 @@ -1,248 +1,250 @@ # Workaround, because of Powershell bug present in old builds. -Function Write-Host ($message,$nonewline,$backgroundcolor,$foregroundcolor) {$Message | Out-Host} +function Write-Host ($message,$nonewline,$backgroundcolor,$foregroundcolor) { $Message | Out-Host } New-Enum iso.filenametype Universal Partner Consumer Windows7 -if (-not (Get-Command Mount-DiskImage -errorAction SilentlyContinue)) +if (-not (Get-Command Mount-DiskImage -ErrorAction SilentlyContinue)) { - Write-Host ' + Write-Host ' Sorry, but your system does not have the ability to mount ISO files. This is maybe because you are running an older version of Windows than 6.2 Error: Cannot find Mount-DiskImage ' - return + return } -function get-i386infos($letter, $type, $label) { - - $result = "" | select MajorVersion, MinorVersion, BuildNumber, DeltaVersion, BranchName, CompileDate, Tag, Architecture, BuildType, Type, Sku, Editions, Licensing, LanguageCode, VolumeLabel - - $result.VolumeLabel = $label - - # Gathering Compiledate and the buildbranch from the main setup.exe executable. - $NoExtended = $false - - if (Test-Path ($letter+'\'+$type+'\ntoskrnl.ex_')) { - & 'bin\7z' e $letter\$type\ntoskrnl.ex_ *.exe -r | out-null - if (((Get-item .\ntoskrnl.exe).VersionInfo.FileVersion) -like '*built by:*') { - $result.CompileDate = (Get-item .\ntoskrnl.exe).VersionInfo.FileVersion.split(':')[-1].replace(' ', '') - $result.BranchName = (Get-item .\ntoskrnl.exe).VersionInfo.FileVersion.split(':')[-2].replace(' at', '').replace(' ', '') - } elseif (((Get-item .\ntoskrnl.exe).VersionInfo.FileVersion) -like '*.*.*.*(*)*') { - $result.CompileDate = (Get-item .\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') - $result.BranchName = (Get-item .\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) - } else { - $NoExtended = $true - } - - if ((Get-item .\ntoskrnl.exe).VersionInfo.IsDebug) { - $result.BuildType = 'chk' - } else { - $result.BuildType = 'fre' - } - $result.Architecture = (Test-Arch '.\ntoskrnl.exe').FileType - - if ($NoExtended) { - $buildno = (Get-item .\ntoskrnl.exe).VersionInfo.FileVersion - } else { - $buildno = (Get-item .\ntoskrnl.exe).VersionInfo.ProductVersion - } - - if (-not ($buildno -like '*.*.*.*')) { - & 'bin\7z' e .\ntoskrnl.exe .rsrc\version.txt | out-null - $buildno = Remove-InvalidFileNameChars(Get-Content '.\version.txt' -First 1).split(' ')[-1].replace(',', '.') - Remove-Item '.\version.txt' -force - } - - Remove-Item '.\ntoskrnl.exe' -force - } elseif (Test-Path ($letter+'\'+$type+'\ntoskrnl.exe')) { - if (((Get-item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion) -like '*built by:*') { - $result.CompileDate = (Get-item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion.split(':')[-1].replace(' ', '') - $result.BranchName = (Get-item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion.split(':')[-2].replace(' at', '').replace(' ', '') - } elseif (((Get-item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion) -like '*.*.*.*(*)*') { - $result.CompileDate = (Get-item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') - $result.BranchName = (Get-item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) - } else { - $NoExtended = $true - } - - if ((Get-item $letter\$type\ntoskrnl.exe).VersionInfo.IsDebug) { - $result.BuildType = 'chk' - } else { - $result.BuildType = 'fre' - } - $result.Architecture = (Test-Arch ($letter+'\'+$type+'\NTKRNLMP.EXE')).FileType - - if ($NoExtended) { - $buildno = (Get-item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion - } else { - $buildno = (Get-item $letter\$type\ntoskrnl.exe).VersionInfo.ProductVersion - } - - if (-not ($buildno -like '*.*.*.*')) { - & 'bin\7z' e $letter\$type\ntoskrnl.exe .rsrc\version.txt | out-null - $buildno = Remove-InvalidFileNameChars(Get-Content '.\version.txt' -First 1).split(' ')[-1].replace(',', '.') - Remove-Item '.\version.txt' -force - } - } elseif (Test-Path ($letter+'\'+$type+'\NTKRNLMP.EX_')) { - & 'bin\7z' e $letter\$type\NTKRNLMP.EX_ *.exe -r | out-null - if (((Get-item .\NTKRNLMP.exe).VersionInfo.FileVersion) -like '*built by:*') { - $result.CompileDate = (Get-item .\NTKRNLMP.EXE).VersionInfo.FileVersion.split(':')[-1].replace(' ', '') - $result.BranchName = (Get-item .\NTKRNLMP.EXE).VersionInfo.FileVersion.split(':')[-2].replace(' at', '').replace(' ', '') - } elseif (((Get-item .\NTKRNLMP.exe).VersionInfo.FileVersion) -like '*.*.*.*(*)*') { - $result.CompileDate = (Get-item .\NTKRNLMP.EXE).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') - $result.BranchName = (Get-item .\NTKRNLMP.EXE).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) - } else { - $NoExtended = $true - } - - if ((Get-item .\NTKRNLMP.EXE).VersionInfo.IsDebug) { - $result.BuildType = 'chk' - } else { - $result.BuildType = 'fre' - } - $result.Architecture = (Test-Arch '.\NTKRNLMP.EXE').FileType - - if ($NoExtended) { - $buildno = (Get-item .\NTKRNLMP.EXE).VersionInfo.FileVersion - } else { - $buildno = (Get-item .\NTKRNLMP.EXE).VersionInfo.ProductVersion - } - - if (-not ($buildno -like '*.*.*.*')) { - & 'bin\7z' e .\NTKRNLMP.EXE .rsrc\version.txt | out-null - $buildno = Remove-InvalidFileNameChars(Get-Content '.\version.txt' -First 1).split(' ')[-1].replace(',', '.') - Remove-Item '.\version.txt' -force - } - - Remove-Item '.\NTKRNLMP.EXE' -force - } else { - if (((Get-item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion) -like '*built by:*') { - $result.CompileDate = (Get-item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion.split(':')[-1].replace(' ', '') - $result.BranchName = (Get-item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion.split(':')[-2].replace(' at', '').replace(' ', '') - } elseif (((Get-item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion) -like '*.*.*.*(*)*') { - $result.CompileDate = (Get-item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') - $result.BranchName = (Get-item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) - } else { - $NoExtended = $true - } - - if ((Get-item $letter\$type\NTKRNLMP.EXE).VersionInfo.IsDebug) { - $result.BuildType = 'chk' - } else { - $result.BuildType = 'fre' - } - $result.Architecture = (Test-Arch ($letter+'\'+$type+'\NTKRNLMP.EXE')).FileType - if ($type.toLower() -eq 'alpha') { - $result.Architecture = 'AXP' - } - - if ($NoExtended) { - $buildno = (Get-item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion - } else { - $buildno = (Get-item $letter\$type\NTKRNLMP.EXE).VersionInfo.ProductVersion - } - - if (-not ($buildno -like '*.*.*.*')) { - & 'bin\7z' e $letter\$type\NTKRNLMP.EXE .rsrc\version.txt | out-null - $buildno = Remove-InvalidFileNameChars(Get-Content '.\version.txt' -First 1).split(' ')[-1].replace(',', '.') - Remove-Item '.\version.txt' -force - } - } - - $result.MajorVersion = $buildno.split('.')[0] - $result.MinorVersion = $buildno.split('.')[1] - $result.BuildNumber = $buildno.split('.')[2] - $result.DeltaVersion = $buildno.split('.')[3] - - $cdtag = (get-inicontent $letter\$type\txtsetup.sif)["SourceDisksNames"]["_x"].split(',')[1] - if ($cdtag -eq '%cdtagfile%') { - $editionletter = (get-inicontent $letter\$type\txtsetup.sif)["Strings"]["cdtagfile"].toLower().replace('"', '') - } else { - $editionletter = $cdtag.toLower().replace('"', '') - } - - $editionletter = $editionletter.replace('cdrom.', '') - $editionletter_ = $editionletter.split('.')[0][-2] - $editionletter = $editionletter.split('.')[0][-1] - - if ($editionletter -eq 'p') { - $result.Sku = 'Professional' - $result.Type = 'client' - } elseif ($editionletter -eq 'c') { - $result.Sku = 'Home' - $result.Type = 'client' - } elseif ($editionletter -eq 'w') { - $result.Sku = 'Workstation' - $result.Type = 'client' - } elseif ($editionletter -eq 'b') { - $result.Sku = 'Web' - $result.Type = 'server' - } elseif ($editionletter -eq 's') { - $result.Sku = 'Standard' - if ($editionletter_ -eq 't') { - $result.Sku = 'Terminal' - } - $result.Type = 'server' - } elseif ($editionletter -eq 'a') { - if ($buildno.split('.')[2] -le 2202) { - $result.Sku = 'Advanced' - } else { - $result.Sku = 'Enterprise' - } - $result.Type = 'server' - } elseif ($editionletter -eq 'l') { - $result.Sku = 'Smallbusiness' - $result.Type = 'server' - } elseif ($editionletter -eq 'd') { - $result.Sku = 'Datacenter' - $result.Type = 'server' - } else { - $result.Sku = $editionletter - $result.Type = 'unknown' - } - - $result.Editions = $result.Sku - - $langid = '0x'+(get-inicontent $letter\$type\TXTSETUP.SIF)["nls"]["DefaultLayout"] - - $langid = $langid.replace('E001', '') - - $result.LanguageCode = [System.Globalization.Cultureinfo]::GetCultureInfo([int32]$langid).Name - - Write-Host "Dismounting $($isofile)..." - get-DiskImage -ImagePath $isofile.fullname | Dismount-DiskImage - - $result.Licensing = 'Retail' - - return $result +function get-i386infos ($letter,$type,$label) { + + $result = "" | select MajorVersion,MinorVersion,BuildNumber,DeltaVersion,BranchName,CompileDate,Tag,Architecture,BuildType,Type,Sku,Editions,Licensing,LanguageCode,VolumeLabel + + $result.VolumeLabel = $label + + # Gathering Compiledate and the buildbranch from the main setup.exe executable. + $NoExtended = $false + + if (Test-Path ($letter + '\' + $type + '\ntoskrnl.ex_')) { + & 'bin\7z' e $letter\$type\ntoskrnl.ex_ *.exe -r | Out-Null + if (((Get-Item .\ntoskrnl.exe).VersionInfo.FileVersion) -like '*built by:*') { + $result.CompileDate = (Get-Item .\ntoskrnl.exe).VersionInfo.FileVersion.split(':')[-1].replace(' ','') + $result.BranchName = (Get-Item .\ntoskrnl.exe).VersionInfo.FileVersion.split(':')[-2].replace(' at','').replace(' ','') + } elseif (((Get-Item .\ntoskrnl.exe).VersionInfo.FileVersion) -like '*.*.*.*(*)*') { + $result.CompileDate = (Get-Item .\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')','') + $result.BranchName = (Get-Item .\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + } else { + $NoExtended = $true + } + + if ((Get-Item .\ntoskrnl.exe).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $result.Architecture = (Test-Arch '.\ntoskrnl.exe').FileType + + if ($NoExtended) { + $buildno = (Get-Item .\ntoskrnl.exe).VersionInfo.FileVersion + } else { + $buildno = (Get-Item .\ntoskrnl.exe).VersionInfo.ProductVersion + } + + if (-not ($buildno -like '*.*.*.*')) { + & 'bin\7z' e .\ntoskrnl.exe .rsrc\version.txt | Out-Null + $buildno = Remove-InvalidFileNameChars (Get-Content '.\version.txt' -First 1).split(' ')[-1].replace(',','.') + Remove-Item '.\version.txt' -Force + } + + Remove-Item '.\ntoskrnl.exe' -Force + } elseif (Test-Path ($letter + '\' + $type + '\ntoskrnl.exe')) { + if (((Get-Item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion) -like '*built by:*') { + $result.CompileDate = (Get-Item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion.split(':')[-1].replace(' ','') + $result.BranchName = (Get-Item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion.split(':')[-2].replace(' at','').replace(' ','') + } elseif (((Get-Item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion) -like '*.*.*.*(*)*') { + $result.CompileDate = (Get-Item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')','') + $result.BranchName = (Get-Item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + } else { + $NoExtended = $true + } + + if ((Get-Item $letter\$type\ntoskrnl.exe).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $result.Architecture = (Test-Arch ($letter + '\' + $type + '\NTKRNLMP.EXE')).FileType + + if ($NoExtended) { + $buildno = (Get-Item $letter\$type\ntoskrnl.exe).VersionInfo.FileVersion + } else { + $buildno = (Get-Item $letter\$type\ntoskrnl.exe).VersionInfo.ProductVersion + } + + if (-not ($buildno -like '*.*.*.*')) { + & 'bin\7z' e $letter\$type\ntoskrnl.exe .rsrc\version.txt | Out-Null + $buildno = Remove-InvalidFileNameChars (Get-Content '.\version.txt' -First 1).split(' ')[-1].replace(',','.') + Remove-Item '.\version.txt' -Force + } + } elseif (Test-Path ($letter + '\' + $type + '\NTKRNLMP.EX_')) { + & 'bin\7z' e $letter\$type\NTKRNLMP.EX_ *.exe -r | Out-Null + if (((Get-Item .\NTKRNLMP.exe).VersionInfo.FileVersion) -like '*built by:*') { + $result.CompileDate = (Get-Item .\NTKRNLMP.EXE).VersionInfo.FileVersion.split(':')[-1].replace(' ','') + $result.BranchName = (Get-Item .\NTKRNLMP.EXE).VersionInfo.FileVersion.split(':')[-2].replace(' at','').replace(' ','') + } elseif (((Get-Item .\NTKRNLMP.exe).VersionInfo.FileVersion) -like '*.*.*.*(*)*') { + $result.CompileDate = (Get-Item .\NTKRNLMP.EXE).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')','') + $result.BranchName = (Get-Item .\NTKRNLMP.EXE).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + } else { + $NoExtended = $true + } + + if ((Get-Item .\NTKRNLMP.EXE).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $result.Architecture = (Test-Arch '.\NTKRNLMP.EXE').FileType + + if ($NoExtended) { + $buildno = (Get-Item .\NTKRNLMP.EXE).VersionInfo.FileVersion + } else { + $buildno = (Get-Item .\NTKRNLMP.EXE).VersionInfo.ProductVersion + } + + if (-not ($buildno -like '*.*.*.*')) { + & 'bin\7z' e .\NTKRNLMP.EXE .rsrc\version.txt | Out-Null + $buildno = Remove-InvalidFileNameChars (Get-Content '.\version.txt' -First 1).split(' ')[-1].replace(',','.') + Remove-Item '.\version.txt' -Force + } + + Remove-Item '.\NTKRNLMP.EXE' -Force + } else { + if (((Get-Item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion) -like '*built by:*') { + $result.CompileDate = (Get-Item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion.split(':')[-1].replace(' ','') + $result.BranchName = (Get-Item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion.split(':')[-2].replace(' at','').replace(' ','') + } elseif (((Get-Item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion) -like '*.*.*.*(*)*') { + $result.CompileDate = (Get-Item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')','') + $result.BranchName = (Get-Item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + } else { + $NoExtended = $true + } + + if ((Get-Item $letter\$type\NTKRNLMP.EXE).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $result.Architecture = (Test-Arch ($letter + '\' + $type + '\NTKRNLMP.EXE')).FileType + if ($type.toLower() -eq 'alpha') { + $result.Architecture = 'AXP' + } + + if ($NoExtended) { + $buildno = (Get-Item $letter\$type\NTKRNLMP.EXE).VersionInfo.FileVersion + } else { + $buildno = (Get-Item $letter\$type\NTKRNLMP.EXE).VersionInfo.ProductVersion + } + + if (-not ($buildno -like '*.*.*.*')) { + & 'bin\7z' e $letter\$type\NTKRNLMP.EXE .rsrc\version.txt | Out-Null + $buildno = Remove-InvalidFileNameChars (Get-Content '.\version.txt' -First 1).split(' ')[-1].replace(',','.') + Remove-Item '.\version.txt' -Force + } + } + + $result.MajorVersion = $buildno.split('.')[0] + $result.MinorVersion = $buildno.split('.')[1] + $result.BuildNumber = $buildno.split('.')[2] + $result.DeltaVersion = $buildno.split('.')[3] + + $cdtag = (get-inicontent $letter\$type\txtsetup.sif)["SourceDisksNames"]["_x"].split(',')[1] + if ($cdtag -eq '%cdtagfile%') { + $editionletter = (get-inicontent $letter\$type\txtsetup.sif)["Strings"]["cdtagfile"].toLower().replace('"','') + } else { + $editionletter = $cdtag.toLower().replace('"','') + } + + $editionletter = $editionletter.replace('cdrom.','') + $editionletter_ = $editionletter.split('.')[0][-2] + $editionletter = $editionletter.split('.')[0][-1] + + if ($editionletter -eq 'p') { + $result.Sku = 'Professional' + $result.Type = 'client' + } elseif ($editionletter -eq 'c') { + $result.Sku = 'Home' + $result.Type = 'client' + } elseif ($editionletter -eq 'w') { + $result.Sku = 'Workstation' + $result.Type = 'client' + } elseif ($editionletter -eq 'b') { + $result.Sku = 'Web' + $result.Type = 'server' + } elseif ($editionletter -eq 's') { + $result.Sku = 'Standard' + if ($editionletter_ -eq 't') { + $result.Sku = 'Terminal' + } + $result.Type = 'server' + } elseif ($editionletter -eq 'a') { + if ($buildno.split('.')[2] -le 2202) { + $result.Sku = 'Advanced' + } else { + $result.Sku = 'Enterprise' + } + $result.Type = 'server' + } elseif ($editionletter -eq 'l') { + $result.Sku = 'Smallbusiness' + $result.Type = 'server' + } elseif ($editionletter -eq 'd') { + $result.Sku = 'Datacenter' + $result.Type = 'server' + } else { + $result.Sku = $editionletter + $result.Type = 'unknown' + } + + $result.Editions = $result.Sku + + $langid = '0x' + (get-inicontent $letter\$type\TXTSETUP.SIF)["nls"]["DefaultLayout"] + + $langid = $langid.replace('E001','') + + $result.LanguageCode = [System.Globalization.Cultureinfo]::GetCultureInfo([int32]$langid).Name + + Write-Host "Dismounting $($isofile)..." + Get-DiskImage -ImagePath $isofile.fullname | Dismount-DiskImage + + $result.Licensing = 'Retail' + + return $result } -function ISO-identify($isofile) { +function ISO-identify ($isofile) { - $langcodes = @{} - [globalization.cultureinfo]::GetCultures("allCultures") | select name,DisplayName | foreach-object { - $langcodes[$_.DisplayName] = $_.Name - } - $langcodes['Spanish (Spain, Traditional Sort)'] = 'es-ES_tradnl' - $langcodes['Chinese (Simplified, China)'] = 'zh-CHS' - $langcodes['Norwegian Bokmål (Norway)'] = 'nb-NO' - - $result = "" | select MajorVersion, MinorVersion, BuildNumber, DeltaVersion, BranchName, CompileDate, Tag, Architecture, BuildType, Type, Sku, Editions, Licensing, LanguageCode, VolumeLabel - - # We mount the ISO File - Write-Host "Mounting $($isofile)..." - Mount-DiskImage -ImagePath $isofile.fullname + $langcodes = @{} + [globalization.cultureinfo]::GetCultures("allCultures") | select name,DisplayName | ForEach-Object { + $langcodes[$_.DisplayName] = $_.Name + } + $langcodes['Spanish (Spain, Traditional Sort)'] = 'es-ES_tradnl' + $langcodes['Chinese (Simplified, China)'] = 'zh-CHS' + $langcodes['Norwegian Bokm�l (Norway)'] = 'nb-NO' - # We get the mounted drive letter - $letter = (get-DiskImage -ImagePath $isofile.fullname | Get-Volume).driveletter + ":" - $result.VolumeLabel = (get-DiskImage -ImagePath $isofile.fullname | Get-Volume).FileSystemLabel + $result = "" | select MajorVersion,MinorVersion,BuildNumber,DeltaVersion,BranchName,CompileDate,Tag,Architecture,BuildType,Type,Sku,Editions,Licensing,LanguageCode,VolumeLabel,BuildString,SetupPath - Write-Host "Mounted $($isofile) as drive $($letter)" - - if ((Test-Path ($letter+"\sources\install.wim")) -and (Test-Path ($letter+"\sources\lang.ini")) -and (Test-Path ($letter+"\sources\boot.wim"))) { + # We mount the ISO File + Write-Host "Mounting $($isofile)..." + Mount-DiskImage -ImagePath $isofile.fullname + + # We get the mounted drive letter + $letter = (Get-DiskImage -ImagePath $isofile.fullname | Get-Volume).driveletter + ":" + $result.VolumeLabel = (Get-DiskImage -ImagePath $isofile.fullname | Get-Volume).FileSystemLabel + + Write-Host "Mounted $($isofile) as drive $($letter)" - # Gathering all infos we can find from install wim to $WIMInfo including the WIM Header + if ((Test-Path ($letter + "\sources\install.wim")) -and (Test-Path ($letter + "\sources\lang.ini")) -and (Test-Path ($letter + "\sources\boot.wim"))) { + + $WIM = $letter + "\sources\install.wim" + + # Gathering all infos we can find from install wim to $WIMInfo including the WIM Header # This portion of code comes from gus33000's ESDDecrypter Beta. # The required notice is displayed below : @@ -277,683 +279,720 @@ function ISO-identify($isofile) { } } - $result.Editions = $editions - - # Converting standards architecture names to friendly ones, if we didn't found any, we put the standard one instead * cough * arm / ia64, - # Yes, IA64 is still a thing for server these days... - if ($WIMInfo[1].Architecture -eq 'x86') { - $result.Architecture = 'x86' - } elseif ($WIMInfo[1].Architecture -eq 'x86_64') { - $result.Architecture = 'amd64' - } else { - $result.Architecture = $WIMInfo[1].Architecture - } - - # Gathering Compiledate and the buildbranch from the ntoskrnl executable. - Write-Host 'Checking critical system files for a build string and build type information...' - & $wimlib extract $letter\sources\install.wim 1 windows\system32\ntkrnlmp.exe windows\system32\ntoskrnl.exe --nullglob --no-acls | out-null - if (Test-Path .\ntkrnlmp.exe) { - $result.CompileDate = (Get-item .\ntkrnlmp.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') - $result.BranchName = (Get-item .\ntkrnlmp.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) - if ((Get-item .\ntkrnlmp.exe).VersionInfo.IsDebug) { - $result.BuildType = 'chk' - } else { - $result.BuildType = 'fre' - } - $ProductVersion = (Get-item .\ntkrnlmp.exe).VersionInfo.ProductVersion - remove-item .\ntkrnlmp.exe -force - } elseif (Test-Path .\ntoskrnl.exe) { - $result.CompileDate = (Get-item .\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') - $result.BranchName = (Get-item .\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) - if ((Get-item .\ntoskrnl.exe).VersionInfo.IsDebug) { - $result.BuildType = 'chk' - } else { - $result.BuildType = 'fre' - } - $ProductVersion = (Get-item .\ntoskrnl.exe).VersionInfo.ProductVersion - remove-item .\ntoskrnl.exe -force - } - - $result.MajorVersion = $ProductVersion.split('.')[0] - $result.MinorVersion = $ProductVersion.split('.')[1] - $result.BuildNumber = $ProductVersion.split('.')[2] - $result.DeltaVersion = $ProductVersion.split('.')[3] - - # Gathering Compiledate and the buildbranch from the build registry. - Write-Host 'Checking registry for a more accurate build string...' - & $wimlib extract $letter\sources\install.wim 1 windows\system32\config\ --no-acls | out-null - & 'reg' load HKLM\RenameISOs .\config\SOFTWARE | out-null - $output = ( & 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion" /v "BuildLab") - if (($output[2] -ne $null) -and (-not ($output[2].Split(' ')[-1].Split('.')[-1]) -eq '')) { - $result.CompileDate = $output[2].Split(' ')[-1].Split('.')[-1] - $result.BranchName = $output[2].Split(' ')[-1].Split('.')[-2] - $output_ = ( & 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion" /v "BuildLabEx") - if (($output_[2] -ne $null) -and (-not ($output_[2].Split(' ')[-1].Split('.')[-1]) -eq '')) { - if ($output_[2].Split(' ')[-1] -like '*.*.*.*.*') { - $result.BuildNumber = $output_[2].Split(' ')[-1].Split('.')[0] - $result.DeltaVersion = $output_[2].Split(' ')[-1].Split('.')[1] - } - } - } else { - Write-Host 'Registry check was unsuccessful. Aborting and continuing with critical system files build string...' - } - & 'reg' unload HKLM\RenameISOs | out-null - remove-item .\config\ -recurse -force - - # Defining if server or client thanks to Microsoft including 'server' in the server sku names - if (($WIMInfo.header.ImageCount -gt 2) -and (($WIMInfo[1].EditionID) -eq $null)) { - $result.Type = 'client' - $result.Sku = $null - } elseif (($WIMInfo[1].EditionID) -eq $null) { - $result.Type = 'client' - $result.Sku = 'unstaged' - } elseif (($WIMInfo[1].EditionID.toLower()) -like '*server*') { - $result.Type = 'server' - $result.Sku = $WIMInfo[1].EditionID.toLower() -replace 'server', '' - } else { - $result.Type = 'client' - $result.Sku = $WIMInfo[1].EditionID.toLower() - } - - $result.Licensing = 'Retail' - - # Checking for any possible edition lock. We are not handling pid files atm, so we are putting staged instead. (We will probably never handle pid files) - if (Test-Path ($letter+'\sources\ei.cfg')) { - $content = @() - Get-Content ($letter+'\sources\ei.cfg') | foreach-object -process { - $content += $_ - } - $counter = 0 - foreach ($item in $content) { - $counter++ - if ($item -eq '[EditionID]') { - $result.Sku = $content[$counter] - } - } - $counter = 0 - foreach ($item in $content) { - $counter++ - if ($item -eq '[Channel]') { - $result.Licensing = $content[$counter] - } - } - } elseif (-not (Test-Path ($letter+'\sources\pid.txt'))) { - if ($WIMInfo.header.ImageCount -gt 2) { - $result.Sku = $null - } - } elseif (($type -eq 'server') -and (Test-Path ($letter+'\sources\pid.txt'))) { - $result.Sku = $lastedition -replace 'server', '' - } - - if (($WIMInfo.header.ImageCount -eq 4) -and ($result.Type -eq 'server')) { - $result.Sku = $null - } - - Get-Content ($letter+'\sources\lang.ini') | foreach-object -begin {$h=@()} -process { $k = [regex]::split($_,'`r`n'); if(($k[0].CompareTo("") -ne 0)) { $h += $k[0] } } - $result.LanguageCode = ($h[((0..($h.Count - 1) | Where { $h[$_] -eq '[Available UI Languages]' }) + 1)]).split('=')[0].Trim() - - Write-Host "Dismounting $($isofile)..." - get-DiskImage -ImagePath $isofile.fullname | Dismount-DiskImage - - } elseif ((Test-Path ($letter+'\setup.exe')) -and (Test-Path ($letter+'\sources\setup.exe'))) { - - $buildno = (Get-item $letter\setup.exe).VersionInfo.ProductVersion - - $result.MajorVersion = $buildno.split('.')[0] - $result.MinorVersion = $buildno.split('.')[1] - $result.BuildNumber = $buildno.split('.')[2] - $result.DeltaVersion = $buildno.split('.')[3] - - # Gathering Compiledate and the buildbranch from the main setup.exe executable. - $result.CompileDate = (Get-item $letter\setup.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') - $result.BranchName = (Get-item $letter\setup.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) - - if (Test-Path $letter'\sources\product.ini') { - $result.Sku = (get-inicontent ($letter+'\sources\product.ini'))["No-Section"]["skuid"].replace(' ', '') - if ($result.Sku -eq 'pro') { - $result.Sku = 'Professional' - $result.Type = 'Client' - } - } else { - $files = (Get-ChildItem $letter\* | where-object {-not([System.IO.Path]::hasExtension($_.FullName)) -and -not ($_.PsIsContainer)}) - if ($files -ne $null) { - - $editionletter = $files[-1].Name.toLower() - - $editionletter = $editionletter.replace('cdrom.', '') - $editionletter_ = $editionletter.split('.')[0][-2] - $editionletter = $editionletter.split('.')[0][-1] - - if ($editionletter -eq 'p') { - $result.Sku = 'Professional' - $result.Type = 'client' - } elseif ($editionletter -eq 'c') { - $result.Sku = 'Home' - $result.Type = 'client' - } elseif ($editionletter -eq 'w') { - $result.Sku = 'Workstation' - $result.Type = 'client' - } elseif ($editionletter -eq 'b') { - $result.Sku = 'Web' - $result.Type = 'server' - } elseif ($editionletter -eq 's') { - $result.Sku = 'Standard' - if ($editionletter_ -eq 't') { - $result.Sku = 'Terminal' - } - $result.Type = 'server' - } elseif ($editionletter -eq 'a') { - if ($result.BuildNumber.split('.')[2] -le 2202) { - $result.Sku = 'Advanced' - } else { - $result.Sku = 'Enterprise' + if ($lastedition -eq $null) { + for ($i=1; $i -le $WIMInfo.header.ImageCount; $i++){ + $OutputVariable = ( & $wimlib info "$($letter)\sources\install.wim" $i) + ForEach ($isofile_ in $OutputVariable) { + $CurrentItem = ($isofile_ -replace '\s+', ' ').split(':') + $CurrentItemName = $CurrentItem[0] -replace ' ', '' + if (($CurrentItem[1] -replace ' ', '') -ne '') { + if ($CurrentItemName -eq 'Flags') { + if ($CurrentItem[1].Substring(1) -ne "Windows Foundation") { + $WIMInfo[$i]["EditionID"] = $CurrentItem[1].Substring(1) + $lastedition = $CurrentItem[1].Substring(1) + $editions += $CurrentItem[1].Substring(1) + } + } } - $result.Type = 'server' - } elseif ($editionletter -eq 'l') { - $result.Sku = 'Smallbusiness' - $result.Type = 'server' - } elseif ($editionletter -eq 'd') { - $result.Sku = 'Datacenter' - $result.Type = 'server' - } else { - $result.Sku = $editionletter - $result.Type = 'unknown' - } - } - } - - $result.LanguageCode = $langcodes[(Get-item $letter'\setup.exe').VersionInfo.Language] - - if ((Get-item $letter\setup.exe).VersionInfo.IsDebug) { - $result.BuildType = 'chk' - } else { - $result.BuildType = 'fre' - } - $result.Architecture = (Test-Arch $letter'\sources\setup.exe').FileType - - $result.Editions = $result.Sku - - (& 'bin\7z' l -i!*\ntldr $letter\sources\install.wim) | % { if ($_ -like '*ntldr*') { $wimindex = $_.split(' \')[-2] } } - - # Gathering Compiledate and the buildbranch from the ntoskrnl executable. - Write-Host 'Checking critical system files for a build string and build type information...' - & 'bin\7z' x $letter'\sources\install.wim' "$($wimindex)\windows\system32\ntkrnlmp.exe" | out-null - & 'bin\7z' x $letter'\sources\install.wim' "$($wimindex)\windows\system32\ntoskrnl.exe" | out-null - if (Test-Path .\$wimindex\windows\system32\ntkrnlmp.exe) { - $result.CompileDate = (Get-item .\$wimindex\windows\system32\ntkrnlmp.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') - $result.BranchName = (Get-item .\$wimindex\windows\system32\ntkrnlmp.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) - if ((Get-item .\$wimindex\windows\system32\ntkrnlmp.exe).VersionInfo.IsDebug) { - $result.BuildType = 'chk' - } else { - $result.BuildType = 'fre' - } - $ProductVersion = (Get-item .\$wimindex\windows\system32\ntkrnlmp.exe).VersionInfo.ProductVersion - remove-item .\$wimindex\windows\system32\ntkrnlmp.exe -force - } elseif (Test-Path .\$wimindex\windows\system32\ntoskrnl.exe) { - $result.CompileDate = (Get-item .\$wimindex\windows\system32\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') - $result.BranchName = (Get-item .\$wimindex\windows\system32\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) - if ((Get-item .\$wimindex\windows\system32\ntoskrnl.exe).VersionInfo.IsDebug) { - $result.BuildType = 'chk' - } else { - $result.BuildType = 'fre' - } - $ProductVersion = (Get-item .\$wimindex\windows\system32\ntoskrnl.exe).VersionInfo.ProductVersion - remove-item .\$wimindex\windows\system32\ntoskrnl.exe -force - } - - $result.MajorVersion = $ProductVersion.split('.')[0] - $result.MinorVersion = $ProductVersion.split('.')[1] - $result.BuildNumber = $ProductVersion.split('.')[2] - $result.DeltaVersion = $ProductVersion.split('.')[3] - - # Gathering Compiledate and the buildbranch from the build registry. - Write-Host 'Checking registry for a more accurate build string...' - & 'bin\7z' x $letter'\sources\install.wim' "$($wimindex)\windows\system32\config\" | out-null - & 'reg' load HKLM\RenameISOs .\$wimindex\windows\system32\config\SOFTWARE | out-null - $output = ( & 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion" /v "BuildLab") - if (($output -ne $null) -and ($output[2] -ne $null) -and (-not ($output[2].Split(' ')[-1].Split('.')[-1]) -eq '')) { - $result.CompileDate = $output[2].Split(' ')[-1].Split('.')[-1] - $result.BranchName = $output[2].Split(' ')[-1].Split('.')[-2] - $output_ = ( & 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion" /v "BuildLabEx") - if (($output_[2] -ne $null) -and (-not ($output_[2].Split(' ')[-1].Split('.')[-1]) -eq '')) { - if ($output_[2].Split(' ')[-1] -like '*.*.*.*.*') { - $result.BuildNumber = $output_[2].Split(' ')[-1].Split('.')[0] - $result.DeltaVersion = $output_[2].Split(' ')[-1].Split('.')[1] } } - } else { - Write-Host 'Registry check was unsuccessful. Aborting and continuing with critical system files build string...' - } - & 'reg' unload HKLM\RenameISOs | out-null - - & 'reg' load HKLM\RenameISOs .\$wimindex\windows\system32\config\SYSTEM | out-null - $ProductSuite = ( Get-ItemProperty -Path HKLM:\RenameISOs\ControlSet001\Control\ProductOptions -Name ProductSuite).ProductSuite - $ProductType = ( Get-ItemProperty -Path HKLM:\RenameISOs\ControlSet001\Control\ProductOptions -Name ProductType).ProductType - Write-Host $ProductSuite - Write-Host $ProductType - - if ($ProductType -eq 'ServerNT') { - $result.Type = 'server' - } else { - $result.Type = 'client' } - if ($ProductSuite -is [System.Array]) { - if ($ProductSuite[0] -ne '') { - $result.Sku = $ProductSuite[0] - } else { - $result.Sku = 'Professional' - } - } elseif ($ProductSuite -ne '') { - $result.Sku = $ProductSuite - } else { - $result.Sku = 'Professional' + $result.Editions = $editions + + # Converting standards architecture names to friendly ones, if we didn't found any, we put the standard one instead * cough * arm / ia64, + # Yes, IA64 is still a thing for server these days... + if ($WIMInfo[1].Architecture -eq 'x86') { + $result.Architecture = 'x86' + } elseif ($WIMInfo[1].Architecture -eq 'x86_64') { + $result.Architecture = 'amd64' + } else { + $result.Architecture = $WIMInfo[1].Architecture + } + + # Gathering Compiledate and the buildbranch from the ntoskrnl executable. + Write-Host 'Checking critical system files for a build string and build type information...' + & $wimlib extract $WIM 1 windows\system32\ntkrnlmp.exe windows\system32\ntoskrnl.exe --nullglob --no-acls | Out-Null + if (Test-Path .\ntkrnlmp.exe) { + $result.CompileDate = (Get-Item .\ntkrnlmp.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')','') + $result.BranchName = (Get-Item .\ntkrnlmp.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + if ((Get-Item .\ntkrnlmp.exe).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $ProductVersion = (Get-Item .\ntkrnlmp.exe).VersionInfo.ProductVersion + Remove-Item .\ntkrnlmp.exe -Force + } elseif (Test-Path .\ntoskrnl.exe) { + $result.CompileDate = (Get-Item .\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')','') + $result.BranchName = (Get-Item .\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + if ((Get-Item .\ntoskrnl.exe).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $ProductVersion = (Get-Item .\ntoskrnl.exe).VersionInfo.ProductVersion + Remove-Item .\ntoskrnl.exe -Force + } + + $result.MajorVersion = $ProductVersion.split('.')[0] + $result.MinorVersion = $ProductVersion.split('.')[1] + $result.BuildNumber = $ProductVersion.split('.')[2] + $result.DeltaVersion = $ProductVersion.split('.')[3] + + $result.Licensing = 'Retail' + + # Gathering Compiledate and the buildbranch from the build registry. + Write-Host 'Checking registry for a more accurate build string and licensing information...' + & $wimlib extract $WIM 1 windows\system32\config\ --no-acls | Out-Null + & 'reg' load HKLM\RenameISOs .\config\SOFTWARE | Out-Null + $output = (& 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion" /v "BuildLab") + if (($output[2] -ne $null) -and (-not ($output[2].split(' ')[-1].split('.')[-1]) -eq '')) { + $result.CompileDate = $output[2].split(' ')[-1].split('.')[-1] + $result.BranchName = $output[2].split(' ')[-1].split('.')[-2] + $output_ = (& 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion" /v "BuildLabEx") + if (($output_[2] -ne $null) -and (-not ($output_[2].split(' ')[-1].split('.')[-1]) -eq '')) { + if ($output_[2].split(' ')[-1] -like '*.*.*.*.*') { + $result.BuildNumber = $output_[2].split(' ')[-1].split('.')[0] + $result.DeltaVersion = $output_[2].split(' ')[-1].split('.')[1] + } + } + } else { + Write-Host 'Registry check for buildstring was unsuccessful. Aborting and continuing with critical system files build string...' + } + $output = (& 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion\DefaultProductKey" /v "ProductId") + if ($output -ne $null) { + if ($output[2] -ne $null) { + $var = $output[2].split(' ')[-1].Substring($output[2].split(' ')[-1].Length - 3,3) + if ($var.toUpper() -eq "OEM") { + $result.Licensing = "oem" + } } - $result.Editions = $result.Sku - - & 'reg' unload HKLM\RenameISOs | out-null - - remove-item .\$wimindex\windows\system32\config\ -recurse -force - - remove-item .\$wimindex\ -recurse -force - - - Write-Host "Dismounting $($isofile)..." - get-DiskImage -ImagePath $isofile.fullname | Dismount-DiskImage - - } elseif ((Test-Path ($letter+'\setup.exe')) -and (Test-Path ($letter+'\ia64\txtsetup.sif'))) { - - $result = get-i386infos $letter 'ia64' $result.VolumeLabel - - } elseif ((Test-Path ($letter+'\setup.exe')) -and (Test-Path ($letter+'\amd64\txtsetup.sif'))) { - - $result = get-i386infos $letter 'amd64' $result.VolumeLabel - - } elseif ((Test-Path ($letter+'\i386\ntoskrnl.ex_')) -and (Test-Path ($letter+'\i386\txtsetup.sif'))) { - - $result = get-i386infos $letter 'i386' $result.VolumeLabel - - } elseif ((Test-Path ($letter+'\i386\ntoskrnl.exe')) -and (Test-Path ($letter+'\i386\txtsetup.sif'))) { + } + + & 'reg' unload HKLM\RenameISOs | Out-Null + Remove-Item .\config\ -Recurse -Force + - $result = get-i386infos $letter 'i386' $result.VolumeLabel - - } elseif ((Test-Path ($letter+'\i386\NTKRNLMP.ex_')) -and (Test-Path ($letter+'\i386\txtsetup.sif'))) { - $result = get-i386infos $letter 'i386' $result.VolumeLabel - - } elseif ((Test-Path ($letter+'\i386\NTKRNLMP.exe')) -and (Test-Path ($letter+'\i386\txtsetup.sif'))) { + # Defining if server or client thanks to Microsoft including 'server' in the server sku names + if (($WIMInfo[1].EditionID) -eq $null) { + $result.Type = 'client' + $result.Sku = 'unstaged' + } elseif (($WIMInfo[1].EditionID.toLower()) -like '*server*') { + $result.Type = 'server' + $result.Sku = $WIMInfo[1].EditionID.toLower() -replace 'server','' + } else { + $result.Type = 'client' + $result.Sku = $WIMInfo[1].EditionID.toLower() + } - $result = get-i386infos $letter 'i386' $result.VolumeLabel - - } elseif ((Test-Path ($letter+'\alpha\ntoskrnl.exe')) -and (Test-Path ($letter+'\alpha\txtsetup.sif'))) { - - $result = get-i386infos $letter 'alpha' $result.VolumeLabel - - } elseif ((Test-Path ($letter+'\alpha\ntoskrnl.ex_')) -and (Test-Path ($letter+'\alpha\txtsetup.sif'))) { - - $result = get-i386infos $letter 'alpha' $result.VolumeLabel - - } elseif (((Get-ChildItem $letter\*WIN*.CAB -Recurse) | where-object {(($_.FullName).Split('\').Count) -le 4}) -ne $null) { - $cab = ((Get-ChildItem $letter\*WIN*.CAB -Recurse) | where-object {(($_.FullName).Split('\').Count) -le 4})[1] - $result.Type = 'client' - if ((Get-ChildItem ($cab.directory.fullname+'\USER.EXE') -Recurse) -ne $null) { - $result.BuildType = 'chk' - } else { - $result.BuildType = 'fre' - } - & 'bin\7z' e $cab user.exe | out-null - $result.MajorVersion = ((Get-item .\user.exe).VersionInfo.ProductVersion).split('.')[0] - $result.MinorVersion = ((Get-item .\user.exe).VersionInfo.ProductVersion).split('.')[1] - $result.BuildNumber = ((Get-item .\user.exe).VersionInfo.ProductVersion).split('.')[2] - $result.Architecture = 'X86' - $result.LanguageCode = $langcodes[(Get-item .\user.exe).VersionInfo.Language] - Remove-Item -force .\user.exe - - - # Hotfix for a MS derping on the 347 Spanish version of Windows 95, the OS is technically 347, but for some reason, - # kernel386, gdi, and user are reporting 346 as the build number. While win32 components, (kernel32, gdi32, user32) - # reports 347, as it should be. If you have any doubt, you can find this 347 spanish build on the multilang dvd of 347. - if (($result.LanguageCode -eq 'es-ES_tradnl') -and ($result.BuildNumber -eq '346')) { - $result.BuildNumber = '347' - } - - if ($result.BuildNumber -eq '950') { - & 'bin\7z' e $cab kernel32.dll | out-null - $result.MajorVersion = ((Get-item .\kernel32.dll).VersionInfo.ProductVersion).split('.')[0] - $result.MinorVersion = ((Get-item .\kernel32.dll).VersionInfo.ProductVersion).split('.')[1] - $result.BuildNumber = ((Get-item .\kernel32.dll).VersionInfo.ProductVersion).split('.')[2] - Remove-Item -force .\kernel32.dll - } - - $paths = @() - ((Get-ChildItem $letter\*WIN*.CAB -Recurse) | where-object {(($_.FullName).Split('\').Count) -le 4}) | foreach-object -process { - if (-not ($paths -contains $_.directory.fullname)) { - $paths += $_.directory.fullname - } - } - - if ($paths.count -gt 1) { - $result.LanguageCode = 'multi' - } - - if (Test-Path ($cab.directory.fullname+'.\SETUPPP.INF')) { - if (((get-inicontent ($cab.directory.fullname+'.\SETUPPP.INF'))["Strings"]) -ne $null) { - if (((get-inicontent ($cab.directory.fullname+'.\SETUPPP.INF'))["Strings"]["SubVersionString"]) -ne $null) { - $subver = (get-inicontent ($cab.directory.fullname+'.\SETUPPP.INF'))["Strings"]["SubVersionString"].replace('"', '') - if ($subver -like '*;*') { - $subver = $subver.split(';')[0] - } - - $subver = Remove-InvalidFileNameChars($subver) - $subver = $subver.Split(' ') - - foreach ($item in $subver) { - if ($item -ne '') { - if ($item -like '.*') { - $result.DeltaVersion = $item.substring(1) - } elseif (($item.Length -eq 1) -and (-not ($item -match "[0-9]"))) { - $result.BuildNumber = ($result.BuildNumber+$item) - } else { - if ($result.Tag -eq $null) { - $result.Tag = $item - } else { - $result.Tag = ($result.Tag+'_'+$item) - } - } - } - } - } - } - } else { - & 'bin\7z' e $cab.directory.fullname'\PRECOPY2.CAB' SETUPPP.INF | out-null - if (((get-inicontent '.\SETUPPP.INF')["Strings"]) -ne $null) { - if (((get-inicontent '.\SETUPPP.INF')["Strings"]["SubVersionString"]) -ne $null) { - $subver = (get-inicontent '.\SETUPPP.INF')["Strings"]["SubVersionString"].replace('"', '') - if ($subver -like '*;*') { - $subver = $subver.split(';')[0] - } - - if ($subver -ne '') { - $subver = Remove-InvalidFileNameChars($subver) - $subver = $subver.Split(' ') - - foreach ($item in $subver) { - if ($item -ne '') { - if ($item -like '.*') { - $result.DeltaVersion = $item.substring(1) - } elseif (($item.Length -eq 1) -and (-not ($item -match "[0-9]"))) { - $result.BuildNumber = ($result.BuildNumber+$item) - } else { - if ($result.Tag -eq $null) { - $result.Tag = $item - } else { - $result.Tag = ($result.Tag+'_'+$item) - } - } - } - } - } - } - } - Remove-Item -force '.\SETUPPP.INF' - } - - Write-Host "Dismounting $($isofile)..." - get-DiskImage -ImagePath $isofile.fullname | Dismount-DiskImage - } elseif ((Get-ChildItem $letter\*CHICO*.CAB -Recurse) -ne $null) { - $cab = (Get-ChildItem $letter\*CHICO*.CAB -Recurse)[1] - $result.Type = 'client' - if ((Get-ChildItem ($cab.directory.fullname+'\USER.EXE') -Recurse) -ne $null) { - $result.BuildType = 'chk' + if ($WIMInfo.header.ImageCount -gt 1) { + if ($WIMInfo[1].EditionID -eq $null) { + $result.Type = 'client' + $result.Sku = 'unstaged' + } elseif (($WIMInfo[1].EditionID.toLower()) -like '*server*') { + $result.Type = 'server' + $result.Sku = $null } else { - $result.BuildType = 'fre' - } - & 'bin\7z' e $cab user.exe | out-null - $result.MajorVersion = ((Get-item .\user.exe).VersionInfo.ProductVersion).split('.')[0] - $result.MinorVersion = ((Get-item .\user.exe).VersionInfo.ProductVersion).split('.')[1] - $result.BuildNumber = ((Get-item .\user.exe).VersionInfo.ProductVersion).split('.')[2] - $result.Architecture = 'x86' - Remove-Item .\user.exe -force - & 'bin\7z' e $cab shell32.dll | out-null - & 'bin\7z' e .\shell32.dll .rsrc\version.txt | out-null - (get-content .\version.txt) | foreach-object -process { - $_ = Remove-InvalidFileNameChars($_) - if ($_ -like ('*Translation*')) { - $langdata = $_.split(',')[1].Trim() - $result.LanguageCode = [System.Globalization.Cultureinfo]::GetCultureInfo([int32]$langdata).Name - } - } - - Remove-Item '.\version.txt' -force - Remove-Item .\shell32.dll -force - - $paths = @() - (Get-ChildItem $letter\*CHICO*.CAB -Recurse) | foreach-object -process { - if (-not ($paths -contains $_.directory.fullname)) { - $paths += $_.directory.fullname - } - } - - if ($paths.count -gt 1) { - $result.LanguageCode = 'multi' - } - - & 'bin\7z' e $cab.directory.fullname'\PRECOPY2.CAB' SETUPPP.INF | out-null - if (((get-inicontent '.\SETUPPP.INF')["Strings"]) -ne $null) { - if (((get-inicontent '.\SETUPPP.INF')["Strings"]["SubVersionString"]) -ne $null) { - $subver = (get-inicontent '.\SETUPPP.INF')["Strings"]["SubVersionString"].replace('"', '').replace(' ', '').replace('-', '') - if ($subver -like '*;*') { - $subver = $subver.split(';')[0] - } - if ($subver -ne '') { - $result.BuildNumber = ($result.BuildNumber+'_'+$subver) - } - } + $result.Type = 'client' + $result.Sku = $null } - Remove-Item '.\SETUPPP.INF' -force - - Write-Host "Dismounting $($isofile)..." - get-DiskImage -ImagePath $isofile.fullname | Dismount-DiskImage - } else { - Write-Host "The ISO is unknown!" - Write-Host "Dismounting $($isofile)..." - get-DiskImage -ImagePath $isofile.fullname | Dismount-DiskImage - return $null - } - if ($result.BuildNumber -eq $null) { - Write-Host "The ISO is unknown!" - return $null } - return $result -} -function get-BetterISOFilename($item) { - $results = ISO-Identify($item) - Write-Host $results - if ($results -eq $null) { - return $null - } + if (Test-Path "$($letter)\sources\ei.cfg") { + $content = @() + Get-Content ("$($letter)\sources\ei.cfg") | ForEach-Object -Process { + $content += $_ + } + $counter = 0 + foreach ($item in $content) { + $counter++ + if ($item -eq '[EditionID]') { + $result.Sku = $content[$counter] + } + } + $counter = 0 + foreach ($item in $content) { + $counter++ + if ($item -eq '[Channel]') { + $result.Licensing = $content[$counter] + } + } + } + + if (($WIMInfo.header.ImageCount -eq 4) -and ($result.Type -eq 'server')) { + $result.Sku = $null + } + + Get-Content ("$($letter)\sources\lang.ini") | ForEach-Object -Begin { $h = @() } -Process { $k = [regex]::split($_,'`r`n'); if (($k[0].CompareTo("") -ne 0)) { $h += $k[0] } } + $result.LanguageCode = ($h[((0..($h.Count - 1) | Where { $h[$_] -eq '[Available UI Languages]' }) + 1)]).split('=')[0].Trim() + + $result.BuildString = ($result.MajorVersion + '.' + $result.MinorVersion + '.' + $result.BuildNumber + '.' + $result.DeltaVersion + '.' + $result.BranchName + '.' + $result.CompileDate) + $result.SetupPath = $letter - switch ($scheme) { - 0 { - if ($results.Sku -eq $null) { - $identifier = $results.Type - } else { - $identifier = $results.Type+'-'+$results.Sku - } - - if ($results.Licensing -ne $null) { - $identifier = $identifier+'_'+$results.Licensing - } - - $filename = $results.MajorVersion+'.'+$results.MinorVersion+'.'+$results.BuildNumber - - if (-not ($results.DeltaVersion -eq $null)) { - $filename = $filename+'.'+$results.DeltaVersion - } - - if (-not ($results.BranchName -eq $null)) { - $filename = $filename+'.'+$results.BranchName - } - - if (-not ($results.CompileDate -eq $null)) { - $filename = $filename+'.'+$results.CompileDate - } - - if (-not ($results.Tag -eq $null)) { - $filename = $filename+'_'+$results.Tag - } - - $filename = $filename+'_'+$results.Architecture+$results.BuildType+'_'+$identifier+'_'+$results.LanguageCode - $filename = $filename.toLower() - - - if ($addLabel) { - $filename = $filename+'-'+$results.VolumeLabel - } - $filename = $filename+'.iso' - } - 1 { - $Edition = $null - $Licensing = $null - - foreach ($item_ in $results.Editions) { - if ($Edition -eq $null) { - $Licensing = 'RET' - $Edition_ = $item_ - if ($item_ -eq 'Core') {$Edition_ = 'CORE'} - if ($item_ -eq 'CoreN') {$Edition_ = 'COREN'} - if ($item_ -eq 'CoreSingleLanguage') {$Edition_ = 'SINGLELANGUAGE'} - if ($item_ -eq 'CoreCountrySpecific') {$Edition_ = 'CHINA'} - if ($item_ -eq 'Professional') {$Edition_ = 'PRO'} - if ($item_ -eq 'ProfessionalN') {$Edition_ = 'PRON'} - if ($item_ -eq 'ProfessionalWMC') {$Edition_ = 'PROWMC'} - if ($item_ -eq 'CoreConnected') {$Edition_ = 'CORECONNECTED'} - if ($item_ -eq 'CoreConnectedN') {$Edition_ = 'CORECONNECTEDN'} - if ($item_ -eq 'CoreConnectedSingleLanguage') {$Edition_ = 'CORECONNECTEDSINGLELANGUAGE'} - if ($item_ -eq 'CoreConnectedCountrySpecific') {$Edition_ = 'CORECONNECTEDCHINA'} - if ($item_ -eq 'ProfessionalStudent') {$Edition_ = 'PROSTUDENT'} - if ($item_ -eq 'ProfessionalStudentN') {$Edition_ = 'PROSTUDENTN'} - if ($item_ -eq 'Enterprise') { - $Licensing = 'VOL' - $Edition_ = 'ENTERPRISE' - } - $Edition = $Edition_ - } else { - $Edition_ = $item_ - if ($item_ -eq 'Core') {$Edition_ = 'CORE'} - if ($item_ -eq 'CoreN') {$Edition_ = 'COREN'} - if ($item_ -eq 'CoreSingleLanguage') {$Edition_ = 'SINGLELANGUAGE'} - if ($item_ -eq 'CoreCountrySpecific') {$Edition_ = 'CHINA'} - if ($item_ -eq 'Professional') {$Edition_ = 'PRO'} - if ($item_ -eq 'ProfessionalN') {$Edition_ = 'PRON'} - if ($item_ -eq 'ProfessionalWMC') {$Edition_ = 'PROWMC'} - if ($item_ -eq 'CoreConnected') {$Edition_ = 'CORECONNECTED'} - if ($item_ -eq 'CoreConnectedN') {$Edition_ = 'CORECONNECTEDN'} - if ($item_ -eq 'CoreConnectedSingleLanguage') {$Edition_ = 'CORECONNECTEDSINGLELANGUAGE'} - if ($item_ -eq 'CoreConnectedCountrySpecific') {$Edition_ = 'CORECONNECTEDCHINA'} - if ($item_ -eq 'ProfessionalStudent') {$Edition_ = 'PROSTUDENT'} - if ($item_ -eq 'ProfessionalStudentN') {$Edition_ = 'PROSTUDENTN'} - if ($item_ -eq 'Enterprise') { - $Licensing = $Licensing+'VOL' - $Edition_ = 'ENTERPRISE' - } - $Edition = $Edition+'-'+$Edition_ - } - } - - if ($results.Type.toLower() -eq 'server') { - $Edition = $Edition.toUpper() -replace 'SERVERHYPER', 'SERVERHYPERCORE' -replace 'SERVER', '' - } - - if ($results.Licensing.toLower() -eq 'volume') { - $Licensing = 'VOL' - } elseif ($results.Licensing.toLower() -eq 'oem') { - $Licensing = 'OEM' - } elseif ($Licensing -eq $null) { - $Licensing = 'RET' - } - - if ($Edition -contains 'PRO-CORE') { - $Licensing = $Licensing -replace 'RET', 'OEMRET' - } elseif ($results.Sku -eq $null -and $results.Type.toLower() -eq 'server') { - $Edition = '' - if ($results.Licensing.toLower() -eq 'retail') { - $Licensing = 'OEMRET' - } - if ($results.Licensing.toLower() -eq 'retail' -and [int]$results.BuildNumber -lt 9900) { - $Licensing = 'OEM' - } - } elseif ($results.Editions.Count -eq 1 -and $results.Type.toLower() -eq 'server') { - $Licensing = 'OEM' - } - - if ([int]$results.BuildNumber -lt 8008) { - $Edition = $results.Sku - } - - if ($Edition -eq 'unstaged') { - $Edition = '' - } - - $arch = $results.Architecture -replace 'amd64', 'x64' - if ($results.BranchName -eq $null) { - $FILENAME = ($results.BuildNumber+'.'+$results.DeltaVersion) - } else { - $FILENAME = ($results.BuildNumber+'.'+$results.DeltaVersion+'.'+$results.CompileDate+'.'+$results.BranchName) - } - - $FILENAME = ($FILENAME+'_'+$results.Type+$Edition+'_'+$Licensing+'_'+$arch+$results.BuildType+'_'+$results.LanguageCode) - - if ($addLabel) { - $filename = $filename+'-'+$results.VolumeLabel - } - $filename = ($filename+'.iso').ToUpper() - } - 2 { - if ($results.LanguageCode -eq 'en-gb') { - $lang = 'en-gb' - } elseif ($results.LanguageCode -eq 'es-mx') { - $lang = 'es-mx' - } elseif ($results.LanguageCode -eq 'fr-ca') { - $lang = 'fr-ca' - } elseif ($results.LanguageCode -eq 'pt-pt') { - $lang = 'pp' - } elseif ($results.LanguageCode -eq 'sr-latn-rs') { - $lang = 'sr-latn' - } elseif ($results.LanguageCode -eq 'zh-cn') { - $lang = 'cn' - } elseif ($results.LanguageCode -eq 'zh-tw') { - $lang = 'tw' - } elseif ($results.LanguageCode -eq 'zh-hk') { - $lang = 'hk' - } else { - $lang = $results.LanguageCode.split('-')[0] - } - - $arch = $results.Architecture - $EditionID = $null - - foreach ($item_ in $results.Editions) { - if ($EditionID -eq $null) { - $EditionID = $item_ - } else { - $EditionID = $EditionID+'-'+$item_ - } - } - - if ($results.BranchName -ne $null) { - $filename = ($lang.toLower())+'_'+$results.BuildNumber+'.'+$results.DeltaVersion+'.'+$results.BranchName+'.'+$results.CompileDate+'_'+$arch+$results.BuildType+'_'+$results.Sku+'_'+($results.LanguageCode.toLower())+'_'+$EditionID+'-'+$results.VolumeLabel+'.iso' - if ($EditionID.toLower() -eq 'enterprise') {$filename = ($lang.toLower())+'_'+$results.BuildNumber+'.'+$results.DeltaVersion+'.'+$results.BranchName+'.'+$results.CompileDate+'_'+$arch+$results.BuildType+'_'+$results.Sku+'_'+($results.LanguageCode.toLower())+'_VL_'+$EditionID+'-'+$results.VolumeLabel+'.iso'} - if ($EditionID.toLower() -eq 'enterprisen') {$filename = ($lang.toLower())+'_'+$results.BuildNumber+'.'+$results.DeltaVersion+'.'+$results.BranchName+'.'+$results.CompileDate+'_'+$arch+$results.BuildType+'_'+$results.Sku+'_'+($results.LanguageCode.toLower())+'_VL_'+$EditionID+'-'+$results.VolumeLabel+'.iso'} - } else { - $filename = ($lang.toLower())+'_'+$results.BuildNumber+'.'+$results.DeltaVersion+'.'+$results.CompileDate+'_'+$arch+$results.BuildType+'_'+$results.Sku+'_'+($results.LanguageCode.toLower())+'_'+$EditionID+'-'+$results.VolumeLabel+'.iso' - if ($EditionID.toLower() -eq 'enterprise') {$filename = ($lang.toLower())+'_'+$results.BuildNumber+'.'+$results.DeltaVersion+'_'+$arch+$results.BuildType+'_'+$results.Sku+'_'+($results.LanguageCode.toLower())+'_VL_'+$EditionID+'-'+$results.VolumeLabel+'.iso'} - if ($EditionID.toLower() -eq 'enterprisen') {$filename = ($lang.toLower())+'_'+$results.BuildNumber+'.'+$results.DeltaVersion+'_'+$arch+$results.BuildType+'_'+$results.Sku+'_'+($results.LanguageCode.toLower())+'_VL_'+$EditionID+'-'+$results.VolumeLabel+'.iso'} - } - } - } - Write-Host "Found: $($filename)" - return $filename + Write-Host "Dismounting $($isofile)..." + Get-DiskImage -ImagePath $isofile.fullname | Dismount-DiskImage + + } elseif ((Test-Path ($letter + '\setup.exe')) -and (Test-Path ($letter + '\sources\setup.exe'))) { + + $buildno = (Get-Item $letter\setup.exe).VersionInfo.ProductVersion + + $result.MajorVersion = $buildno.split('.')[0] + $result.MinorVersion = $buildno.split('.')[1] + $result.BuildNumber = $buildno.split('.')[2] + $result.DeltaVersion = $buildno.split('.')[3] + + # Gathering Compiledate and the buildbranch from the main setup.exe executable. + $result.CompileDate = (Get-Item $letter\setup.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')','') + $result.BranchName = (Get-Item $letter\setup.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + + if (Test-Path $letter'\sources\product.ini') { + $result.Sku = (get-inicontent ($letter + '\sources\product.ini'))["No-Section"]["skuid"].replace(' ','') + if ($result.Sku -eq 'pro') { + $result.Sku = 'Professional' + $result.Type = 'Client' + } + } else { + $files = (Get-ChildItem $letter\* | Where-Object { -not ([System.IO.Path]::hasExtension($_.fullname)) -and -not ($_.PSIsContainer) }) + if ($files -ne $null) { + + $editionletter = $files[-1].Name.toLower() + + $editionletter = $editionletter.replace('cdrom.','') + $editionletter_ = $editionletter.split('.')[0][-2] + $editionletter = $editionletter.split('.')[0][-1] + + if ($editionletter -eq 'p') { + $result.Sku = 'Professional' + $result.Type = 'client' + } elseif ($editionletter -eq 'c') { + $result.Sku = 'Home' + $result.Type = 'client' + } elseif ($editionletter -eq 'w') { + $result.Sku = 'Workstation' + $result.Type = 'client' + } elseif ($editionletter -eq 'b') { + $result.Sku = 'Web' + $result.Type = 'server' + } elseif ($editionletter -eq 's') { + $result.Sku = 'Standard' + if ($editionletter_ -eq 't') { + $result.Sku = 'Terminal' + } + $result.Type = 'server' + } elseif ($editionletter -eq 'a') { + if ($result.BuildNumber.split('.')[2] -le 2202) { + $result.Sku = 'Advanced' + } else { + $result.Sku = 'Enterprise' + } + $result.Type = 'server' + } elseif ($editionletter -eq 'l') { + $result.Sku = 'Smallbusiness' + $result.Type = 'server' + } elseif ($editionletter -eq 'd') { + $result.Sku = 'Datacenter' + $result.Type = 'server' + } else { + $result.Sku = $editionletter + $result.Type = 'unknown' + } + } + } + + $result.LanguageCode = $langcodes[(Get-Item $letter'\setup.exe').VersionInfo.Language] + + if ((Get-Item $letter\setup.exe).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $result.Architecture = (Test-Arch $letter'\sources\setup.exe').FileType + + $result.Editions = $result.Sku + + (& 'bin\7z' l -i!*\ntldr $letter\sources\install.wim) | % { if ($_ -like '*ntldr*') { $wimindex = $_.split(' \')[-2] } } + + # Gathering Compiledate and the buildbranch from the ntoskrnl executable. + Write-Host 'Checking critical system files for a build string and build type information...' + & 'bin\7z' x $letter'\sources\install.wim' "$($wimindex)\windows\system32\ntkrnlmp.exe" | Out-Null + & 'bin\7z' x $letter'\sources\install.wim' "$($wimindex)\windows\system32\ntoskrnl.exe" | Out-Null + if (Test-Path .\$wimindex\windows\system32\ntkrnlmp.exe) { + $result.CompileDate = (Get-Item .\$wimindex\windows\system32\ntkrnlmp.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')','') + $result.BranchName = (Get-Item .\$wimindex\windows\system32\ntkrnlmp.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + if ((Get-Item .\$wimindex\windows\system32\ntkrnlmp.exe).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $ProductVersion = (Get-Item .\$wimindex\windows\system32\ntkrnlmp.exe).VersionInfo.ProductVersion + Remove-Item .\$wimindex\windows\system32\ntkrnlmp.exe -Force + } elseif (Test-Path .\$wimindex\windows\system32\ntoskrnl.exe) { + $result.CompileDate = (Get-Item .\$wimindex\windows\system32\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')','') + $result.BranchName = (Get-Item .\$wimindex\windows\system32\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + if ((Get-Item .\$wimindex\windows\system32\ntoskrnl.exe).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $ProductVersion = (Get-Item .\$wimindex\windows\system32\ntoskrnl.exe).VersionInfo.ProductVersion + Remove-Item .\$wimindex\windows\system32\ntoskrnl.exe -Force + } + + $result.MajorVersion = $ProductVersion.split('.')[0] + $result.MinorVersion = $ProductVersion.split('.')[1] + $result.BuildNumber = $ProductVersion.split('.')[2] + $result.DeltaVersion = $ProductVersion.split('.')[3] + + # Gathering Compiledate and the buildbranch from the build registry. + Write-Host 'Checking registry for a more accurate build string...' + & 'bin\7z' x $letter'\sources\install.wim' "$($wimindex)\windows\system32\config\" | Out-Null + & 'reg' load HKLM\RenameISOs .\$wimindex\windows\system32\config\SOFTWARE | Out-Null + $output = (& 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion" /v "BuildLab") + if (($output -ne $null) -and ($output[2] -ne $null) -and (-not ($output[2].split(' ')[-1].split('.')[-1]) -eq '')) { + $result.CompileDate = $output[2].split(' ')[-1].split('.')[-1] + $result.BranchName = $output[2].split(' ')[-1].split('.')[-2] + $output_ = (& 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion" /v "BuildLabEx") + if (($output_[2] -ne $null) -and (-not ($output_[2].split(' ')[-1].split('.')[-1]) -eq '')) { + if ($output_[2].split(' ')[-1] -like '*.*.*.*.*') { + $result.BuildNumber = $output_[2].split(' ')[-1].split('.')[0] + $result.DeltaVersion = $output_[2].split(' ')[-1].split('.')[1] + } + } + } else { + Write-Host 'Registry check was unsuccessful. Aborting and continuing with critical system files build string...' + } + & 'reg' unload HKLM\RenameISOs | Out-Null + + & 'reg' load HKLM\RenameISOs .\$wimindex\windows\system32\config\SYSTEM | Out-Null + $ProductSuite = (Get-ItemProperty -Path HKLM:\RenameISOs\ControlSet001\Control\ProductOptions -Name ProductSuite).ProductSuite + $ProductType = (Get-ItemProperty -Path HKLM:\RenameISOs\ControlSet001\Control\ProductOptions -Name ProductType).ProductType + Write-Host $ProductSuite + Write-Host $ProductType + + if ($ProductType -eq 'ServerNT') { + $result.Type = 'server' + } else { + $result.Type = 'client' + } + + if ($ProductSuite -is [System.Array]) { + if ($ProductSuite[0] -ne '') { + $result.Sku = $ProductSuite[0] + } else { + $result.Sku = 'Professional' + } + } elseif ($ProductSuite -ne '') { + $result.Sku = $ProductSuite + } else { + $result.Sku = 'Professional' + } + $result.Editions = $result.Sku + + & 'reg' unload HKLM\RenameISOs | Out-Null + + Remove-Item .\$wimindex\windows\system32\config\ -Recurse -Force + + Remove-Item .\$wimindex\ -Recurse -Force + + + Write-Host "Dismounting $($isofile)..." + Get-DiskImage -ImagePath $isofile.fullname | Dismount-DiskImage + + } elseif ((Test-Path ($letter + '\setup.exe')) -and (Test-Path ($letter + '\ia64\txtsetup.sif'))) { + + $result = get-i386infos $letter 'ia64' $result.VolumeLabel + + } elseif ((Test-Path ($letter + '\setup.exe')) -and (Test-Path ($letter + '\amd64\txtsetup.sif'))) { + + $result = get-i386infos $letter 'amd64' $result.VolumeLabel + + } elseif ((Test-Path ($letter + '\i386\ntoskrnl.ex_')) -and (Test-Path ($letter + '\i386\txtsetup.sif'))) { + + $result = get-i386infos $letter 'i386' $result.VolumeLabel + + } elseif ((Test-Path ($letter + '\i386\ntoskrnl.exe')) -and (Test-Path ($letter + '\i386\txtsetup.sif'))) { + + $result = get-i386infos $letter 'i386' $result.VolumeLabel + + } elseif ((Test-Path ($letter + '\i386\NTKRNLMP.ex_')) -and (Test-Path ($letter + '\i386\txtsetup.sif'))) { + + $result = get-i386infos $letter 'i386' $result.VolumeLabel + + } elseif ((Test-Path ($letter + '\i386\NTKRNLMP.exe')) -and (Test-Path ($letter + '\i386\txtsetup.sif'))) { + + $result = get-i386infos $letter 'i386' $result.VolumeLabel + + } elseif ((Test-Path ($letter + '\alpha\ntoskrnl.exe')) -and (Test-Path ($letter + '\alpha\txtsetup.sif'))) { + + $result = get-i386infos $letter 'alpha' $result.VolumeLabel + + } elseif ((Test-Path ($letter + '\alpha\ntoskrnl.ex_')) -and (Test-Path ($letter + '\alpha\txtsetup.sif'))) { + + $result = get-i386infos $letter 'alpha' $result.VolumeLabel + + } elseif (((Get-ChildItem $letter\*WIN*.CAB -Recurse) | Where-Object { (($_.fullname).split('\').Count) -le 4 }) -ne $null) { + $cab = ((Get-ChildItem $letter\*WIN*.CAB -Recurse) | Where-Object { (($_.fullname).split('\').Count) -le 4 })[1] + $result.Type = 'client' + if ((Get-ChildItem ($cab.directory.fullname + '\USER.EXE') -Recurse) -ne $null) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + & 'bin\7z' e $cab user.exe | Out-Null + $result.MajorVersion = ((Get-Item .\user.exe).VersionInfo.ProductVersion).split('.')[0] + $result.MinorVersion = ((Get-Item .\user.exe).VersionInfo.ProductVersion).split('.')[1] + $result.BuildNumber = ((Get-Item .\user.exe).VersionInfo.ProductVersion).split('.')[2] + $result.Architecture = 'X86' + $result.LanguageCode = $langcodes[(Get-Item .\user.exe).VersionInfo.Language] + Remove-Item -Force .\user.exe + + + # Hotfix for a MS derping on the 347 Spanish version of Windows 95, the OS is technically 347, but for some reason, + # kernel386, gdi, and user are reporting 346 as the build number. While win32 components, (kernel32, gdi32, user32) + # reports 347, as it should be. If you have any doubt, you can find this 347 spanish build on the multilang dvd of 347. + if (($result.LanguageCode -eq 'es-ES_tradnl') -and ($result.BuildNumber -eq '346')) { + $result.BuildNumber = '347' + } + + if ($result.BuildNumber -eq '950') { + & 'bin\7z' e $cab kernel32.dll | Out-Null + $result.MajorVersion = ((Get-Item .\kernel32.dll).VersionInfo.ProductVersion).split('.')[0] + $result.MinorVersion = ((Get-Item .\kernel32.dll).VersionInfo.ProductVersion).split('.')[1] + $result.BuildNumber = ((Get-Item .\kernel32.dll).VersionInfo.ProductVersion).split('.')[2] + Remove-Item -Force .\kernel32.dll + } + + $paths = @() + ((Get-ChildItem $letter\*WIN*.CAB -Recurse) | Where-Object { (($_.fullname).split('\').Count) -le 4 }) | ForEach-Object -Process { + if (-not ($paths -contains $_.directory.fullname)) { + $paths += $_.directory.fullname + } + } + + if ($paths.Count -gt 1) { + $result.LanguageCode = 'multi' + } + + if (Test-Path ($cab.directory.fullname + '.\SETUPPP.INF')) { + if (((get-inicontent ($cab.directory.fullname + '.\SETUPPP.INF'))["Strings"]) -ne $null) { + if (((get-inicontent ($cab.directory.fullname + '.\SETUPPP.INF'))["Strings"]["SubVersionString"]) -ne $null) { + $subver = (get-inicontent ($cab.directory.fullname + '.\SETUPPP.INF'))["Strings"]["SubVersionString"].replace('"','') + if ($subver -like '*;*') { + $subver = $subver.split(';')[0] + } + + $subver = Remove-InvalidFileNameChars ($subver) + $subver = $subver.split(' ') + + foreach ($item in $subver) { + if ($item -ne '') { + if ($item -like '.*') { + $result.DeltaVersion = $item.Substring(1) + } elseif (($item.Length -eq 1) -and (-not ($item -match "[0-9]"))) { + $result.BuildNumber = ($result.BuildNumber + $item) + } else { + if ($result.Tag -eq $null) { + $result.Tag = $item + } else { + $result.Tag = ($result.Tag + '_' + $item) + } + } + } + } + } + } + } else { + & 'bin\7z' e $cab.directory.fullname '\PRECOPY2.CAB' SETUPPP.INF | Out-Null + if (((get-inicontent '.\SETUPPP.INF')["Strings"]) -ne $null) { + if (((get-inicontent '.\SETUPPP.INF')["Strings"]["SubVersionString"]) -ne $null) { + $subver = (get-inicontent '.\SETUPPP.INF')["Strings"]["SubVersionString"].replace('"','') + if ($subver -like '*;*') { + $subver = $subver.split(';')[0] + } + + if ($subver -ne '') { + $subver = Remove-InvalidFileNameChars ($subver) + $subver = $subver.split(' ') + + foreach ($item in $subver) { + if ($item -ne '') { + if ($item -like '.*') { + $result.DeltaVersion = $item.Substring(1) + } elseif (($item.Length -eq 1) -and (-not ($item -match "[0-9]"))) { + $result.BuildNumber = ($result.BuildNumber + $item) + } else { + if ($result.Tag -eq $null) { + $result.Tag = $item + } else { + $result.Tag = ($result.Tag + '_' + $item) + } + } + } + } + } + } + } + Remove-Item -Force '.\SETUPPP.INF' + } + + Write-Host "Dismounting $($isofile)..." + Get-DiskImage -ImagePath $isofile.fullname | Dismount-DiskImage + } elseif ((Get-ChildItem $letter\*CHICO*.CAB -Recurse) -ne $null) { + $cab = (Get-ChildItem $letter\*CHICO*.CAB -Recurse)[1] + $result.Type = 'client' + if ((Get-ChildItem ($cab.directory.fullname + '\USER.EXE') -Recurse) -ne $null) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + & 'bin\7z' e $cab user.exe | Out-Null + $result.MajorVersion = ((Get-Item .\user.exe).VersionInfo.ProductVersion).split('.')[0] + $result.MinorVersion = ((Get-Item .\user.exe).VersionInfo.ProductVersion).split('.')[1] + $result.BuildNumber = ((Get-Item .\user.exe).VersionInfo.ProductVersion).split('.')[2] + $result.Architecture = 'x86' + Remove-Item .\user.exe -Force + & 'bin\7z' e $cab shell32.dll | Out-Null + & 'bin\7z' e .\shell32.dll .rsrc\version.txt | Out-Null + (Get-Content .\version.txt) | ForEach-Object -Process { + $_ = Remove-InvalidFileNameChars ($_) + if ($_ -like ('*Translation*')) { + $langdata = $_.split(',')[1].Trim() + $result.LanguageCode = [System.Globalization.Cultureinfo]::GetCultureInfo([int32]$langdata).Name + } + } + + Remove-Item '.\version.txt' -Force + Remove-Item .\shell32.dll -Force + + $paths = @() + (Get-ChildItem $letter\*CHICO*.CAB -Recurse) | ForEach-Object -Process { + if (-not ($paths -contains $_.directory.fullname)) { + $paths += $_.directory.fullname + } + } + + if ($paths.Count -gt 1) { + $result.LanguageCode = 'multi' + } + + & 'bin\7z' e $cab.directory.fullname '\PRECOPY2.CAB' SETUPPP.INF | Out-Null + if (((get-inicontent '.\SETUPPP.INF')["Strings"]) -ne $null) { + if (((get-inicontent '.\SETUPPP.INF')["Strings"]["SubVersionString"]) -ne $null) { + $subver = (get-inicontent '.\SETUPPP.INF')["Strings"]["SubVersionString"].replace('"','').replace(' ','').replace('-','') + if ($subver -like '*;*') { + $subver = $subver.split(';')[0] + } + if ($subver -ne '') { + $result.BuildNumber = ($result.BuildNumber + '_' + $subver) + } + } + } + Remove-Item '.\SETUPPP.INF' -Force + + Write-Host "Dismounting $($isofile)..." + Get-DiskImage -ImagePath $isofile.fullname | Dismount-DiskImage + } else { + Write-Host "The ISO is unknown!" + Write-Host "Dismounting $($isofile)..." + Get-DiskImage -ImagePath $isofile.fullname | Dismount-DiskImage + return $null + } + if ($result.BuildNumber -eq $null) { + Write-Host "The ISO is unknown!" + return $null + } + return $result +} + +function get-BetterISOFilename ($item) { + $results = ISO-Identify ($item) + Write-Host $results + if ($results -eq $null) { + return $null + } + + switch ($scheme) { + 0 { + if ($results.Sku -eq $null) { + $identifier = $results.Type + } else { + $identifier = $results.Type + '-' + $results.Sku + } + + if ($results.Licensing -ne $null) { + $identifier = $identifier + '_' + $results.Licensing + } + + $filename = $results.MajorVersion + '.' + $results.MinorVersion + '.' + $results.BuildNumber + + if (-not ($results.DeltaVersion -eq $null)) { + $filename = $filename + '.' + $results.DeltaVersion + } + + if (-not ($results.BranchName -eq $null)) { + $filename = $filename + '.' + $results.BranchName + } + + if (-not ($results.CompileDate -eq $null)) { + $filename = $filename + '.' + $results.CompileDate + } + + if (-not ($results.Tag -eq $null)) { + $filename = $filename + '_' + $results.Tag + } + + $filename = $filename + '_' + $results.Architecture + $results.BuildType + '_' + $identifier + '_' + $results.LanguageCode + $filename = $filename.toLower() + + + if ($addLabel) { + $filename = $filename + '-' + $results.VolumeLabel + } + $filename = $filename + '.iso' + } + 1 { + $Edition = $null + $Licensing = $null + + foreach ($item_ in $results.Editions) { + if ($Edition -eq $null) { + $Licensing = 'RET' + $Edition_ = $item_ + if ($item_ -eq 'Core') { $Edition_ = 'CORE' } + if ($item_ -eq 'CoreN') { $Edition_ = 'COREN' } + if ($item_ -eq 'CoreSingleLanguage') { $Edition_ = 'SINGLELANGUAGE' } + if ($item_ -eq 'CoreCountrySpecific') { $Edition_ = 'CHINA' } + if ($item_ -eq 'Professional') { $Edition_ = 'PRO' } + if ($item_ -eq 'ProfessionalN') { $Edition_ = 'PRON' } + if ($item_ -eq 'ProfessionalWMC') { $Edition_ = 'PROWMC' } + if ($item_ -eq 'CoreConnected') { $Edition_ = 'CORECONNECTED' } + if ($item_ -eq 'CoreConnectedN') { $Edition_ = 'CORECONNECTEDN' } + if ($item_ -eq 'CoreConnectedSingleLanguage') { $Edition_ = 'CORECONNECTEDSINGLELANGUAGE' } + if ($item_ -eq 'CoreConnectedCountrySpecific') { $Edition_ = 'CORECONNECTEDCHINA' } + if ($item_ -eq 'ProfessionalStudent') { $Edition_ = 'PROSTUDENT' } + if ($item_ -eq 'ProfessionalStudentN') { $Edition_ = 'PROSTUDENTN' } + if ($item_ -eq 'Enterprise') { + $Licensing = 'VOL' + $Edition_ = 'ENTERPRISE' + } + $Edition = $Edition_ + } else { + $Edition_ = $item_ + if ($item_ -eq 'Core') { $Edition_ = 'CORE' } + if ($item_ -eq 'CoreN') { $Edition_ = 'COREN' } + if ($item_ -eq 'CoreSingleLanguage') { $Edition_ = 'SINGLELANGUAGE' } + if ($item_ -eq 'CoreCountrySpecific') { $Edition_ = 'CHINA' } + if ($item_ -eq 'Professional') { $Edition_ = 'PRO' } + if ($item_ -eq 'ProfessionalN') { $Edition_ = 'PRON' } + if ($item_ -eq 'ProfessionalWMC') { $Edition_ = 'PROWMC' } + if ($item_ -eq 'CoreConnected') { $Edition_ = 'CORECONNECTED' } + if ($item_ -eq 'CoreConnectedN') { $Edition_ = 'CORECONNECTEDN' } + if ($item_ -eq 'CoreConnectedSingleLanguage') { $Edition_ = 'CORECONNECTEDSINGLELANGUAGE' } + if ($item_ -eq 'CoreConnectedCountrySpecific') { $Edition_ = 'CORECONNECTEDCHINA' } + if ($item_ -eq 'ProfessionalStudent') { $Edition_ = 'PROSTUDENT' } + if ($item_ -eq 'ProfessionalStudentN') { $Edition_ = 'PROSTUDENTN' } + if ($item_ -eq 'Enterprise') { + $Licensing = $Licensing + 'VOL' + $Edition_ = 'ENTERPRISE' + } + $Edition = $Edition + '-' + $Edition_ + } + } + + if ($results.Type.toLower() -eq 'server') { + $Edition = $Edition.toUpper() -replace 'SERVERHYPER','SERVERHYPERCORE' -replace 'SERVER','' + } + + if ($results.Licensing.toLower() -eq 'volume') { + $Licensing = 'VOL' + } elseif ($results.Licensing.toLower() -eq 'oem') { + $Licensing = 'OEM' + } elseif ($Licensing -eq $null) { + $Licensing = 'RET' + } + + if ($Edition -contains 'PRO-CORE') { + $Licensing = $Licensing -replace 'RET','OEMRET' + } elseif ($results.Sku -eq $null -and $results.Type.toLower() -eq 'server') { + $Edition = '' + if ($results.Licensing.toLower() -eq 'retail') { + $Licensing = 'OEMRET' + } + if ($results.Licensing.toLower() -eq 'retail' -and [int]$results.BuildNumber -lt 9900) { + $Licensing = 'OEM' + } + } elseif ($results.Editions.Count -eq 1 -and $results.Type.toLower() -eq 'server') { + $Licensing = 'OEM' + } + + if ([int]$results.BuildNumber -lt 8008) { + $Edition = $results.Sku + } + + if ($Edition -eq 'unstaged') { + $Edition = '' + } + + $arch = $results.Architecture -replace 'amd64','x64' + if ($results.BranchName -eq $null) { + $FILENAME = ($results.BuildNumber + '.' + $results.DeltaVersion) + } else { + $FILENAME = ($results.BuildNumber + '.' + $results.DeltaVersion + '.' + $results.CompileDate + '.' + $results.BranchName) + } + + $FILENAME = ($FILENAME + '_' + $results.Type + $Edition + '_' + $Licensing + '_' + $arch + $results.BuildType + '_' + $results.LanguageCode) + + if ($addLabel) { + $filename = $filename + '-' + $results.VolumeLabel + } + $filename = ($filename + '.iso').toUpper() + } + 2 { + if ($results.LanguageCode -eq 'en-gb') { + $lang = 'en-gb' + } elseif ($results.LanguageCode -eq 'es-mx') { + $lang = 'es-mx' + } elseif ($results.LanguageCode -eq 'fr-ca') { + $lang = 'fr-ca' + } elseif ($results.LanguageCode -eq 'pt-pt') { + $lang = 'pp' + } elseif ($results.LanguageCode -eq 'sr-latn-rs') { + $lang = 'sr-latn' + } elseif ($results.LanguageCode -eq 'zh-cn') { + $lang = 'cn' + } elseif ($results.LanguageCode -eq 'zh-tw') { + $lang = 'tw' + } elseif ($results.LanguageCode -eq 'zh-hk') { + $lang = 'hk' + } else { + $lang = $results.LanguageCode.split('-')[0] + } + + $arch = $results.Architecture + $EditionID = $null + + foreach ($item_ in $results.Editions) { + if ($EditionID -eq $null) { + $EditionID = $item_ + } else { + $EditionID = $EditionID + '-' + $item_ + } + } + + if ($results.BranchName -ne $null) { + $filename = ($lang.toLower()) + '_' + $results.BuildNumber + '.' + $results.DeltaVersion + '.' + $results.BranchName + '.' + $results.CompileDate + '_' + $arch + $results.BuildType + '_' + $results.Sku + '_' + ($results.LanguageCode.toLower()) + '_' + $EditionID + '-' + $results.VolumeLabel + '.iso' + if ($EditionID.toLower() -eq 'enterprise') { $filename = ($lang.toLower()) + '_' + $results.BuildNumber + '.' + $results.DeltaVersion + '.' + $results.BranchName + '.' + $results.CompileDate + '_' + $arch + $results.BuildType + '_' + $results.Sku + '_' + ($results.LanguageCode.toLower()) + '_VL_' + $EditionID + '-' + $results.VolumeLabel + '.iso' } + if ($EditionID.toLower() -eq 'enterprisen') { $filename = ($lang.toLower()) + '_' + $results.BuildNumber + '.' + $results.DeltaVersion + '.' + $results.BranchName + '.' + $results.CompileDate + '_' + $arch + $results.BuildType + '_' + $results.Sku + '_' + ($results.LanguageCode.toLower()) + '_VL_' + $EditionID + '-' + $results.VolumeLabel + '.iso' } + } else { + $filename = ($lang.toLower()) + '_' + $results.BuildNumber + '.' + $results.DeltaVersion + '.' + $results.CompileDate + '_' + $arch + $results.BuildType + '_' + $results.Sku + '_' + ($results.LanguageCode.toLower()) + '_' + $EditionID + '-' + $results.VolumeLabel + '.iso' + if ($EditionID.toLower() -eq 'enterprise') { $filename = ($lang.toLower()) + '_' + $results.BuildNumber + '.' + $results.DeltaVersion + '_' + $arch + $results.BuildType + '_' + $results.Sku + '_' + ($results.LanguageCode.toLower()) + '_VL_' + $EditionID + '-' + $results.VolumeLabel + '.iso' } + if ($EditionID.toLower() -eq 'enterprisen') { $filename = ($lang.toLower()) + '_' + $results.BuildNumber + '.' + $results.DeltaVersion + '_' + $arch + $results.BuildType + '_' + $results.Sku + '_' + ($results.LanguageCode.toLower()) + '_VL_' + $EditionID + '-' + $results.VolumeLabel + '.iso' } + } + } + } + Write-Host "Found: $($filename)" + return $filename } diff --git a/bin/esd_lib_fast.ps1 b/bin/esd_lib_fast.ps1 new file mode 100644 index 0000000..80cb5f5 --- /dev/null +++ b/bin/esd_lib_fast.ps1 @@ -0,0 +1,977 @@ +[CmdletBinding()] +param ( + [ValidateScript({(Test-Path $_) -and ((Get-Item $_).Extension -eq ".esd")})] + [parameter(Mandatory=$false,HelpMessage="The complete path to the ESD file to convert.")] + [Array] $ESD, + + [ValidateScript({(Test-Path $_)})] + [parameter(Mandatory=$false,HelpMessage="The place where the final ISO file will be stored")] + [System.IO.DirectoryInfo] $Destination = '.\', + + [parameter(Mandatory=$false,HelpMessage="The crypto key that will be used to decrypt the ESD file.")] + $CryptoKey, + + [parameter(Mandatory=$false,HelpMessage="The type of extension used for the Windows Image (WIM or ESD)")] + $extensiontype +) + +try{ + Add-Type -AssemblyName PresentationCore,PresentationFramework,WindowsBase,system.windows.forms +} catch { + Throw "Failed to load Windows Presentation Framework assemblies." +} + +$Host.UI.RawUI.WindowTitle = "ESD Toolkit - March Preview 2016" + +start-transcript -path ".\logs\WindowsSetupToolKit_$(get-date -format yyMMdd-HHmm).log" | out-null + +Write-Host ' +Based on the script by abbodi1406 +ESD Toolkit - March Preview 2016 - Copyright 2015-2016 (c) gus33000 - Version 4.0 +For testing purposes only. Build 4.0.10123.0.fbl_release(gus33000).160304-1600 +' + +Write-Host 'Loading utilities module...' +. '.\bin\utils.ps1' + +New-Enum iso.filenametype Partner Consumer Windows7 +New-Enum wim.extensiontype WIM ESD + +function Select-Menu ($displayoptions, $arrayofoptions) { + Do { + $counter = 0 + if ($displayoptions.Count -ne 1) { + foreach ($item in $displayoptions) { + $counter++ + $padding = ' ' * ((([string]$displayoptions.Length).Length) - (([string]$counter).Length)) + Write-host -ForeGroundColor White ('['+$counter+']'+$padding+' '+$item) + } + Write-Host '' + $choice = read-host -prompt "Select number and press enter" + } else { + $counter++ + $choice = 1 + } + } until ([int]$choice -gt 0 -and [int]$choice -le $counter) + $choice = $choice - 1 + return $arrayofoptions[$choice] +} + +function Get-ScriptDirectory { + Split-Path -parent $PSCommandPath +} + +#Is this a Wow64 powershell host +function Test-Wow64 { + return (Test-Win32) -and (test-path env:\PROCESSOR_ARCHITEW6432) +} + +#Is this a 64 bit process +function Test-Win64 { + return [IntPtr]::size -eq 8 +} + +#Is this a 32 bit process +function Test-Win32 { + return [IntPtr]::size -eq 4 +} + +if (Test-Wow64) { + $wimlib = '.\bin\wimlib-imagex.exe' +} elseif (Test-Win64) { + $wimlib = '.\bin\bin64\wimlib-imagex.exe' +} elseif (Test-Win32) { + $wimlib = '.\bin\wimlib-imagex.exe' +} else { + return +} + +function Copy-File { + param( + [string]$from, + [string]$to + ) + $ffile = [io.file]::OpenRead($from) + $tofile = [io.file]::OpenWrite($to) + try { + $sw = [System.Diagnostics.Stopwatch]::StartNew() + [byte[]]$buff = new-object byte[] (4096*1024) + [long]$total = [long]$count = 0 + do { + $count = $ffile.Read($buff, 0, $buff.Length) + $tofile.Write($buff, 0, $count) + $total += $count + [int]$pctcomp = ([int]($total/$ffile.Length* 100)) + [int]$secselapsed = [int]($sw.elapsedmilliseconds.ToString())/1000 + if ($secselapsed -ne 0) { + [single]$xferrate = (($total/$secselapsed)/1mb) + } else { + [single]$xferrate = 0.0 + } + if ($total % 1mb -eq 0) { + if($pctcomp -gt 0) { + [int]$secsleft = ((($secselapsed/$pctcomp)* 100)-$secselapsed) + } else { + [int]$secsleft = 0 + } + if ($pastpct -ne $pctcomp) { + Write-Progress ` + -Activity ($pctcomp.ToString() + "% Copying file @ " + "{0:n2}" -f $xferrate + " MB/s")` + -status ($from.Split("\")|select -last 1) ` + -PercentComplete $pctcomp ` + -SecondsRemaining $secsleft; + } + $pastpct = $pctcomp + } + } while ($count -gt 0) + $sw.Stop(); + $sw.Reset(); + } + finally { + Write-Progress -Activity ($pctcomp.ToString() + "% Copying file @ " + "{0:n2}" -f $xferrate + " MB/s") -Complete + Write-Host (($from.Split("\")|select -last 1) + ` + " copied in " + $secselapsed + " seconds at " + ` + "{0:n2}" -f [int](($ffile.length/$secselapsed)/1mb) + " MB/s."); + $ffile.Close(); + $tofile.Close(); + } +} + +function Convert-ESDs ( + [parameter(Mandatory=$true)] + [Boolean] $Backup, + [ValidateNotNullOrEmpty()] + [ValidateScript({(Test-Path $_) -and ((Get-Item $_).Extension -eq ".esd")})] + [parameter(Mandatory=$true)] + [Array] $ESD, + [parameter(Mandatory=$false)] + [Array] $RSAKey +) +{ + [Array]$ESDs = @() + [Array]$BackedUpESDs = @() + foreach ($esdfile in $ESD) { + & $wimlib info "$($esdfile)" > $null + if ($LASTEXITCODE -eq 74) { + $tempesd = $esdfile + if ($Backup) { + $BackedUpESDs += ($esdfile+'.mod') + Copy-File $esdfile ($esdfile+'.mod') + $tempesd = ($esdfile+'.mod') + } + $ESDs += $tempesd + & ".\bin\esddecrypt.exe" "$($tempesd)" "$($RSAKey)" + if ($LASTEXITCODE -ne 0) { + if ($Backup) { + foreach ($bakesd in $BackedUpESDs) { + remove-item $bakesd -force + } + } + return $LASTEXITCODE + } + } elseif ($LASTEXITCODE -eq 18) { + if ($Backup) { + foreach ($bakesd in $BackedUpESDs) { + remove-item $bakesd -force + } + } + return 18 + } else { + $ESDs += $esdfile + } + } + return $ESDs, $BackedUpESDs +} + +function New-x64x86Media { + Copy-Item .\Media\x86\boot\ .\Media\ -recurse + Copy-Item .\Media\x86\efi\ .\Media\ -recurse + Copy-Item .\Media\x86\bootmgr .\Media\ + Copy-Item .\Media\x86\bootmgr.efi .\Media\ + Copy-Item .\Media\x86\autorun.inf .\Media\ + Copy-Item .\Media\x86\setup.exe .\Media\ + Copy-Item .\Media\x64\efi\boot\bootx64.efi .\Media\efi\boot\ + $x64guid = bcdedit /store .\Media\boot\bcd /v ` + | Select-String "path" -Context 2,0 ` + | % { $_.Context.PreContext[0] -replace '^identifier +' } ` + | ? { $_ -ne "{default}" } + bcdedit /store .\Media\boot\bcd /set "{default}" description "Windows 10 Setup (64-bit)" + bcdedit /store .\Media\boot\bcd /set "{default}" device ramdisk=[boot]\x64\sources\boot.wim,$x64guid + bcdedit /store .\Media\boot\bcd /set "{default}" osdevice ramdisk=[boot]\x64\sources\boot.wim,$x64guid + bcdedit /store .\Media\boot\bcd /copy "{default}" /d "Windows 10 Setup (32-bit)" + $x86guid = bcdedit /store .\Media\boot\bcd /v ` + | Select-String "path" -Context 2,0 ` + | % { $_.Context.PreContext[0] -replace '^identifier +' } ` + | ? { $_ -ne "$x64guid" } + bcdedit /store .\Media\boot\bcd /set "$($x86guid)" device ramdisk=[boot]\x86\sources\boot.wim,$x64guid + bcdedit /store .\Media\boot\bcd /set "$($x86guid)" osdevice ramdisk=[boot]\x86\sources\boot.wim,$x64guid + Remove-item .\Media\boot\bcd.LOG -force + Remove-item .\Media\boot\bcd.LOG1 -force + Remove-item .\Media\boot\bcd.LOG2 -force +} + +function CleanTM ( + [parameter(Mandatory=$true)] + $BackedUpESDs +) +{ + if (Test-Path '.\Media\') { + Remove-Item -recurse .\Media -force + } + if ($bakesd -ne $null) { + foreach ($bakesd in $BackedUpESDs) { + remove-item $bakesd -force + } + } +} + +function Get-InfosFromESD ( + [parameter(Mandatory=$true,HelpMessage="The complete path to the ESD file to convert.")] + [Array] $ESD +) +{ + $esdinformations = @() + foreach ($esdfile in $ESD) { + $result = "" | select MajorVersion, MinorVersion, BuildNumber, DeltaVersion, BranchName, CompileDate, Architecture, BuildType, Type, Sku, Editions, Licensing, LanguageCode, VolumeLabel, BuildString, ESDs + + $editions = @() + $counter = 0 + + $WIMInfo = New-Object System.Collections.ArrayList + $WIMInfo=@{} + + for ($i=1; $i -le 3; $i++){ + $counter++ + $WIMInfo[$counter] = @{} + $OutputVariable = ( & $wimlib info "$($esdfile)" $i) + ForEach ($Item in $OutputVariable) { + $CurrentItem = ($Item -replace '\s+', ' ').split(':') + $CurrentItemName = $CurrentItem[0] -replace ' ', '' + if (($CurrentItem[1] -replace ' ', '') -ne '') { + $WIMInfo[$counter][$CurrentItemName] = $CurrentItem[1].Substring(1) + } + } + } + + $header = @{} + $OutputVariable = ( & $wimlib info "$($esdfile)" --header) + ForEach ($Item in $OutputVariable) { + $CurrentItem = ($Item -replace '\s+', ' ').split('=') + $CurrentItemName = $CurrentItem[0] -replace ' ', '' + if (($CurrentItem[1] -replace ' ', '') -ne '') { + $header[$CurrentItemName] = $CurrentItem[1].Substring(1) + } + } + + for ($i=4; $i -le $header.ImageCount; $i++){ + $counter++ + $WIMInfo[$counter] = @{} + $OutputVariable = ( & $wimlib info "$($esdfile)" $i) + ForEach ($Item in $OutputVariable) { + $CurrentItem = ($Item -replace '\s+', ' ').split(':') + $CurrentItemName = $CurrentItem[0] -replace ' ', '' + if (($CurrentItem[1] -replace ' ', '') -ne '') { + $WIMInfo[$counter][$CurrentItemName] = $CurrentItem[1].Substring(1) + if ($CurrentItemName -eq 'EditionID') { + $lastedition = $CurrentItem[1].Substring(1) + $editions += $CurrentItem[1].Substring(1) + } + } + } + } + + $WIMInfo["header"] = @{} + $WIMInfo["header"]["ImageCount"] = ($counter.toString()) + + $result.Editions = $editions + + # Converting standards architecture names to friendly ones, if we didn't found any, we put the standard one instead * cough * arm / ia64, + # Yes, IA64 is still a thing for server these days... + if ($WIMInfo[4].Architecture -eq 'x86') { + $result.Architecture = 'x86' + } elseif ($WIMInfo[4].Architecture -eq 'x86_64') { + $result.Architecture = 'amd64' + } else { + $result.Architecture = $WIMInfo[4].Architecture + } + + # Gathering Compiledate and the buildbranch from the ntoskrnl executable. + Write-Host 'Checking critical system files for a build string and build type information...' + & $wimlib extract $esdfile 4 windows\system32\ntkrnlmp.exe windows\system32\ntoskrnl.exe --nullglob --no-acls | out-null + if (Test-Path .\ntkrnlmp.exe) { + $result.CompileDate = (Get-item .\ntkrnlmp.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') + $result.BranchName = (Get-item .\ntkrnlmp.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + if ((Get-item .\ntkrnlmp.exe).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $ProductVersion = (Get-item .\ntkrnlmp.exe).VersionInfo.ProductVersion + remove-item .\ntkrnlmp.exe -force + } elseif (Test-Path .\ntoskrnl.exe) { + $result.CompileDate = (Get-item .\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') + $result.BranchName = (Get-item .\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + if ((Get-item .\ntoskrnl.exe).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $ProductVersion = (Get-item .\ntoskrnl.exe).VersionInfo.ProductVersion + remove-item .\ntoskrnl.exe -force + } + + $result.MajorVersion = $ProductVersion.split('.')[0] + $result.MinorVersion = $ProductVersion.split('.')[1] + $result.BuildNumber = $ProductVersion.split('.')[2] + $result.DeltaVersion = $ProductVersion.split('.')[3] + + # Gathering Compiledate and the buildbranch from the build registry. + Write-Host 'Checking registry for a more accurate build string...' + & $wimlib extract $esdfile 4 windows\system32\config\ --no-acls | out-null + & 'reg' load HKLM\RenameISOs .\config\SOFTWARE | out-null + $output = ( & 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion" /v "BuildLab") + if (($output[2] -ne $null) -and (-not ($output[2].Split(' ')[-1].Split('.')[-1]) -eq '')) { + $result.CompileDate = $output[2].Split(' ')[-1].Split('.')[-1] + $result.BranchName = $output[2].Split(' ')[-1].Split('.')[-2] + $output_ = ( & 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion" /v "BuildLabEx") + if (($output_[2] -ne $null) -and (-not ($output_[2].Split(' ')[-1].Split('.')[-1]) -eq '')) { + if ($output_[2].Split(' ')[-1] -like '*.*.*.*.*') { + $result.BuildNumber = $output_[2].Split(' ')[-1].Split('.')[0] + $result.DeltaVersion = $output_[2].Split(' ')[-1].Split('.')[1] + } + } + } else { + Write-Host 'Registry check was unsuccessful. Aborting and continuing with critical system files build string...' + } + & 'reg' unload HKLM\RenameISOs | out-null + remove-item .\config\ -recurse -force + + # Defining if server or client thanks to Microsoft including 'server' in the server sku names + if (($WIMInfo.header.ImageCount -gt 4) -and (($WIMInfo[4].EditionID) -eq $null)) { + $result.Type = 'client' + $result.Sku = $null + } elseif (($WIMInfo[4].EditionID) -eq $null) { + $result.Type = 'client' + $result.Sku = 'unstaged' + } elseif (($WIMInfo[4].EditionID.toLower()) -like '*server*') { + $result.Type = 'server' + $result.Sku = $WIMInfo[4].EditionID.toLower() -replace 'server', '' + } else { + $result.Type = 'client' + $result.Sku = $WIMInfo[4].EditionID.toLower() + } + + $result.Licensing = 'Retail' + + & $wimlib extract $esdfile 1 sources\ei.cfg --nullglob --no-acls | out-null + if (Test-Path ".\ei.cfg") { + $content = @() + Get-Content (".\ei.cfg") | foreach-object -process { + $content += $_ + } + $counter = 0 + foreach ($item in $content) { + $counter++ + if ($item -eq '[EditionID]') { + $result.Sku = $content[$counter] + } + } + $counter = 0 + foreach ($item in $content) { + $counter++ + if ($item -eq '[Channel]') { + $result.Licensing = $content[$counter] + } + } + Remove-Item ".\ei.cfg" -force + } + + if (($WIMInfo.header.ImageCount -eq 7) -and ($result.Type -eq 'server')) { + $result.Sku = $null + } + + & $wimlib extract $esdfile 1 sources\lang.ini --nullglob --no-acls | out-null + Get-Content ('lang.ini') | foreach-object -begin {$h=@()} -process { $k = [regex]::split($_,'`r`n'); if(($k[0].CompareTo("") -ne 0)) { $h += $k[0] } } + $result.LanguageCode = ($h[((0..($h.Count - 1) | Where { $h[$_] -eq '[Available UI Languages]' }) + 1)]).split('=')[0].Trim() + remove-item lang.ini -force + + $tag = 'ir3' + $DVD = 'DV9' + + if ($WIMInfo[4].Architecture -eq 'x86') { + $arch = 'x86' + } + + if ($WIMInfo[4].Architecture -eq 'x86_64') { + $arch = 'x64' + } + + if ($WIMInfo[4].ServicePackBuild -eq '17056') { + $tag = 'ir4' + } + if ($WIMInfo[4].ServicePackBuild -eq '17415') { + $tag = 'ir5' + } + if ($WIMInfo[4].ServicePackBuild -gt '17415') { + $tag = 'ir6' + } + + if ([int] $WIMInfo[4].Build -gt '9600') { + $tag = 'JM1' + $DVD = 'DV5' + } + if ([int] $WIMInfo[4].Build -ge '9896') { + $tag = 'J' + $DVD = 'DV5' + } + + if ($result.Licensing.toLower() -eq 'volume') { + $ltag = 'FREV_' + } elseif ($result.Licensing.toLower() -eq 'oem') { + $ltag = 'FREO_' + } else { + $ltag = 'FRE_' + } + + $DVDLabel = ($tag+'_CCSA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper() + if ($WIMInfo.header.ImageCount -eq 4) { + if ($WIMInfo[4].EditionID -eq 'Core') {$DVDLabel = ($tag+'_CCRA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreConnected') {$DVDLabel = ($tag+'_CCONA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreConnectedCountrySpecific') {$DVDLabel = ($tag+'_CCCHA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreConnectedN') {$DVDLabel = ($tag+'_CCONNA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreConnectedSingleLanguage') {$DVDLabel = ($tag+'_CCSLA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreCountrySpecific') {$DVDLabel = ($tag+'_CCHA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreN') {$DVDLabel = ($tag+'_CCRNA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreSingleLanguage') {$DVDLabel = ($tag+'_CSLA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'Professional') {$DVDLabel = ($tag+'_CPRA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'ProfessionalN') {$DVDLabel = ($tag+'_CPRNA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'ProfessionalStudent') {$DVDLabel = ($tag+'_CPRSA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'ProfessionalStudentN') {$DVDLabel = ($tag+'_CPRSNA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'ProfessionalWMC') {$DVDLabel = ($tag+'_CPWMCA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'Education') {$DVDLabel = ($tag+'_CEDA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'EducationN') {$DVDLabel = ($tag+'_CEDNA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'Enterprise') {$DVDLabel = ($tag+'_CENA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'EnterpriseN') {$DVDLabel = ($tag+'_CENNA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'EnterpriseS') {$DVDLabel = ($tag+'_CES_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'EnterpriseSN') {$DVDLabel = ($tag+'_CESN_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + } + + $result.VolumeLabel = $DVDLabel + $result.BuildString = ($result.MajorVersion+'.'+$result.MinorVersion+'.'+$result.BuildNumber+'.'+$result.DeltaVersion+'.'+$result.BranchName+'.'+$result.CompileDate) + $result.ESDs = [array]$esdfile + $esdinformations += $result + } + $archs = @() + ($esdinformations | select Architecture).Architecture | % { + if (-not ($archs -contains $_.toLower())) { + $archs += $_.toLower() + } + } + $filename = $null + foreach ($arch in $archs) { + $currentesds1 = ($esdinformations | Where-Object { $_.architecture.toLower() -eq $arch }) + $buildtypes = @() + ($currentesds1 | select BuildType).BuildType | % { + if (-not ($buildtypes -contains $_.toLower())) { + $buildtypes += $_.toLower() + } + } + foreach ($buildtype in $buildtypes) { + $currentesds2 = ($currentesds1 | Where-Object { $_.buildtype.toLower() -eq $buildtype }) + $builds = @() + ($currentesds2 | select BuildString).BuildString | % { + if (-not ($builds -contains $_.toLower())) { + $builds += $_.toLower() + } + } + foreach ($build in $builds) { + $currentesds3 = ($currentesds2 | Where-Object {$_.BuildString.toLower() -eq $build }) + $languages = @() + ($currentesds3 | select LanguageCode).LanguageCode | % { + if (-not ($languages -contains $_.toLower())) { + $languages += $_.toLower() + } + } + foreach ($language in $languages) { + $currentesds4 = ($currentesds3 | Where-Object {$_.LanguageCode -eq $language }) + $Edition = $null + $Licensing = $null + ($currentesds4 | select Editions).Editions | % { + if ($_ -is [System.Array]) { + foreach ($item in $_) { + if ($Edition -eq $null) { + $Edition_ = $item + if ($item -eq 'Core') {$Edition_ = 'CORE'} + if ($item -eq 'CoreN') {$Edition_ = 'COREN'} + if ($item -eq 'CoreSingleLanguage') {$Edition_ = 'SINGLELANGUAGE'} + if ($item -eq 'CoreCountrySpecific') {$Edition_ = 'CHINA'} + if ($item -eq 'Professional') {$Edition_ = 'PRO'} + if ($item -eq 'ProfessionalN') {$Edition_ = 'PRON'} + if ($item -eq 'ProfessionalWMC') {$Edition_ = 'PROWMC'} + if ($item -eq 'CoreConnected') {$Edition_ = 'CORECONNECTED'} + if ($item -eq 'CoreConnectedN') {$Edition_ = 'CORECONNECTEDN'} + if ($item -eq 'CoreConnectedSingleLanguage') {$Edition_ = 'CORECONNECTEDSINGLELANGUAGE'} + if ($item -eq 'CoreConnectedCountrySpecific') {$Edition_ = 'CORECONNECTEDCHINA'} + if ($item -eq 'ProfessionalStudent') {$Edition_ = 'PROSTUDENT'} + if ($item -eq 'ProfessionalStudentN') {$Edition_ = 'PROSTUDENTN'} + if ($item -eq 'Enterprise') {$Edition_ = 'ENTERPRISE'} + $Edition = $Edition_ + } else { + $Edition_ = $item_ + if ($item -eq 'Core') {$Edition_ = 'CORE'} + if ($item -eq 'CoreN') {$Edition_ = 'COREN'} + if ($item -eq 'CoreSingleLanguage') {$Edition_ = 'SINGLELANGUAGE'} + if ($item -eq 'CoreCountrySpecific') {$Edition_ = 'CHINA'} + if ($item -eq 'Professional') {$Edition_ = 'PRO'} + if ($item -eq 'ProfessionalN') {$Edition_ = 'PRON'} + if ($item -eq 'ProfessionalWMC') {$Edition_ = 'PROWMC'} + if ($item -eq 'CoreConnected') {$Edition_ = 'CORECONNECTED'} + if ($item -eq 'CoreConnectedN') {$Edition_ = 'CORECONNECTEDN'} + if ($item -eq 'CoreConnectedSingleLanguage') {$Edition_ = 'CORECONNECTEDSINGLELANGUAGE'} + if ($item -eq 'CoreConnectedCountrySpecific') {$Edition_ = 'CORECONNECTEDCHINA'} + if ($item -eq 'ProfessionalStudent') {$Edition_ = 'PROSTUDENT'} + if ($item -eq 'ProfessionalStudentN') {$Edition_ = 'PROSTUDENTN'} + if ($item -eq 'Enterprise') {$Edition_ = 'ENTERPRISE'} + $Edition = $Edition+'-'+$Edition_ + } + } + } else { + if ($Edition -eq $null) { + $Edition_ = $_ + if ($_ -eq 'Core') {$Edition_ = 'CORE'} + if ($_ -eq 'CoreN') {$Edition_ = 'COREN'} + if ($_ -eq 'CoreSingleLanguage') {$Edition_ = 'SINGLELANGUAGE'} + if ($_ -eq 'CoreCountrySpecific') {$Edition_ = 'CHINA'} + if ($_ -eq 'Professional') {$Edition_ = 'PRO'} + if ($_ -eq 'ProfessionalN') {$Edition_ = 'PRON'} + if ($_ -eq 'ProfessionalWMC') {$Edition_ = 'PROWMC'} + if ($_ -eq 'CoreConnected') {$Edition_ = 'CORECONNECTED'} + if ($_ -eq 'CoreConnectedN') {$Edition_ = 'CORECONNECTEDN'} + if ($_ -eq 'CoreConnectedSingleLanguage') {$Edition_ = 'CORECONNECTEDSINGLELANGUAGE'} + if ($_ -eq 'CoreConnectedCountrySpecific') {$Edition_ = 'CORECONNECTEDCHINA'} + if ($_ -eq 'ProfessionalStudent') {$Edition_ = 'PROSTUDENT'} + if ($_ -eq 'ProfessionalStudentN') {$Edition_ = 'PROSTUDENTN'} + if ($_ -eq 'Enterprise') {$Edition_ = 'ENTERPRISE'} + $Edition = $Edition_ + } else { + $Edition_ = $_ + if ($_ -eq 'Core') {$Edition_ = 'CORE'} + if ($_ -eq 'CoreN') {$Edition_ = 'COREN'} + if ($_ -eq 'CoreSingleLanguage') {$Edition_ = 'SINGLELANGUAGE'} + if ($_ -eq 'CoreCountrySpecific') {$Edition_ = 'CHINA'} + if ($_ -eq 'Professional') {$Edition_ = 'PRO'} + if ($_ -eq 'ProfessionalN') {$Edition_ = 'PRON'} + if ($_ -eq 'ProfessionalWMC') {$Edition_ = 'PROWMC'} + if ($_ -eq 'CoreConnected') {$Edition_ = 'CORECONNECTED'} + if ($_ -eq 'CoreConnectedN') {$Edition_ = 'CORECONNECTEDN'} + if ($_ -eq 'CoreConnectedSingleLanguage') {$Edition_ = 'CORECONNECTEDSINGLELANGUAGE'} + if ($_ -eq 'CoreConnectedCountrySpecific') {$Edition_ = 'CORECONNECTEDCHINA'} + if ($_ -eq 'ProfessionalStudent') {$Edition_ = 'PROSTUDENT'} + if ($_ -eq 'ProfessionalStudentN') {$Edition_ = 'PROSTUDENTN'} + if ($_ -eq 'Enterprise') {$Edition_ = 'ENTERPRISE'} + $Edition = $Edition+'-'+$Edition_ + } + } + } + ($currentesds4 | select Licensing).Licensing | % { + if ($Licensing -eq $null) { + $Licensing = $_ + } else { + if (-not ($Licensing -contains $_)) { + $Licensing = $Licensing+$_ + } + } + } + $Edition = $Edition.toUpper() -replace 'SERVERHYPER', 'SERVERHYPERCORE' -replace 'SERVER', '' + $Licensing = $Licensing.toUpper() -replace 'VOLUME', 'VOL' -replace 'RETAIL', 'RET' + if ($Edition -eq 'PRO-CORE') { + $Licensing = 'OEMRET' + } + if ($Edition.toLower() -eq 'unstaged') { + $Edition = '' + } + $arch_ = $arch -replace 'amd64', 'x64' + if ($currentesds4 -is [System.Array]) { + $FILENAME_ = ($currentesds4[0].BuildNumber+'.'+$currentesds4[0].DeltaVersion+'.'+$currentesds4[0].CompileDate+'.'+$currentesds4[0].BranchName) + } else { + $FILENAME_ = ($currentesds4.BuildNumber+'.'+$currentesds4.DeltaVersion+'.'+$currentesds4.CompileDate+'.'+$currentesds4.BranchName) + } + $FILENAME_ = ($FILENAME_+'_CLIENT'+$Edition+'_'+$Licensing+'_'+$arch_+$buildtype+'_'+$language).toUpper() + if ($filename -eq $null) { + $filename = $FILENAME_ + } else { + $filename = $filename+'-'+$FILENAME_ + } + $parts += 1 + } + } + } + } + + $tag = 'ir3' + $DVD = 'DV9' + if ($esdinformations[0].Architecture -eq 'x86') { + $arch = 'x86' + } + if ($esdinformations[0].Architecture -eq 'x86_64') { + $arch = 'x64' + } + if ([int] $esdinformations[0].DeltaVersion -eq '17056') { + $tag = 'ir4' + } + if ([int] $esdinformations[0].DeltaVersion -eq '17415') { + $tag = 'ir5' + } + if ([int] $esdinformations[0].DeltaVersion -gt '17415') { + $tag = 'ir6' + } + if ([int] $esdinformations[0].BuildNumber -gt '9600') { + $tag = 'JM1' + $DVD = 'DV5' + } + if ([int] $esdinformations[0].BuildNumber -ge '9896') { + $tag = 'J' + $DVD = 'DV5' + } + if ($esdinformations[0].Licensing.toLower() -eq 'volume') { + $ltag = 'FREV_' + } elseif ($esdinformations[0].Licensing.toLower() -eq 'oem') { + $ltag = 'FREO_' + } else { + $ltag = 'FRE_' + } + + $filename = ($filename+'.ISO').toUpper() + + if ($esdinformations.count -eq 1) { + $DVDLabel = $esdinformations[0].VolumeLabel + } elseif ($esdinformations.count -eq 2 -and $esdinformations[0].Editions -eq "Professional" -and $esdinformations[1].Editions -eq "Core" -and $parts -eq 1) { + $DVDLabel = ($tag+'_CCSA_'+$arch+$ltag+$esdinformations[0].LanguageCode+'_'+$DVD).ToUpper() + } else { + $DVDLabel = "ESD-ISO" + } + + Write-Host Filename: $filename + Write-Host Volume Label: $DVDLabel + + return $filename, $DVDLabel, $esdinformations +} + +function prepforconvert ( + [ValidateNotNullOrEmpty()] + [ValidateScript({(Test-Path $_) -and ((Get-Item $_).Extension -eq ".esd")})] + [parameter(Mandatory=$true,HelpMessage="The complete path to the ESD file to convert.")] + [Array] $esdfiles, + [parameter(Mandatory=$false,HelpMessage="The crypto key that will be used to decrypt the ESD file.")] + $CryptoKey +) +{ + + if ($CryptoKey -ne $null) { + $result = (Convert-ESDs -Backup $true -ESD $esdfiles -RSAKey $CryptoKey) + } else { + $result = (Convert-ESDs -Backup $true -ESD $esdfiles) + } + [array]$esdinfos = @() + if ($result -is [system.array]) { + $results = Get-InfosFromESD -ESD $result[0] + $esdinfos = $results[2] + $volumelabel = $results[1] + $filename = $results[0] + } + return $result, $esdinfos, $filename, $volumelabel +} + +function Convert-ESD ( + [ValidateNotNullOrEmpty()] + [ValidateScript({(Test-Path $_) -and ((Get-Item $_).Extension -eq ".esd")})] + [parameter(Mandatory=$true,HelpMessage="The complete path to the ESD file to convert.")] + [string] $esdfile, + [ValidateNotNullOrEmpty()] + [parameter(Mandatory=$true,HelpMessage="The place where the final ISO file will be stored")] + [System.IO.DirectoryInfo] $Destination, + [ValidateNotNullOrEmpty()] + [parameter(Mandatory=$false,HelpMessage="The crypto key that will be used to decrypt the ESD file.")] + $CryptoKey, + [parameter(Mandatory=$true,HelpMessage="The type of extension used for the Windows Image (WIM or ESD)")] + [wim.extensiontype] $extensiontype +) +{ + $esdfiles = @($esdfile) + $Results = prepforconvert -ESDFiles $esdfiles -CryptoKey $CryptoKey + $filename = $Results[2] + $label = $Results[3] + $result = $Results[0] + [array]$esdinfos = $Results[1] + if ($result -is [System.Array]) { + + } elseif ($result -eq 18) { + #NotOriginal + CleanTM($result[1]) + return + } else { + #Damaged + CleanTM($result[1]) + return + } + $items = @{} + $archs = @() + foreach ($architecture in $esdinfos.Architecture) { + $items[$architecture] = @{} + $items[$architecture]["SetupESDs"] = @() + foreach ($esd in ($esdinfos | ? {$_.Architecture -eq $architecture})) { + $items[$architecture]["SetupESDs"] += $esd | ? { -not (($items.$architecture.SetupESDs | ? {$_.LanguageCode -eq $esd.LanguageCode}).BuildString -contains $esd.BuildString) } + } + $items[$architecture]["WinREESDs"] = @() + foreach ($esd in ($esdinfos | ? {$_.Architecture -eq $architecture})) { + $items[$architecture]["WinREESDs"] += $esd | ? { -not (($items.$architecture.WinREESDs | ? {$_.LanguageCode -eq $esd.LanguageCode}).BuildString -contains $esd.BuildString) } + } + $items[$architecture]["InstallESDs"] = @() + $items[$architecture]["InstallESDs"] += ($esdinfos | ? {$_.Architecture -eq $architecture}) + $archs += $architecture | ? { -not ($archs -contains $architecture) } + } + $global:builds = @() + foreach ($architecture in $archs) { + if ($items.$architecture.SetupESDs -is [system.array]) { + foreach ($item in $items.$architecture.SetupESDs) { + [array]$global:builds += $item + } + } else { + $item = $items.$architecture.SetupESDs + [array]$global:builds += $item + } + $SetupESD = $global:builds[0] + $WinREESD = $global:builds[0] + Write-Host SetupESD: $SetupESD.ESDs + Write-Host WinREESD: $WinREESD.ESDs + function Convert-ISO ( + $SetupESD, + $WinREESD, + $clean, + $extensiontype, + $isoname, + $label + ) + { + Begin { + function New-SetupMedia ( + [parameter(Mandatory=$true)] + [ValidateScript({(Test-Path $_)})] + [String] $SetupESD, + [parameter(Mandatory=$true)] + [ValidateScript({(Test-Path $_)})] + [String] $WinREESD, + [parameter(Mandatory=$true)] + [ValidateScript({(Test-Path $_\)})] + [String] $Output + ) { + if (Test-Path $Output\sources\boot.wim) { + return 1 + } + Write-Host "Expanding Setup files - In Progress" + $name = $null + & $wimlib apply "$($SetupESD)" 1 $Output | ForEach-Object -Process { + if ($name -eq $null) { + $name = $_ + } + $progress = [regex]::match($_,'\(([^\)]+)\%').Groups[1].Value + if ($progress -match "[0-9]") { + Write-Progress -Activity ('Expanding Setup files...') -status ($name) -PercentComplete $progress -CurrentOperation $_ + } + } + Write-Progress -Activity ('Expanding Setup files...') -Complete + Remove-Item $Output\MediaMeta.xml + Write-Host "Expanding Setup files - Done" + Write-Host "Exporting Windows Recovery environement - In Progress" + $sw = [System.Diagnostics.Stopwatch]::StartNew(); + $operationname = $null + & $wimlib export "$($WinREESD)" 2 $Output\sources\boot.wim --compress=maximum | ForEach-Object -Process { + if ($operationname -eq $null) { + $operationname = $_ + } + $global:lastprogress = $progress + $global:progress = [regex]::match($_,'\(([^\)]+)\%').Groups[1].Value + if ($global:progress -match "[0-9]") { + $total = $_.split(' ')[0] + $totalsize = $_.split(' ')[3] + [long]$pctcomp = ([long]($total/$totalsize* 100)); + [long]$secselapsed = [long]($sw.elapsedmilliseconds.ToString())/1000; + if ($pctcomp -ne 0) { + [long]$secsleft = ((($secselapsed/$pctcomp)* 100)-$secselapsed) + } else { + [long]$secsleft = 0 + } + Write-Progress -Activity ('Exporting Windows Recovery environement...') -status ($operationname) -PercentComplete ($global:progress) -SecondsRemaining $secsleft -CurrentOperation $_ + } + } + $sw.Stop(); + $sw.Reset(); + Write-Host "Exporting Windows Recovery environement - Done" + Write-Progress -Activity ('Exporting Windows Recovery environement...') -Complete + Write-Host "Exporting Windows Preinstallation environement - In Progress" + $sw = [System.Diagnostics.Stopwatch]::StartNew(); + $operationname = $null + & $wimlib export "$($SetupESD)" 3 $Output\sources\boot.wim --boot | ForEach-Object -Process { + if ($operationname -eq $null) { + $operationname = $_ + } + $global:lastprogress = $progress + $global:progress = [regex]::match($_,'\(([^\)]+)\%').Groups[1].Value + if ($global:progress -match "[0-9]") { + $total = $_.split(' ')[0] + $totalsize = $_.split(' ')[3] + [long]$pctcomp = ([long]($total/$totalsize* 100)); + [long]$secselapsed = [long]($sw.elapsedmilliseconds.ToString())/1000; + if ($pctcomp -ne 0) { + [long]$secsleft = ((($secselapsed/$pctcomp)* 100)-$secselapsed) + } else { + [long]$secsleft = 0 + } + Write-Progress -Activity ('Exporting Windows Preinstallation environement...') -status ($operationname) -PercentComplete ($global:progress) -SecondsRemaining $secsleft -CurrentOperation $_ + } + } + $sw.Stop(); + $sw.Reset(); + Write-Host "Exporting Windows Preinstallation environement - Done" + Write-Progress -Activity ('Exporting Windows Preinstallation environement...') -Complete + } + } + Process { + mkdir .\Media\ | Out-Null + New-SetupMedia -SetupESD $SetupESD.ESDs[0] -WinREESD $WinREESD.ESDs[0] -Output .\Media\ + Write-Host "Exporting Windows Installation - In Progress" + $esdfile = $items.$architecture.InstallESDs[0].ESDs[0] + & $wimlib delete $esdfile 1 + & $wimlib delete $esdfile 1 + Move-Item $esdfile .\Media\sources\install.esd + Write-Host "Exporting Windows Installation - Done" + Write-Progress -Activity ('Exporting Windows Installation...') -Complete + Write-Host "Creating ISO File - In Progress" + Write-Host 'Gathering Timestamp information from the Setup Media...' + $timestamp = (Get-ChildItem .\Media\setup.exe | % {[System.TimeZoneInfo]::ConvertTimeToUtc($_.creationtime).ToString("MM/dd/yyyy,HH:mm:ss")}) + Write-Host 'Generating ISO...' + $BootData='2#p0,e,bMedia\boot\etfsboot.com#pEF,e,bMedia\efi\Microsoft\boot\efisys.bin' + & "cmd" "/c" ".\bin\cdimage.exe" "-bootdata:$BootData" "-o" "-h" "-m" "-u2" "-udfver102" "-t$timestamp" "-l$($label)" ".\Media" """$($Destination)\$($isoname)""" + Write-Host "Creating ISO File - Done" + CleanTM($clean) + } + } + Convert-ISO -SetupESD $SetupESD -WinREESD $WinREESD -Clean $result[1] -extensiontype $extensiontype -isoname $filename -label $label + } +} + +function New-Wizard-Decrypt() { + + $Title = "What type of Image format do you want for the ISO file ?" + + $message = "ESD Decrypter needs to know in which format the Windows Installation Image should be. Please choose one option below." + + $WIM = New-Object System.Management.Automation.Host.ChoiceDescription "&WIM Format", ` + "This is the most used Windows Image format. If you want to recreate an original ISO, please choose this option." + + $ESD = New-Object System.Management.Automation.Host.ChoiceDescription "&ESD Format", ` + "This format is not commonly used by MS but it provides the best compression available for storing Windows Images." + + $options = [System.Management.Automation.Host.ChoiceDescription[]]($WIM, $ESD) + + $result = $host.ui.PromptForChoice($title, $message, $options, 0) + + switch ($result) + { + 0 {$extensiontype = ([wim.extensiontype] "WIM")} + 1 {$extensiontype = ([wim.extensiontype] "ESD")} + } + + $Title = "Do you want to use a custom Cryptographic key ?" + + $message = "You can specify a custom Crypto Key if the embedded ones can't decrypt your esd file." + + $NO = New-Object System.Management.Automation.Host.ChoiceDescription "&No", ` + "No, continue with the included Crypto keys." + + $YES = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", ` + "Yes, I want to specify a custom key, but I'll try to decrypt the esd file with your custom key and the embedded ones." + + $options = [System.Management.Automation.Host.ChoiceDescription[]]($NO, $YES) + + $result = $host.ui.PromptForChoice($title, $message, $options, 0) + + switch ($result) + { + 0 {$CustomKey = $false} + 1 {$CustomKey = $true} + } + if ($CustomKey -eq $true) { + $key = Read-Host 'Please enter a complete Cryptographic Key' + } + + $Title = "Do you want to use a custom Destination Path ?" + + $message = "You can specify a custom Destination Path for your ISO file." + + $NO = New-Object System.Management.Automation.Host.ChoiceDescription "&No", ` + "No, place the ISO file in the current folder." + + $YES = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", ` + "Yes, I want to specify a custom destination path." + + $options = [System.Management.Automation.Host.ChoiceDescription[]]($NO, $YES) + + $result = $host.ui.PromptForChoice($title, $message, $options, 0) + + switch ($result) + { + 0 {$CustomPath = '.'} + 1 {$CustomPath = Read-Host 'Please enter a custom destination path'} + } + + foreach ($item in (get-item *.esd)) { + if ($esdnames -eq $null) { + $esdnames = @() + $esdpaths = @() + } + $esdnames += $item.Name + $esdpaths += $item.FullName + } + + if ($esdnames -ne $null) { + $esdnames += 'None of these (You will be prompt for one or multiple esd files path names later)' + $esdpaths += 'None' + Write-Host ' +Please Select which ESD you want to Convert +=========================================== +' + $selected = Menu-Select $esdnames $esdpaths + + if ($selected -eq 'None') { + if ($CustomKey -eq $true) { + Convert-ESD -CryptoKey $key -extensiontype $extensiontype -Destination $CustomPath + } else { + Convert-ESD -extensiontype $extensiontype -Destination $CustomPath + } + } else { + if ($CustomKey -eq $true) { + Convert-ESD -CryptoKey $key -extensiontype $extensiontype -Destination $CustomPath -esdfiles $selected + } else { + Convert-ESD -extensiontype $extensiontype -Destination $CustomPath -esdfiles $selected + } + } + } else { + if ($CustomKey -eq $true) { + Convert-ESD -CryptoKey $key -extensiontype $extensiontype -Destination $CustomPath + } else { + Convert-ESD -extensiontype $extensiontype -Destination $CustomPath + } + } +} + +if ($ESD -ne $null) { + if ($CryptoKey -eq $null) { + Convert-ESD -esdfiles $ESD -Destination $Destination -extensiontype $extensiontype + } else { + Convert-ESD -esdfiles $ESD -Destination $Destination -extensiontype $extensiontype -CryptoKey $CryptoKey + } + return +} + +New-Wizard-Decrypt \ No newline at end of file diff --git a/bin/esd_lib_new.ps1 b/bin/esd_lib_new.ps1 new file mode 100644 index 0000000..2691048 --- /dev/null +++ b/bin/esd_lib_new.ps1 @@ -0,0 +1,1434 @@ +#Dependencies: . '.\bin\utils.ps1' + +New-Enum iso.filenametype Partner Consumer Windows7 +New-Enum wim.extensiontype WIM ESD + +function Select-Menu ($displayoptions, $arrayofoptions) { + Do { + $counter = 0 + if ($displayoptions.Count -ne 1) { + foreach ($item in $displayoptions) { + $counter++ + $padding = ' ' * ((([string]$displayoptions.Length).Length) - (([string]$counter).Length)) + Write-host -ForeGroundColor White ('['+$counter+']'+$padding+' '+$item) + } + Write-Host '' + $choice = read-host -prompt "Select number and press enter" + } else { + $counter++ + $choice = 1 + } + } until ([int]$choice -gt 0 -and [int]$choice -le $counter) + $choice = $choice - 1 + return $arrayofoptions[$choice] +} + +function Get-ScriptDirectory { + Split-Path -parent $PSCommandPath +} + +#Is this a Wow64 powershell host +function Test-Wow64 { + return (Test-Win32) -and (test-path env:\PROCESSOR_ARCHITEW6432) +} + +#Is this a 64 bit process +function Test-Win64 { + return [IntPtr]::size -eq 8 +} + +#Is this a 32 bit process +function Test-Win32 { + return [IntPtr]::size -eq 4 +} + +if (Test-Wow64) { + $wimlib = '.\bin\wimlib-imagex.exe' +} elseif (Test-Win64) { + $wimlib = '.\bin\bin64\wimlib-imagex.exe' +} elseif (Test-Win32) { + $wimlib = '.\bin\wimlib-imagex.exe' +} else { + return +} + +function Copy-File { + param( + [string]$from, + [string]$to + ) + $ffile = [io.file]::OpenRead($from) + $tofile = [io.file]::OpenWrite($to) + try { + $sw = [System.Diagnostics.Stopwatch]::StartNew() + [byte[]]$buff = new-object byte[] (4096*1024) + [long]$total = [long]$count = 0 + do { + $count = $ffile.Read($buff, 0, $buff.Length) + $tofile.Write($buff, 0, $count) + $total += $count + [int]$pctcomp = ([int]($total/$ffile.Length* 100)) + [int]$secselapsed = [int]($sw.elapsedmilliseconds.ToString())/1000 + if ($secselapsed -ne 0) { + [single]$xferrate = (($total/$secselapsed)/1mb) + } else { + [single]$xferrate = 0.0 + } + if ($total % 1mb -eq 0) { + if($pctcomp -gt 0) { + [int]$secsleft = ((($secselapsed/$pctcomp)* 100)-$secselapsed) + } else { + [int]$secsleft = 0 + } + if ($pastpct -ne $pctcomp) { + Write-Progress ` + -Activity ($pctcomp.ToString() + "% Copying file @ " + "{0:n2}" -f $xferrate + " MB/s")` + -status ($from.Split("\")|select -last 1) ` + -PercentComplete $pctcomp ` + -SecondsRemaining $secsleft; + } + $pastpct = $pctcomp + } + } while ($count -gt 0) + $sw.Stop(); + $sw.Reset(); + } + finally { + Write-Progress -Activity ($pctcomp.ToString() + "% Copying file @ " + "{0:n2}" -f $xferrate + " MB/s") -Complete + Write-Host (($from.Split("\")|select -last 1) + ` + " copied in " + $secselapsed + " seconds at " + ` + "{0:n2}" -f [int](($ffile.length/$secselapsed)/1mb) + " MB/s."); + $ffile.Close(); + $tofile.Close(); + } +} + +function Convert-ESDs ( + [parameter(Mandatory=$true)] + [Boolean] $Backup, + [ValidateNotNullOrEmpty()] + [ValidateScript({(Test-Path $_) -and ((Get-Item $_).Extension -eq ".esd")})] + [parameter(Mandatory=$true)] + [Array] $ESD, + [parameter(Mandatory=$false)] + [Array] $RSAKey +) +{ + [Array]$ESDs = @() + [Array]$BackedUpESDs = @() + foreach ($esdfile in $ESD) { + & $wimlib info "$($esdfile)" > $null + if ($LASTEXITCODE -eq 74) { + $tempesd = $esdfile + if ($Backup) { + $BackedUpESDs += ($esdfile+'.mod') + Copy-File $esdfile ($esdfile+'.mod') + $tempesd = ($esdfile+'.mod') + } + $ESDs += $tempesd + & ".\bin\esddecrypt.exe" "$($tempesd)" "$($RSAKey)" + if ($LASTEXITCODE -ne 0) { + if ($Backup) { + foreach ($bakesd in $BackedUpESDs) { + remove-item $bakesd -force + } + } + return $LASTEXITCODE + } + } elseif ($LASTEXITCODE -eq 18) { + if ($Backup) { + foreach ($bakesd in $BackedUpESDs) { + remove-item $bakesd -force + } + } + return 18 + } else { + $ESDs += $esdfile + } + } + return $ESDs, $BackedUpESDs +} + +function New-x64x86Media { + Copy-Item .\Media\x86\boot\ .\Media\ -recurse + Copy-Item .\Media\x86\efi\ .\Media\ -recurse + Copy-Item .\Media\x86\bootmgr .\Media\ + Copy-Item .\Media\x86\bootmgr.efi .\Media\ + Copy-Item .\Media\x86\autorun.inf .\Media\ + Copy-Item .\Media\x86\setup.exe .\Media\ + Copy-Item .\Media\x64\efi\boot\bootx64.efi .\Media\efi\boot\ + $x64guid = bcdedit /store .\Media\boot\bcd /v ` + | Select-String "path" -Context 2,0 ` + | % { $_.Context.PreContext[0] -replace '^identifier +' } ` + | ? { $_ -ne "{default}" } + bcdedit /store .\Media\boot\bcd /set "{default}" description "Windows 10 Setup (64-bit)" + bcdedit /store .\Media\boot\bcd /set "{default}" device ramdisk=[boot]\x64\sources\boot.wim,$x64guid + bcdedit /store .\Media\boot\bcd /set "{default}" osdevice ramdisk=[boot]\x64\sources\boot.wim,$x64guid + bcdedit /store .\Media\boot\bcd /copy "{default}" /d "Windows 10 Setup (32-bit)" + $x86guid = bcdedit /store .\Media\boot\bcd /v ` + | Select-String "path" -Context 2,0 ` + | % { $_.Context.PreContext[0] -replace '^identifier +' } ` + | ? { $_ -ne "$x64guid" } + bcdedit /store .\Media\boot\bcd /set "$($x86guid)" device ramdisk=[boot]\x86\sources\boot.wim,$x64guid + bcdedit /store .\Media\boot\bcd /set "$($x86guid)" osdevice ramdisk=[boot]\x86\sources\boot.wim,$x64guid + Remove-item .\Media\boot\bcd.LOG -force + Remove-item .\Media\boot\bcd.LOG1 -force + Remove-item .\Media\boot\bcd.LOG2 -force +} + +function CleanTM ( + [parameter(Mandatory=$true)] + $BackedUpESDs +) +{ + if (Test-Path '.\Media\') { + Remove-Item -recurse .\Media -force + } + if ($bakesd -ne $null) { + foreach ($bakesd in $BackedUpESDs) { + remove-item $bakesd -force + } + } +} + +function Get-InfosFromESD ( + [parameter(Mandatory=$true,HelpMessage="The complete path to the ESD file to convert.")] + [Array] $ESD +) +{ + $esdinformations = @() + foreach ($esdfile in $ESD) { + $result = "" | select MajorVersion, MinorVersion, BuildNumber, DeltaVersion, BranchName, CompileDate, Architecture, BuildType, Type, Sku, Editions, Licensing, LanguageCode, VolumeLabel, BuildString, ESDs + + $editions = @() + $counter = 0 + + $WIMInfo = New-Object System.Collections.ArrayList + $WIMInfo=@{} + + for ($i=1; $i -le 3; $i++){ + $counter++ + $WIMInfo[$counter] = @{} + $OutputVariable = ( & $wimlib info "$($esdfile)" $i) + ForEach ($Item in $OutputVariable) { + $CurrentItem = ($Item -replace '\s+', ' ').split(':') + $CurrentItemName = $CurrentItem[0] -replace ' ', '' + if (($CurrentItem[1] -replace ' ', '') -ne '') { + $WIMInfo[$counter][$CurrentItemName] = $CurrentItem[1].Substring(1) + } + } + } + + $header = @{} + $OutputVariable = ( & $wimlib info "$($esdfile)" --header) + ForEach ($Item in $OutputVariable) { + $CurrentItem = ($Item -replace '\s+', ' ').split('=') + $CurrentItemName = $CurrentItem[0] -replace ' ', '' + if (($CurrentItem[1] -replace ' ', '') -ne '') { + $header[$CurrentItemName] = $CurrentItem[1].Substring(1) + } + } + + for ($i=4; $i -le $header.ImageCount; $i++){ + $counter++ + $WIMInfo[$counter] = @{} + $OutputVariable = ( & $wimlib info "$($esdfile)" $i) + ForEach ($Item in $OutputVariable) { + $CurrentItem = ($Item -replace '\s+', ' ').split(':') + $CurrentItemName = $CurrentItem[0] -replace ' ', '' + if (($CurrentItem[1] -replace ' ', '') -ne '') { + $WIMInfo[$counter][$CurrentItemName] = $CurrentItem[1].Substring(1) + if ($CurrentItemName -eq 'EditionID') { + $lastedition = $CurrentItem[1].Substring(1) + $editions += $CurrentItem[1].Substring(1) + } + } + } + } + + $WIMInfo["header"] = @{} + $WIMInfo["header"]["ImageCount"] = ($counter.toString()) + + $result.Editions = $editions + + # Converting standards architecture names to friendly ones, if we didn't found any, we put the standard one instead * cough * arm / ia64, + # Yes, IA64 is still a thing for server these days... + if ($WIMInfo[4].Architecture -eq 'x86') { + $result.Architecture = 'x86' + } elseif ($WIMInfo[4].Architecture -eq 'x86_64') { + $result.Architecture = 'amd64' + } else { + $result.Architecture = $WIMInfo[4].Architecture + } + + # Gathering Compiledate and the buildbranch from the ntoskrnl executable. + Write-Host 'Checking critical system files for a build string and build type information...' + & $wimlib extract $esdfile 4 windows\system32\ntkrnlmp.exe windows\system32\ntoskrnl.exe --nullglob --no-acls | out-null + if (Test-Path .\ntkrnlmp.exe) { + $result.CompileDate = (Get-item .\ntkrnlmp.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') + $result.BranchName = (Get-item .\ntkrnlmp.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + if ((Get-item .\ntkrnlmp.exe).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $ProductVersion = (Get-item .\ntkrnlmp.exe).VersionInfo.ProductVersion + remove-item .\ntkrnlmp.exe -force + } elseif (Test-Path .\ntoskrnl.exe) { + $result.CompileDate = (Get-item .\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[1].replace(')', '') + $result.BranchName = (Get-item .\ntoskrnl.exe).VersionInfo.FileVersion.split(' ')[1].split('.')[0].Substring(1) + if ((Get-item .\ntoskrnl.exe).VersionInfo.IsDebug) { + $result.BuildType = 'chk' + } else { + $result.BuildType = 'fre' + } + $ProductVersion = (Get-item .\ntoskrnl.exe).VersionInfo.ProductVersion + remove-item .\ntoskrnl.exe -force + } + + $result.MajorVersion = $ProductVersion.split('.')[0] + $result.MinorVersion = $ProductVersion.split('.')[1] + $result.BuildNumber = $ProductVersion.split('.')[2] + $result.DeltaVersion = $ProductVersion.split('.')[3] + + # Gathering Compiledate and the buildbranch from the build registry. + Write-Host 'Checking registry for a more accurate build string...' + & $wimlib extract $esdfile 4 windows\system32\config\ --no-acls | out-null + & 'reg' load HKLM\RenameISOs .\config\SOFTWARE | out-null + $output = ( & 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion" /v "BuildLab") + if (($output[2] -ne $null) -and (-not ($output[2].Split(' ')[-1].Split('.')[-1]) -eq '')) { + $result.CompileDate = $output[2].Split(' ')[-1].Split('.')[-1] + $result.BranchName = $output[2].Split(' ')[-1].Split('.')[-2] + $output_ = ( & 'reg' query "HKLM\RenameISOs\Microsoft\Windows NT\CurrentVersion" /v "BuildLabEx") + if (($output_[2] -ne $null) -and (-not ($output_[2].Split(' ')[-1].Split('.')[-1]) -eq '')) { + if ($output_[2].Split(' ')[-1] -like '*.*.*.*.*') { + $result.BuildNumber = $output_[2].Split(' ')[-1].Split('.')[0] + $result.DeltaVersion = $output_[2].Split(' ')[-1].Split('.')[1] + } + } + } else { + Write-Host 'Registry check was unsuccessful. Aborting and continuing with critical system files build string...' + } + & 'reg' unload HKLM\RenameISOs | out-null + remove-item .\config\ -recurse -force + + # Defining if server or client thanks to Microsoft including 'server' in the server sku names + if (($WIMInfo.header.ImageCount -gt 4) -and (($WIMInfo[4].EditionID) -eq $null)) { + $result.Type = 'client' + $result.Sku = $null + } elseif (($WIMInfo[4].EditionID) -eq $null) { + $result.Type = 'client' + $result.Sku = 'unstaged' + } elseif (($WIMInfo[4].EditionID.toLower()) -like '*server*') { + $result.Type = 'server' + $result.Sku = $WIMInfo[4].EditionID.toLower() -replace 'server', '' + } else { + $result.Type = 'client' + $result.Sku = $WIMInfo[4].EditionID.toLower() + } + + $result.Licensing = 'Retail' + + & $wimlib extract $esdfile 1 sources\ei.cfg --nullglob --no-acls | out-null + if (Test-Path ".\ei.cfg") { + $content = @() + Get-Content (".\ei.cfg") | foreach-object -process { + $content += $_ + } + $counter = 0 + foreach ($item in $content) { + $counter++ + if ($item -eq '[EditionID]') { + $result.Sku = $content[$counter] + } + } + $counter = 0 + foreach ($item in $content) { + $counter++ + if ($item -eq '[Channel]') { + $result.Licensing = $content[$counter] + } + } + Remove-Item ".\ei.cfg" -force + } + + if (($WIMInfo.header.ImageCount -eq 7) -and ($result.Type -eq 'server')) { + $result.Sku = $null + } + + & $wimlib extract $esdfile 1 sources\lang.ini --nullglob --no-acls | out-null + Get-Content ('lang.ini') | foreach-object -begin {$h=@()} -process { $k = [regex]::split($_,'`r`n'); if(($k[0].CompareTo("") -ne 0)) { $h += $k[0] } } + $result.LanguageCode = ($h[((0..($h.Count - 1) | Where { $h[$_] -eq '[Available UI Languages]' }) + 1)]).split('=')[0].Trim() + remove-item lang.ini -force + + $tag = 'ir3' + $DVD = 'DV9' + + if ($WIMInfo[4].Architecture -eq 'x86') { + $arch = 'x86' + } + + if ($WIMInfo[4].Architecture -eq 'x86_64') { + $arch = 'x64' + } + + if ($WIMInfo[4].ServicePackBuild -eq '17056') { + $tag = 'ir4' + } + if ($WIMInfo[4].ServicePackBuild -eq '17415') { + $tag = 'ir5' + } + if ($WIMInfo[4].ServicePackBuild -gt '17415') { + $tag = 'ir6' + } + + if ([int] $WIMInfo[4].Build -gt '9600') { + $tag = 'JM1' + $DVD = 'DV5' + } + if ([int] $WIMInfo[4].Build -ge '9896') { + $tag = 'J' + $DVD = 'DV5' + } + + if ($result.Licensing.toLower() -eq 'volume') { + $ltag = 'FREV_' + } elseif ($result.Licensing.toLower() -eq 'oem') { + $ltag = 'FREO_' + } else { + $ltag = 'FRE_' + } + + $DVDLabel = ($tag+'_CCSA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper() + if ($WIMInfo.header.ImageCount -eq 4) { + if ($WIMInfo[4].EditionID -eq 'Core') {$DVDLabel = ($tag+'_CCRA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreConnected') {$DVDLabel = ($tag+'_CCONA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreConnectedCountrySpecific') {$DVDLabel = ($tag+'_CCCHA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreConnectedN') {$DVDLabel = ($tag+'_CCONNA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreConnectedSingleLanguage') {$DVDLabel = ($tag+'_CCSLA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreCountrySpecific') {$DVDLabel = ($tag+'_CCHA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreN') {$DVDLabel = ($tag+'_CCRNA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'CoreSingleLanguage') {$DVDLabel = ($tag+'_CSLA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'Professional') {$DVDLabel = ($tag+'_CPRA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'ProfessionalN') {$DVDLabel = ($tag+'_CPRNA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'ProfessionalStudent') {$DVDLabel = ($tag+'_CPRSA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'ProfessionalStudentN') {$DVDLabel = ($tag+'_CPRSNA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'ProfessionalWMC') {$DVDLabel = ($tag+'_CPWMCA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'Education') {$DVDLabel = ($tag+'_CEDA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'EducationN') {$DVDLabel = ($tag+'_CEDNA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'Enterprise') {$DVDLabel = ($tag+'_CENA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'EnterpriseN') {$DVDLabel = ($tag+'_CENNA_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'EnterpriseS') {$DVDLabel = ($tag+'_CES_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + if ($WIMInfo[4].EditionID -eq 'EnterpriseSN') {$DVDLabel = ($tag+'_CESN_'+$arch+$ltag+$WIMInfo[4].DefaultLanguage+'_'+$DVD).ToUpper()} + } + + $result.VolumeLabel = $DVDLabel + $result.BuildString = ($result.MajorVersion+'.'+$result.MinorVersion+'.'+$result.BuildNumber+'.'+$result.DeltaVersion+'.'+$result.BranchName+'.'+$result.CompileDate) + $result.ESDs = [array]$esdfile + $esdinformations += $result + } + $archs = @() + ($esdinformations | select Architecture).Architecture | % { + if (-not ($archs -contains $_.toLower())) { + $archs += $_.toLower() + } + } + $filename = $null + foreach ($arch in $archs) { + $currentesds1 = ($esdinformations | Where-Object { $_.architecture.toLower() -eq $arch }) + $buildtypes = @() + ($currentesds1 | select BuildType).BuildType | % { + if (-not ($buildtypes -contains $_.toLower())) { + $buildtypes += $_.toLower() + } + } + foreach ($buildtype in $buildtypes) { + $currentesds2 = ($currentesds1 | Where-Object { $_.buildtype.toLower() -eq $buildtype }) + $builds = @() + ($currentesds2 | select BuildString).BuildString | % { + if (-not ($builds -contains $_.toLower())) { + $builds += $_.toLower() + } + } + foreach ($build in $builds) { + $currentesds3 = ($currentesds2 | Where-Object {$_.BuildString.toLower() -eq $build }) + $languages = @() + ($currentesds3 | select LanguageCode).LanguageCode | % { + if (-not ($languages -contains $_.toLower())) { + $languages += $_.toLower() + } + } + foreach ($language in $languages) { + $currentesds4 = ($currentesds3 | Where-Object {$_.LanguageCode -eq $language }) + $Edition = $null + $Licensing = $null + ($currentesds4 | select Editions).Editions | % { + if ($_ -is [System.Array]) { + foreach ($item in $_) { + if ($Edition -eq $null) { + $Edition_ = $item + if ($item -eq 'Core') {$Edition_ = 'CORE'} + if ($item -eq 'CoreN') {$Edition_ = 'COREN'} + if ($item -eq 'CoreSingleLanguage') {$Edition_ = 'SINGLELANGUAGE'} + if ($item -eq 'CoreCountrySpecific') {$Edition_ = 'CHINA'} + if ($item -eq 'Professional') {$Edition_ = 'PRO'} + if ($item -eq 'ProfessionalN') {$Edition_ = 'PRON'} + if ($item -eq 'ProfessionalWMC') {$Edition_ = 'PROWMC'} + if ($item -eq 'CoreConnected') {$Edition_ = 'CORECONNECTED'} + if ($item -eq 'CoreConnectedN') {$Edition_ = 'CORECONNECTEDN'} + if ($item -eq 'CoreConnectedSingleLanguage') {$Edition_ = 'CORECONNECTEDSINGLELANGUAGE'} + if ($item -eq 'CoreConnectedCountrySpecific') {$Edition_ = 'CORECONNECTEDCHINA'} + if ($item -eq 'ProfessionalStudent') {$Edition_ = 'PROSTUDENT'} + if ($item -eq 'ProfessionalStudentN') {$Edition_ = 'PROSTUDENTN'} + if ($item -eq 'Enterprise') {$Edition_ = 'ENTERPRISE'} + $Edition = $Edition_ + } else { + $Edition_ = $item_ + if ($item -eq 'Core') {$Edition_ = 'CORE'} + if ($item -eq 'CoreN') {$Edition_ = 'COREN'} + if ($item -eq 'CoreSingleLanguage') {$Edition_ = 'SINGLELANGUAGE'} + if ($item -eq 'CoreCountrySpecific') {$Edition_ = 'CHINA'} + if ($item -eq 'Professional') {$Edition_ = 'PRO'} + if ($item -eq 'ProfessionalN') {$Edition_ = 'PRON'} + if ($item -eq 'ProfessionalWMC') {$Edition_ = 'PROWMC'} + if ($item -eq 'CoreConnected') {$Edition_ = 'CORECONNECTED'} + if ($item -eq 'CoreConnectedN') {$Edition_ = 'CORECONNECTEDN'} + if ($item -eq 'CoreConnectedSingleLanguage') {$Edition_ = 'CORECONNECTEDSINGLELANGUAGE'} + if ($item -eq 'CoreConnectedCountrySpecific') {$Edition_ = 'CORECONNECTEDCHINA'} + if ($item -eq 'ProfessionalStudent') {$Edition_ = 'PROSTUDENT'} + if ($item -eq 'ProfessionalStudentN') {$Edition_ = 'PROSTUDENTN'} + if ($item -eq 'Enterprise') {$Edition_ = 'ENTERPRISE'} + $Edition = $Edition+'-'+$Edition_ + } + } + } else { + if ($Edition -eq $null) { + $Edition_ = $_ + if ($_ -eq 'Core') {$Edition_ = 'CORE'} + if ($_ -eq 'CoreN') {$Edition_ = 'COREN'} + if ($_ -eq 'CoreSingleLanguage') {$Edition_ = 'SINGLELANGUAGE'} + if ($_ -eq 'CoreCountrySpecific') {$Edition_ = 'CHINA'} + if ($_ -eq 'Professional') {$Edition_ = 'PRO'} + if ($_ -eq 'ProfessionalN') {$Edition_ = 'PRON'} + if ($_ -eq 'ProfessionalWMC') {$Edition_ = 'PROWMC'} + if ($_ -eq 'CoreConnected') {$Edition_ = 'CORECONNECTED'} + if ($_ -eq 'CoreConnectedN') {$Edition_ = 'CORECONNECTEDN'} + if ($_ -eq 'CoreConnectedSingleLanguage') {$Edition_ = 'CORECONNECTEDSINGLELANGUAGE'} + if ($_ -eq 'CoreConnectedCountrySpecific') {$Edition_ = 'CORECONNECTEDCHINA'} + if ($_ -eq 'ProfessionalStudent') {$Edition_ = 'PROSTUDENT'} + if ($_ -eq 'ProfessionalStudentN') {$Edition_ = 'PROSTUDENTN'} + if ($_ -eq 'Enterprise') {$Edition_ = 'ENTERPRISE'} + $Edition = $Edition_ + } else { + $Edition_ = $_ + if ($_ -eq 'Core') {$Edition_ = 'CORE'} + if ($_ -eq 'CoreN') {$Edition_ = 'COREN'} + if ($_ -eq 'CoreSingleLanguage') {$Edition_ = 'SINGLELANGUAGE'} + if ($_ -eq 'CoreCountrySpecific') {$Edition_ = 'CHINA'} + if ($_ -eq 'Professional') {$Edition_ = 'PRO'} + if ($_ -eq 'ProfessionalN') {$Edition_ = 'PRON'} + if ($_ -eq 'ProfessionalWMC') {$Edition_ = 'PROWMC'} + if ($_ -eq 'CoreConnected') {$Edition_ = 'CORECONNECTED'} + if ($_ -eq 'CoreConnectedN') {$Edition_ = 'CORECONNECTEDN'} + if ($_ -eq 'CoreConnectedSingleLanguage') {$Edition_ = 'CORECONNECTEDSINGLELANGUAGE'} + if ($_ -eq 'CoreConnectedCountrySpecific') {$Edition_ = 'CORECONNECTEDCHINA'} + if ($_ -eq 'ProfessionalStudent') {$Edition_ = 'PROSTUDENT'} + if ($_ -eq 'ProfessionalStudentN') {$Edition_ = 'PROSTUDENTN'} + if ($_ -eq 'Enterprise') {$Edition_ = 'ENTERPRISE'} + $Edition = $Edition+'-'+$Edition_ + } + } + } + ($currentesds4 | select Licensing).Licensing | % { + if ($Licensing -eq $null) { + $Licensing = $_ + } else { + if (-not ($Licensing -contains $_)) { + $Licensing = $Licensing+$_ + } + } + } + $Edition = $Edition.toUpper() -replace 'SERVERHYPER', 'SERVERHYPERCORE' -replace 'SERVER', '' + $Licensing = $Licensing.toUpper() -replace 'VOLUME', 'VOL' -replace 'RETAIL', 'RET' + if ($Edition -eq 'PRO-CORE') { + $Licensing = 'OEMRET' + } + if ($Edition.toLower() -eq 'unstaged') { + $Edition = '' + } + $arch_ = $arch -replace 'amd64', 'x64' + if ($currentesds4 -is [System.Array]) { + $FILENAME_ = ($currentesds4[0].BuildNumber+'.'+$currentesds4[0].DeltaVersion+'.'+$currentesds4[0].CompileDate+'.'+$currentesds4[0].BranchName) + } else { + $FILENAME_ = ($currentesds4.BuildNumber+'.'+$currentesds4.DeltaVersion+'.'+$currentesds4.CompileDate+'.'+$currentesds4.BranchName) + } + $FILENAME_ = ($FILENAME_+'_CLIENT'+$Edition+'_'+$Licensing+'_'+$arch_+$buildtype+'_'+$language).toUpper() + if ($filename -eq $null) { + $filename = $FILENAME_ + } else { + $filename = $filename+'-'+$FILENAME_ + } + $parts += 1 + } + } + } + } + + $tag = 'ir3' + $DVD = 'DV9' + if ($esdinformations[0].Architecture -eq 'x86') { + $arch = 'x86' + } + if ($esdinformations[0].Architecture -eq 'x86_64') { + $arch = 'x64' + } + if ([int] $esdinformations[0].DeltaVersion -eq '17056') { + $tag = 'ir4' + } + if ([int] $esdinformations[0].DeltaVersion -eq '17415') { + $tag = 'ir5' + } + if ([int] $esdinformations[0].DeltaVersion -gt '17415') { + $tag = 'ir6' + } + if ([int] $esdinformations[0].BuildNumber -gt '9600') { + $tag = 'JM1' + $DVD = 'DV5' + } + if ([int] $esdinformations[0].BuildNumber -ge '9896') { + $tag = 'J' + $DVD = 'DV5' + } + if ($esdinformations[0].Licensing.toLower() -eq 'volume') { + $ltag = 'FREV_' + } elseif ($esdinformations[0].Licensing.toLower() -eq 'oem') { + $ltag = 'FREO_' + } else { + $ltag = 'FRE_' + } + + $filename = ($filename+'.ISO').toUpper() + + if ($esdinformations.count -eq 1) { + $DVDLabel = $esdinformations[0].VolumeLabel + } elseif ($esdinformations.count -eq 2 -and $esdinformations[0].Editions -eq "Professional" -and $esdinformations[1].Editions -eq "Core" -and $parts -eq 1) { + $DVDLabel = ($tag+'_CCSA_'+$arch+$ltag+$esdinformations[0].LanguageCode+'_'+$DVD).ToUpper() + } else { + $DVDLabel = "ESD-ISO" + } + + Write-Host Filename: $filename + Write-Host Volume Label: $DVDLabel + + return $filename, $DVDLabel, $esdinformations +} + +function prepforconvert ( + [ValidateNotNullOrEmpty()] + [ValidateScript({(Test-Path $_) -and ((Get-Item $_).Extension -eq ".esd")})] + [parameter(Mandatory=$true,HelpMessage="The complete path to the ESD file to convert.")] + [Array] $esdfiles, + [parameter(Mandatory=$false,HelpMessage="The crypto key that will be used to decrypt the ESD file.")] + $CryptoKey +) +{ + + if ($CryptoKey -ne $null) { + $result = (Convert-ESDs -Backup $true -ESD $esdfiles -RSAKey $CryptoKey) + } else { + $result = (Convert-ESDs -Backup $true -ESD $esdfiles) + } + [array]$esdinfos = @() + if ($result -is [system.array]) { + $results = Get-InfosFromESD -ESD $result[0] + $esdinfos = $results[2] + $volumelabel = $results[1] + $filename = $results[0] + } + return $result, $esdinfos, $filename, $volumelabel +} + +function Convert-ESD ( + [ValidateNotNullOrEmpty()] + [ValidateScript({(Test-Path $_) -and ((Get-Item $_).Extension -eq ".esd")})] + [parameter(Mandatory=$true,HelpMessage="The complete path to the ESD file to convert.")] + [Array] $esdfiles, + [ValidateNotNullOrEmpty()] + [parameter(Mandatory=$true,HelpMessage="The place where the final ISO file will be stored")] + [System.IO.DirectoryInfo] $Destination, + [ValidateNotNullOrEmpty()] + [parameter(Mandatory=$false,HelpMessage="The crypto key that will be used to decrypt the ESD file.")] + $CryptoKey, + [parameter(Mandatory=$true,HelpMessage="The type of extension used for the Windows Image (WIM or ESD)")] + [wim.extensiontype] $extensiontype +) +{ + $Results = prepforconvert -ESDFiles $esdfiles -CryptoKey $CryptoKey + $filename = $Results[2] + $label = $Results[3] + $result = $Results[0] + [array]$esdinfos = $Results[1] + if ($result -is [System.Array]) { + + } elseif ($result -eq 18) { + #NotOriginal + CleanTM($result[1]) + return + } else { + #Damaged + CleanTM($result[1]) + return + } + $items = @{} + $archs = @() + foreach ($architecture in $esdinfos.Architecture) { + $items[$architecture] = @{} + $items[$architecture]["SetupESDs"] = @() + foreach ($esd in ($esdinfos | ? {$_.Architecture -eq $architecture})) { + $items[$architecture]["SetupESDs"] += $esd | ? { -not (($items.$architecture.SetupESDs | ? {$_.LanguageCode -eq $esd.LanguageCode}).BuildString -contains $esd.BuildString) } + } + $items[$architecture]["WinREESDs"] = @() + foreach ($esd in ($esdinfos | ? {$_.Architecture -eq $architecture})) { + $items[$architecture]["WinREESDs"] += $esd | ? { -not (($items.$architecture.WinREESDs | ? {$_.LanguageCode -eq $esd.LanguageCode}).BuildString -contains $esd.BuildString) } + } + $items[$architecture]["InstallESDs"] = @() + $items[$architecture]["InstallESDs"] += ($esdinfos | ? {$_.Architecture -eq $architecture}) + $archs += $architecture | ? { -not ($archs -contains $architecture) } + } + if ($items.Count -gt 1) { + function SelectESD($Global:var) { + + $choicesx86 = @() + foreach ($item in $Global:var[0]) { + $displayitem = [string]($item.BuildString+' - '+$item.Architecture+$item.BuildType+' - '+$item.LanguageCode) + $choicesx86 += $displayitem + } + $peitemsx86 = $Global:var[0] + Write-host " +Select your i386 Windows Preinstallation environement source +============================================================ + " + $Global:WinPEESD_x86 = (Select-Menu $choicesx86 $peitemsx86) + $reitemsx86 = $GLobal:var[0] + Write-host " +Select your i386 Windows Recovery environement source +===================================================== + " + $Global:WinREESD_x86 = (Select-Menu $choicesx86 $reitemsx86) + + $choicesx64 = @() + foreach ($item in $Global:var[1]) { + $displayitem = [string]($item.BuildString+' - '+$item.Architecture+$item.BuildType+' - '+$item.LanguageCode) + $choicesx64 += $displayitem + } + $peitemsx64 = $Global:var[1] + Write-host " +Select your amd64 Windows Preinstallation environement source +============================================================= + " + $Global:WinPEESD_x64 = (Select-Menu $choicesx64 $peitemsx64) + $reitemsx64 = $GLobal:var[1] + Write-host " +Select your amd64 Windows Recovery environement source +====================================================== + " + $Global:WinREESD_x64 = (Select-Menu $choicesx64 $reitemsx64) + + return $Global:WinPEESD_x86, $Global:WinREESD_x86, $Global:WinPEESD_x64, $Global:WinREESD_x64 + } + #2 archs + foreach ($architecture in $archs) { + if ($architecture -eq 'amd64') { + $global:builds_x64 = @() + if ($items.$architecture.SetupESDs -is [system.array]) { + #more than 1 choice for setup + foreach ($item in $items.$architecture.SetupESDs) { + [array]$global:builds_x64 += $item + } + } else { + $item = $items.$architecture.SetupESDs + [array]$global:builds_x64 += $item + } + } else { + $global:builds_x86 = @() + if ($items.$architecture.SetupESDs -is [system.array]) { + #more than 1 choice for setup + foreach ($item in $items.$architecture.SetupESDs) { + [array]$global:builds_x86 += $item + } + } else { + $item = $items.$architecture.SetupESDs + [array]$global:builds_x86 += $item + } + } + } + $Results = SelectESD($global:builds_x86, $global:builds_x64) + $items["x86"]["WinREESD"] = @() + $items["x86"]["WinREESD"] = $Results[0] + $items["x86"]["SetupESD"] = $Results[1] + $items["amd64"]["WinREESD"] = @() + $items["amd64"]["WinREESD"] = $Results[0] + $items["amd64"]["SetupESD"] = $Results[1] + $items.x86.WinREESD.ESDs[0] + $items.x86.SetupESD.ESDs[0] + $items.amd64.WinREESD.ESDs[0] + $items.amd64.SetupESD.ESDs[0] + function New-ISO ( + $archs, + $items, + $clean, + $extensiontype, + $isoname, + $label + ) + { + Begin { + function Export-InstallWIM ( + [parameter(Mandatory=$true)] + [ValidateScript({(Test-Path $_)})] + [Array] $ESD, + [parameter(Mandatory=$true)] + [Int] $Index, + [parameter(Mandatory=$true)] + [ValidateScript({(Test-Path $_\)})] + [String] $Output, + [parameter(Mandatory=$true)] + [String] $ExtensionType + ) + { + $operationname = $null + $sw = [System.Diagnostics.Stopwatch]::StartNew(); + if ($extensiontype -eq 'ESD') { + $indexcount = 1 + if (Test-Path $Output\sources\install.esd) { + $header = @{} + $OutputVariable = (& $wimlib info "$($Output)\sources\install.esd" --header) + ForEach ($Item in $OutputVariable) { + $CurrentItem = ($Item -replace '\s+', ' ').split('=') + $CurrentItemName = $CurrentItem[0] -replace ' ', '' + if (($CurrentItem[1] -replace ' ', '') -ne '') { + $header[$CurrentItemName] = $CurrentItem[1].Substring(1) + } + } + $indexcount = $header.ImageCount + 1 + } + & $wimlib export "$($esdfile)" $Index $Output\sources\install.esd --compress=LZMS --solid | ForEach-Object -Process { + if ($operationname -eq $null) { + $operationname = $_ + } + $global:lastprogress = $progress + $global:progress = [regex]::match($_,'\(([^\)]+)\%').Groups[1].Value + if ($progress -match "[0-9]") { + $total = $_.split(' ')[0] + $totalsize = $_.split(' ')[3] + [long]$pctcomp = ([long]($total/$totalsize* 100)); + [long]$secselapsed = [long]($sw.elapsedmilliseconds.ToString())/1000; + if ($pctcomp -ne 0) { + [long]$secsleft = ((($secselapsed/$pctcomp)* 100)-$secselapsed) + } else { + [long]$secsleft = 0 + } + #Write-host Exporting to install.esd... $progress% - $operationname - Time remaining: $secsleft - $_ + Write-Progress -Activity ('Exporting Windows Installation...') -status ($operationname) -PercentComplete ($progress) -SecondsRemaining $secsleft -CurrentOperation $_ + if ($lastprogress -ne $progress) { + #Update-Window ConvertProgress Value $progress + } + } + if ($WIMInfo.$indexcounter.EditionID -eq 'ProfessionalWMC') { + cmd /c ($wimlib + ' update "$($Output)\sources\install.esd" $($indexcount) - + diff --git a/bin/xaml/askrsakey.xaml b/bin/xaml/askrsakey.xaml index 1cbc16e..bd63716 100644 --- a/bin/xaml/askrsakey.xaml +++ b/bin/xaml/askrsakey.xaml @@ -8,7 +8,7 @@ - + diff --git a/bin/xaml/convertend.xaml b/bin/xaml/convertend.xaml index 9e9bcef..16329e5 100644 --- a/bin/xaml/convertend.xaml +++ b/bin/xaml/convertend.xaml @@ -8,7 +8,7 @@ - + diff --git a/bin/xaml/converting.xaml b/bin/xaml/converting.xaml index b01fcca..e2f0938 100644 --- a/bin/xaml/converting.xaml +++ b/bin/xaml/converting.xaml @@ -8,7 +8,7 @@ - + diff --git a/bin/xaml/dropdown.xaml b/bin/xaml/dropdown.xaml index 1902a02..af579ee 100644 --- a/bin/xaml/dropdown.xaml +++ b/bin/xaml/dropdown.xaml @@ -9,7 +9,7 @@ - + diff --git a/bin/xaml/dropdown_single.xaml b/bin/xaml/dropdown_single.xaml index 4a553fc..5bf5d81 100644 --- a/bin/xaml/dropdown_single.xaml +++ b/bin/xaml/dropdown_single.xaml @@ -9,7 +9,7 @@ - + diff --git a/bin/xaml/fileformat.xaml b/bin/xaml/fileformat.xaml index ef986c3..1194cd2 100644 --- a/bin/xaml/fileformat.xaml +++ b/bin/xaml/fileformat.xaml @@ -8,7 +8,7 @@ - + diff --git a/bin/xaml/imageformat.xaml b/bin/xaml/imageformat.xaml index 797324b..94a4cfc 100644 --- a/bin/xaml/imageformat.xaml +++ b/bin/xaml/imageformat.xaml @@ -8,7 +8,7 @@ - + diff --git a/bin/xaml/prepconvert.xaml b/bin/xaml/prepconvert.xaml index 4f46319..2158c12 100644 --- a/bin/xaml/prepconvert.xaml +++ b/bin/xaml/prepconvert.xaml @@ -8,7 +8,7 @@ - + diff --git a/bin/xaml/recap.xaml b/bin/xaml/recap.xaml index 99834e5..5c71a62 100644 --- a/bin/xaml/recap.xaml +++ b/bin/xaml/recap.xaml @@ -8,7 +8,7 @@ - + diff --git a/bin/xaml/rsakey.xaml b/bin/xaml/rsakey.xaml index 8d0c444..63d2048 100644 --- a/bin/xaml/rsakey.xaml +++ b/bin/xaml/rsakey.xaml @@ -8,7 +8,7 @@ - + diff --git a/bin/xaml/selectesd.xaml b/bin/xaml/selectesd.xaml index b993196..24feb67 100644 --- a/bin/xaml/selectesd.xaml +++ b/bin/xaml/selectesd.xaml @@ -8,7 +8,7 @@ - + diff --git a/bin/xaml/welcome.xaml b/bin/xaml/welcome.xaml index 82a8ab7..98e5f27 100644 --- a/bin/xaml/welcome.xaml +++ b/bin/xaml/welcome.xaml @@ -10,7 +10,7 @@ - +