My mod is almost finished. The only portion I think I need help with is using the script in Vista. Since in Vista the script does not create a "System" W Drive. I have tried making the "Windows" drive as ACTIVE and running bcdboot C:\Windows on it but I get registry errors when Vista boots. I have also tried it using bcdboot X:\Windows before the drive letter changes and still get the same registry errors. In Windows 7 and Windows 8 the "System" W drive is created and the drive is made ACTIVE correctly. I'm sure it is me missing a step to ensure the Windows drive is properly pointed to for booting. Any ideas?
After speaking with murphy78 I have decided not to support Vista. I can't seem to figure out how to get it to work properly. If I find a way to support it later I'll do it... but for now my scripts will not support Vista either. I'm sure most users won't mind it anyways. I do have another minor question... Is there any downside to turning NOSYSPART on? NOSYSPART=1 I assume it would be needed for multiboot os setups... but there is no downside to turning off the creation of the 100/300MB System drive for a single os install is there?
I still haven't had proper time to go over proph's script, but in the meantime I changed a few minor things and updated mine to v1.2.6: Changed it so the DISK menu actually tells you what disk number is currently targeted (helpful, right?) Changed the winrecfg stuff so that you add the packages from packages i put in package folders instead of leaving them in by default. This is because kb2934018 will update these files if you actually add the package, and that's a good thing. Plus using the actual packages makes things a little more future-proof. I also added a menu.cmd in the system32 folder for the use-existing-setup files so people can just shift-f10 and type "MENU" like in my monthly releases to open the diskpart/apply script I still want to clean things up and re-design the script and the over-all methodology a bit. Although I'd be happier with a gui using WMIapi stuff, I'm happy enough with the diskpart /s importing method using the ramdrive for now. I do want to re-design the functionality of the script to be more like the Windows Setup in the future, excepting of course the things that aren't supported by default like split-wim without an autounattend, multi-boot, and the recovery image stuff. Sometimes letting your mind work in the background while you do other things is a good way to problem solve things when you are designing or re-designing something complex. I also am a firm believer in trying to simplify things if it's possible to simplify. I also want to de-duplicate some of the code if necessary. Multiple disk menus and prompts can be confusing, so I'd like to consolidate that stuff into a one-time selection with options process. I don't want the script to be confusing to the user. I want it to do what windows setup does, except also support multi-boot, recovery partition, and split-wim images without an autounattend to skip the eula setup failure. Anyway, OP updated to v1.2.6
Really nice script but just one question, once setup with the recovery option how does one actually enter the recovery environment? I have been playing around and I know there is the DART options if you boot the CD but cannot figure out how to get into the recovery. Any info would be really appreciated, I cannot find anything anywhere lol.
Windows has most of the recovery stuff automated in win8+ There are many ways to do the various features in the winre.wim Windows 8 also has a pseudo recovery environment. if you do a shutdown /r /o /t 0 it will logout and enter that pseudo recovery environment. It will have the default recovery options but it won't have anything that you've added to winre.wim like dart8.1 To access dart8.1 from the winre.wim you need to run Code: reagentc /boottore shutdown /r /t 0 Alternatively you can do a: Code: bcdedit /set {default} bootmenupolicy legacy and try to press f8 during boot. I find that this is damn near impossible though, so I usually recommend only doing that if you need to enter safe mode or something on the fly.
As far as windows 8 I know there is a lot of built in recovery but I was not 100% what all was entailed in the recovery partition your script creates. TBH I thought it was something similar that will bring you back to factory based with nothing installed like an OEM recovery partition lmfao.
What WHat WHAT!!! How come I didn't know about that? Does that also mean you could assign a function key to boot WinRE???
indeed. in my script I use f1. The actual command is: Code: winrecfg /setreimage /path W:\Recovery\WindowsRE /target Z:\Windows /bootkey 3b00 that's for winrecfg (the winpe version of reagentc) but you can just sub all the arguments for reagentc. I just left it at 3b00 because I don't know which ones do what, but that's f1 and it seems good enough for me.
I was planning on looking up what winrecfg actually did as I've never used it. I've used reagentc for everything - even in winpe/re... For notebooks all my Win7 images follow whatever the default manufacturer uses, ie MSI uses F3 which is 0x3d00. Wow this has made my day! Can't wait to try stuff out on the weekend! Thanks m8tty!!!
@ murphy78 I think this may be of some use for you: http://forums.mydigitallife.net/thr...)-without-downloading-ADK?p=929730#post929730 Best Regards
Hey murphy78, sorry I haven't been getting back the code I put out...I do have a lot of unfinished projects laying around that I just don't have time to work on by myself anymore, one of them being helping more with your awesome DiskPart and Apply Image Script. I did want to at least post the AutoIT script I started a while ago to interact with diskpart: Code: #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Version=Beta #AutoIt3Wrapper_Run_After=%out% #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ; By Gen 4-22-2014 #RequireAdmin #include <Constants.au3> #include <StaticConstants.au3> #include <GuiConstantsEx.au3> #include <MsgBoxConstants.au3> #include <FileConstants.au3> #include <WindowsConstants.au3> #include <Array.au3> #include <ButtonConstants.au3> #include <GUIButton.au3> ; If this option is used then all variables must be pre-declared with Local, Global or in some cases Dim before ; they can be used - removes the chance for misspelled variables causing bugs. Opt( "MustDeclareVars", 1 ) ;Local Const $wbemFlagReturnImmediately = 0x10 ;Local Const $wbemFlagForwardOnly = 0x20 Local Const $sProgName = "WinNTPart v0.1" Local Const $iSizeOfAllDiskInfo = 7 Local $iComboBox1, $iSysCheckBox, $iGPTCheckBox, $iWinRECheckBox, $iRecoveryCheckBox, $iGoButton, $aAllDiskInfo Local $bIsUEFIBooted Local $iWindowWidth = 500 Local $iWindowHeight = 300 Local $sessionid = String( Random(0,32768,1) ) Local $tempfile = @TempDir & 'winntpart.' & $sessionid & '.txt' ; Get the WMI object ;Local $oWMI = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2") ; Try to figure out if we have a Camera ; http://smsug.ca/blogs/garth_jones/archive/2013/04/02/find-all-webcam-wql.aspx ; Local $aItems = $oWMI.ExecQuery('SELECT * FROM SMS_R_System', "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) ;Local $aItems = $oWMI.ExecQuery('SELECT CS.Name0,SD.Name0,SD.DeviceID0 FROM dbo.v_GS_COMPUTER_SYSTEM CS join dbo.v_GS_SYSTEM_DEVICES SD on CS.ResourceID = SD.ResourceID Where SD.Name0 like "%Webcam%"', "SQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) ;If IsObj($aItems) then ; For $elements In $aItems ; MsgBox(0, "", $elements.Name0) ; Next ;Else ; Msgbox(0,"","No WMI Objects Found For Selection" ) ;EndIf ; Call main function main() ; Returns an array of size 2. ; Example of Diskpart Format: "Disk 0 Online 133GB 11GB * *" Func DPParseListDisk( $string ) Local $aListDisk[2], $match If $string Then $match = StringRegExp( $string, "^[[:space:]]+Disk [0-9]+[[:space:]]+[^[:space:]]+[[:space:]]+([0-9]+ [[:alpha:]]+)[[:space:]]+([0-9]+ [[:alpha:]]+)", 1) If Not @error Then $aListDisk[0] = $match[0] ; Disk Size $aListDisk[1] = $match[1] ; Free Space ;$aListDisk[2] = $match[3] ; Dynamic (may be empty) ;$aListDisk[3] = $match[4] ; GPT (may be empty) EndIf EndIf ; Sanity checks If Not $aListDisk[0] Then $aListDisk[0] = "ERROR" EndIf If Not $aListDisk[1] Then $aListDisk[1] = "ERROR" EndIf Return $aListDisk EndFunc ; Returns an array of size 5 Func DPParseDiskDetail($iDisk, $sListdisk) Local $aDiskInfo[5], $match, $file, $iPID, $sOutput, $aArray, $bNameNext $file = FileOpen( $tempfile, $FO_OVERWRITE ) FileWrite( $file, "select disk " & $iDisk & @CRLF & "detail disk" ) FileClose( $file ) $iPID = Run(@ComSpec & ' /c diskpart /s "' & $tempfile & '"',"", @SW_HIDE, $STDOUT_CHILD) ProcessWaitClose($iPID) $sOutput = StdoutRead($iPID) $aArray = StringSplit(StringTrimRight(StringStripCR($sOutput), StringLen(@CRLF)), @CRLF) If Not @error Then For $string In $aArray If StringLen( $string ) > 2 Then ; skip empty lines If Not $bNameNext Then If StringRegExp( $string, "^\s*Disk " & $iDisk & " is.*selected disk.*$" ) Then $bNameNext = True ; two lines down is name all by itself Else ; all other info If Not $aDiskInfo[4] Then $match = StringRegExp( $string, "Location Path[^:]*:\s?([^[:space:]]+)", 1) If Not @error Then $aDiskInfo[4] = $match[0] ; Location Path (IE, "PCIROOT(0)#PCI(1F02)#ATA(C00T00L00)") ContinueLoop EndIf EndIf If Not $aDiskInfo[3] Then $match = StringRegExp( $string, "Status[^:]*:\s?([[:alnum:]]+)", 1) If Not @error Then $aDiskInfo[3] = $match[0] ; Disk Status ContinueLoop EndIf EndIf If Not $aDiskInfo[2] Then $match = StringRegExp( $string, "Type[^:]*:\s?([[:alnum:]]+)", 1) If Not @error Then $aDiskInfo[2] = $match[0] ; Disk (Bus) Type ContinueLoop EndIf EndIf If Not $aDiskInfo[1] Then $match = StringRegExp( $string, "Disk ID[^:]*:\s?([[:alnum:]]+)", 1) If Not @error Then $aDiskInfo[1] = $match[0] ; Disk ID ContinueLoop EndIf EndIf EndIf ElseIf StringRegExp( $string, "[[:alnum:]]+" ) Then ; skip empty lines $aDiskInfo[0] = $string $bNameNext = False ;MsgBox(0, "", "Name is : " & $aDiskInfo[0]) EndIf EndIf Next ;_ArrayDisplay($aArray) EndIf ; Sanity checks If Not $aDiskInfo[0] Then $aDiskInfo[0] = "UNKNOWN DISK " & $iDisk EndIf If Not $aDiskInfo[1] Then $aDiskInfo[1] = "UNKNOWN" EndIf If Not $aDiskInfo[2] Then $aDiskInfo[2] = "UNKNOWN" EndIf If Not $aDiskInfo[3] Then $aDiskInfo[3] = "UNKNOWN" EndIf If Not $aDiskInfo[4] Then $aDiskInfo[4] = "UNKNOWN" EndIf Return $aDiskInfo EndFunc ; Returns a 2D array with info on all disks. Func DPGetAllDiskInfo() Local $aAllInfo, $iPID, $sOutput, $aArray, $match, $aDiskInfo, $aDiskInfo2, $size, $i $iPID = Run(@ComSpec & ' /c echo list disk | diskpart',"", @SW_HIDE, $STDOUT_CHILD) ProcessWaitClose($iPID) $sOutput = StdoutRead($iPID) ; Use StringSplit to split the output of StdoutRead to an array. All carriage returns (@CRLF) are stripped and @CRLF (line feed) is used as the delimiter. $aArray = StringSplit(StringTrimRight(StringStripCR($sOutput), StringLen(@CRLF)), @CRLF) If @error Then MsgBox($MB_SYSTEMMODAL, "", "It appears there was an error trying to run diskpart.") Else For $string In $aArray $match = StringRegExp($string, "^\s+Disk ([0-9]+) .+", 1) If Not @error Then $aDiskInfo = DPParseDiskDetail( $match[0], $string ) $aDiskInfo2 = DPParseListDisk( $string ) _ArrayConcatenate( $aDiskInfo, $aDiskInfo2 ) ; Need to do some weird stuff here because of 2D arrays If UBound($aAllInfo) == 0 Then Dim $aAllInfo[1][$iSizeOfAllDiskInfo] $size = 0 Else $size = UBound($aAllInfo, 1) ReDim $aAllInfo[$size + 1][$iSizeOfAllDiskInfo] EndIf For $i = 0 To (UBound($aDiskInfo)-1) $aAllInfo[$size][$i] = $aDiskInfo[$i] Next EndIf Next EndIf Return $aAllInfo EndFunc Func DPRepartition( $iDisk ) ; DEBUG DEBUG DEBUG DEBUG!!! MsgBox(0, "DEBUG", "All ur data r belong 2 uz") EndFunc Func IsUEFIPEBooted() Local $val = RegRead("HKLM\System\CurrentControlSet\Control", "PEFirmwareType") If Not @error Then If $val == 0x2 Then Return True ElseIf $val == 0x1 Then Return False EndIf EndIf Return Null EndFunc Func Init() Local $i Local $sComboItems = "-- Select Disk --" $bIsUEFIBooted = IsUEFIPEBooted() GUICreate($sProgName, $iWindowWidth, $iWindowHeight) If $bIsUEFIBooted Then GUICtrlCreateLabel("* UEFI Detected ", $iWindowWidth - 120, 5, 120, 20, $SS_RIGHT) Else GUICtrlCreateLabel("* MBR Detected ", $iWindowWidth - 120, 5, 120, 20, $SS_RIGHT) EndIf GUICtrlCreateLabel($sProgName, 5, 5) Opt("GUICoordMode", 2) ; Switch to relative positioning GUICtrlCreateLabel("Select Disk For Partitioning", -1, 20, $iWindowWidth - 10) $iComboBox1 = GUICtrlCreateCombo("", -1, 2, $iWindowWidth - 10) $aAllDiskInfo = DPGetAllDiskInfo() For $i = 0 To (UBound($aAllDiskInfo,1)-1) $sComboItems = $sComboItems & '|' & "Disk " & $i & ": " & $aAllDiskInfo[$i][0] & " (" & $aAllDiskInfo[$i][5] & ")" Next GUICtrlSetData(-1, $sComboItems, "-- Select Disk --") $iSysCheckBox = GUICtrlCreateCheckBox("Add System Partition", -1, 2) GUICtrlSetState(-1, $GUI_CHECKED) $iWinRECheckBox = GUICtrlCreateCheckBox("Copy over WinRE", -1, 2) GUICtrlSetState(-1, $GUI_CHECKED) $iRecoveryCheckBox = GUICtrlCreateCheckBox("Add Recovery Partition", -1, 2) GUICtrlSetState(-1, $GUI_CHECKED) $iGPTCheckBox = GUICtrlCreateCheckBox("Use GPT", -1, 2) GUICtrlSetState(-1, $GUI_UNCHECKED) Opt("GUICoordMode", 1) ; Default (absolute) $iGoButton = GUICtrlCreateButton("Go!", 10, $iWindowHeight - 40, 80) EndFunc Func Cleanup() FileDelete( $tempfile ) EndFunc Func Go() Local $iOKORCANCEL, $match, $iDisk $match = StringRegExp( GUICtrlRead( $iComboBox1 ), "^Disk ([0-9]+):", 1 ) If Not @error Then $iDisk = $match[0] $iOKORCANCEL = MsgBox($MB_OKCANCEL, "Does this look right?", _ "Repartition drive " & $iDisk & "?" & @CRLF & _ @CRLF & _ $aAllDiskInfo[$iDisk][0] & @CRLF & _ "ID: " & $aAllDiskInfo[$iDisk][1] & @CRLF & _ "Type: " & $aAllDiskInfo[$iDisk][2] & @CRLF & _ "Location: " & $aAllDiskInfo[$iDisk][4] & @CRLF & _ @CRLF & _ "Unallocated Space: " & $aAllDiskInfo[$iDisk][6] & @CRLF & _ "Total Size: " & $aAllDiskInfo[$iDisk][5] & @CRLF & _ @CRLF & _ "Status: " & $aAllDiskInfo[$iDisk][3] & @CRLF ) If $iOKORCANCEL == $IDOK Then $iOKORCANCEL = MsgBox($MB_OKCANCEL, "WARNING!", _ "ALL DATA ON DRIVE " & $iDisk & " WILL BE LOST!" & @CRLF & _ @CRLF & _ "Continue?" ) If $iOKORCANCEL == $IDOK Then DPRepartition($iDisk) EndIf EndIf Else MsgBox(0, "", "Please select a disk!") EndIf EndFunc Func main() Local $state Init() ; GUI MESSAGE LOOP GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Cleanup() Exit Case $iGoButton Go() Case $iGPTCheckBox ;$state = GUICtrlRead( $iGPTCheckBox ) ;If $state == $GUI_CHECKED Then ;GUICtrlSetState( $iSysCheckBox, $GUI_CHECKED) ; _GUICtrlButton_SetState( $iSysCheckBox, $BST_INDETERMINATE ) ;Else ; _GUICtrlButton_SetState( $iSysCheckBox, $BST_CHECKED ) ;EndIf Case $iSysCheckBox $state = GUICtrlRead( $iSysCheckBox ) If $state == $GUI_CHECKED Then GUICtrlSetState( $iWinRECheckBox, $GUI_SHOW) Else GUICtrlSetState( $iWinRECheckBox, $GUI_HIDE) EndIf EndSwitch WEnd EndFunc It's not totally absent of commenting and will at least show you the drives and volumes. It's a start that I hope to use to fully GUI-ify your script or at least complement WinNTSetup (which doesn't do partitioning or recovery creation). We can even have it call batch files for some processing, if you don't want to work with AutoIT. In fact, I'd rather modularize at least dealing with diskpart into a shared script, so it's easily updated and used in other projects.
Has anyone had success getting this to work with a PC or laptop that has a hybrid hard drive? It throws an error when copying the bcdboot files.
Hey sir ! I see to use SCANSTATE for Windows : http://forums.mydigitallife.net/thr...ATOR/page292?p=1098759&viewfull=1#post1098759
What options would you suggest for a Windows Enterprise based WTG Windows to Go 8.x or 10? Especially if done on a .VHD/ .VHDX?
Windows to go images are created from within Windows. I'm not entirely sure how exactly they form the images. If you want Enterprise to be installed as intended, you should use a stock Enterprise image as a source. I haven't played with .vhd booting, but as far as the size goes, it really doesn't matter unless you're using a recovery image. Normal setup will make the vhd roughly the same size as dism apply does.
Tested with Windows 10 Enterprise French and work perfectly ! But I see two errors : I use fast setup, after partition no index available, but I tape "1" and the index ready At the end, the script rebuild and error in 42% "the system already exists" Thanks for your work