|
|
在此分享,有高手的話,請把它改得安全點。這script我曾被它格式化了硬盤。
再說一次,此script 有一定的危險性,風險及損失自負。
系統要安裝了支援SDI的配置。
安裝了 sdiloader.exe
reg 了sdiaut.dll
有 robocopy.exe (windows resource kit)
在script 內指定, pebuilder 的輸出目錄, 這裡的文件將會抄進SDI
指定 sdi 文件名稱及存放路徑。
指定 sdi driver letter (造成cd 後,掛接的盤號。)
* sdi 文件大小是依 pebuilder 輸出目錄 的大小,不需指定,因會將其格式為 NTFS compress ,所以造好後有剩餘空間,留細高手改良吧。
* robocopy 設了長的重試時間,以提高成功機會,大家因個人情況,愛改便改。
* unmount 前停留了一段時間,因有時在執行 defrage 後,立即unmount會失敗,這也留細高手改良吧。
運行 CScript Make_WINPE_SDI.vbs 。
如一個400mb 的 文件,約需15分鐘。
執行後 make_winpe_sdi_log.txt 是運行記錄。
_Robocopy.log 是 robocopy 運行記錄。
format_sdi.txt 是 運行 diskpart 時的信息。
active_sdi.txt 也是 運行 diskpart 時的信息。
**** 當然你要造成 iso 啟動 ,還要連同 w2k3 的數個文件放好才用 mkisofs 生成。
***********************************************************************
'* modify from Jacob Hodges's MakeSDI.vbs
'* run CScript Make_WINPE_SDI.vbs
'* THIS SCRIPT KILL MY HARD DISK TWICE. USE IT AS YOUR OWN RISK
'* IT'S BETTER RUN IT UNDER VPC / VMWARE AND BACKUP YOUR VIRTUAL HARD DISK
'***********************************************************************
Option Explicit
Const sImage = "D:\PEBuilder3110a\RamPE\WINPE.SDI"
Const sSourceFolder="D:\pebuilder3110a\BartPE\"
Const sSDI_Driver_Letter="X"
Dim sSize, iThisSDIIndex, sPnpDeviceID, sSignature, slogFile
slogFile = "./" & Split(WScript.ScriptName, ".")(0) & "_log.txt"
' ONLY above Const need to change
Const blnOverwrite=true 'Stores true|false to overwrite a previous image
sSize = 320 : iThisSDIIndex = -1
Dim fs : Set fs = CreateObject("Scripting.FileSystemObject")
If fs.FileExists(slogFile) Then
fs.DeleteFile slogFile, True
End If
'Make sure we are using CSCRIPT
If LCase(fs.GetBaseName(WScript.FullName)) <> "cscript" Then
WriteError "Please use CSCRITP to execute this script."
End If
' Check engine version (V5.5 Or later)
If (ScriptEngineMajorVersion < 5) Or ((ScriptEngineMajorVersion = 5) And (ScriptEngineMinorVersion < 5)) Then
WriteError "This script requires VBScript V5.5 or later. See http://msdn.microsoft.com/scripting to upgrade."
End If
'***********************************************************************
'***********************************************************************
'Constants
'***********************************************************************
Const SDICREATENEW = 1
Dim DISK : DISK = CLng(1263749444) 'For Creating a new disk blob in the SDI Image
'***********************************************************************
'Global Variables
'***********************************************************************
'fs is set globally above
Dim argsNamed 'Name Arguments
Dim oSDIFile 'The New SDI File
'***********************************************************************
'Script Setup
'***********************************************************************
Dim oSDI : Set oSDI = CreateObject("SDIAUT.SDI")
Dim Folder
If FS.FolderExists(sSourceFolder) Then
Set Folder = FS.GetFolder(sSourceFolder)
If not Folder.Size=0 Then
sSize = Folder.Size\1024\1024
Else
WriteError "Source Folder is null [" & sSourceFolder & "]"
End If
Else
WriteError "Source Folder not exist [" & sSourceFolder & "]"
End If
'***********************************************************************
'Main
'***********************************************************************
'Check that the file exists, if so remove it
If fs.FileExists(sImage) Then
writeLog "SDI File Already Exists."
If LCase(blnOverwrite) = "true" Then
writeLog "Deleting " & sImage
fs.DeleteFile sImage, True
Else
WriteError "File already exists, set /overwrite:true if you wish to overwrite the file"
End If
End If
On Error Resume Next
'Create the new SDI file
Set oSDIFile = oSDI.CreateImage(sImage, SDICREATENEW)
writeLog "Source Folder: " & sSourceFolder
writeLog "New SDI File Path: " & oSDIFile.FilePath
'Creating DISK BLOB in SDI Image
writeLog "Creating DISK.... " & sSize & " MB"
CreateDisk sSize
If Err.number <> 0 Then
WriteError "An Error Occured: " & Err.Description
End If
On Error Goto 0
Set oSDI=nothing : Set oSDIFile = nothing
' Mount the SDI just create
MountWinpeSdi
DiskPartSDI
'All Done
WScript.Quit 0
'***********************************************************************
'Helper methods
'***********************************************************************
Sub WriteError(sMsg)
WScript.Echo sMsg
writeLog sMsg
WScript.Quit 0
End Sub
Sub CreateDisk(sSize)
Dim nSize 'size in MB
Dim sHex 'size as Hex
Dim nLo 'Low DWORD
Dim nHi 'High DWORD
Dim oBlob 'DISK Blob
'Get the size in MB
' nSize = GetSizeInMB(sSize)
nSize = sSize
'Convert to hex
sHex = Right("00000000" & Hex(nSize), 8)
'Form the Low DWORD
nLo = CLng("&h" & Right(sHex, 3) & "00000")
nHi = CLng("&h" & Left(sHex, 5))
'Create a DISK Blog
oSDIFile.Blobs.Allocate DISK, nLo, nHi
Set oBlob = FindBlob(oSDIFile)
oBlob.Attribute = 0
End Sub
Function GetSizeInMB(sData)
Dim sTemp : sTemp = Trim(sData)
Dim lTemp : lTemp = CLng(sTemp)
GetSizeInMB = lTemp \ 1048576
End Function
Function FindBlob(oSDIFile)
Dim oBlob
Set FindBlob = Nothing
For Each oBlob In oSDIFile.Blobs
If oBlob.Type = DISK Then Set FindBlob = oBlob : Exit Function
Next
End Function
' ********************************************************
' Mount SDI
' ********************************************************
Function MountWinpeSdi()
Dim sTempImage, oFile, index
Dim oSDIMount : Set oSDIMount = CreateObject("SDIAUT.SDIMountedDisks")
sTempImage = sImage
If Not fs.FileExists(sTempImage) Then
writeLog "Could not find file: " & sTempImage
WScript.Quit 0
Else
Set oFile = fs.GetFile(sTempImage)
sTempImage = oFile.Path
End If
index = FindImageIndex( oSDIMount, sTempImage)
If index = -1 Then
writeLog "Mounting " & sTempImage & "..."
oSDIMount.Add sTempImage
' get the last disk pnpid, assume it's the last SDI disk
' query Win32_DiskDrive return index include any Drive,
' oSDIMount.count only count SDI disk.
' Diskpart use disk id that include any Drive
' hd1(1)=index 0, hd2(D:)=1, sdi_a=2 (sdi count 0), sdi_b=3 (sdi count 1).
' use 1 (sdi count) for diskpart will KILL hd 2.!!!
Dim objWMIService, colItems, objItem
Set objWMIService = GetObject("winmgmts:\\" & "." & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_DiskDrive where caption = 'SDIDisk'",,48)
' criteria = 'caption=sdDisk' is OK. it's the Drive ID include Hard disk ....
For Each objItem In colItems
sPnpDeviceID= objItem.pnpdeviceid
writeLog "Current SDIDisk PnpDeviceID :" & sPnpDeviceID
iThisSDIIndex = objItem.Index
Next
Set objWMIService = nothing : Set colItems = nothing
Rem iThisSDIIndex = oSDIMount.count ' this kill Harddisk if d: eixst and only 1 SDI mount!
Else
writeLog "File already mounted."
WScript.Quit 0
End If
writeLog "Current SDI mounted as index (" & iThisSDIIndex & " )"
writeLog "Current SDI PnpDeviceID ( " & sPnpDeviceID & " )"
writeLog ""
Set oSDIMount = nothing
End Function
Function FindImageIndex(oSDIMount, sName)
Dim i, sTemp, oTempSDI
FindImageIndex = -1
If oSDIMount.Count < 1 Then Exit Function
For i = 1 To oSDIMount.Count
writeLog " index : " & i & " = " & oSDIMount.Item(i).ImagePath
If InStr(1, oSDIMount.Item(i).ImagePath, sName, 1) <> 0 Then
FindImageIndex = i
Exit Function
End If
Next
End Function
Sub DiskPartSDI()
Dim objOutputFile, strOutputFile, strPath, temp, oShell, Folder
Dim lSSize, lTSize
Dim objWMIService, colItems, objItem
Set objWMIService = GetObject("winmgmts:\\" & "." & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_DiskDrive where caption = 'SDIDisk'",,48)
' criteria = 'caption=sdDisk' is OK. it's the Drive ID include Hard disk ....
iThisSDIIndex = -1
For Each objItem In colItems
writeLog "DiskPart :: List all SDIDisk PnpDeviceID :" & objItem.pnpdeviceid
If sPnpDeviceID = objItem.pnpdeviceid Then
iThisSDIIndex = objItem.Index
writeLog "Target SDI disk " & objItem.pnpdeviceid & " index is ( " & iThisSDIIndex & " )"
End If
Next
Set objWMIService = nothing : Set colItems = nothing
If iThisSDIIndex = -1 Then
writeLog "Can not found Target SDI disk."
writeLog "Plese do it yourself (DiskPart, format, robocopy, defrag, unmount yourself) ...."
WScript.Quit 0
End If
Set objWMIService = nothing : Set colItems = nothing
strPath = Left(WScript.ScriptFullName, InstrRev(WScript.ScriptFullName, "\"))
strOutputFile = strPath & "format_sdi.txt"
writeLog "Create " & strOutputFile
Set objOutputFile = FS.CreateTextFile(strOutputFile, TRUE)
objOutputFile.WriteLine("SELECT DISK " & iThisSDIIndex)
objOutputFile.WriteLine("CLEAN")
objOutputFile.WriteLine("CREATE PARTITION PRIMARY")
objOutputFile.WriteLine("ASSIGN LETTER=" & sSDI_Driver_Letter)
objOutputFile.Close
Set oShell = WScript.CreateObject( "WScript.Shell" )
writeLog "running diskpart.exe, PLEASE WAIT....."
oShell.Run "diskpart.exe /s " & strOutputFile,,true ''wait until finish
Rem oShell.Run "%COMSPEC% /k ipconfig"
writeLog "Formating SDI, PLEASE WAIT....."
oShell.Run "Format.com " & sSDI_Driver_Letter & ": /fs:ntfs /Q /C /Y /V:WINPE" ,,true ''wait until finish
writeLog "active " & sSDI_Driver_Letter & ": "
strOutputFile = strPath & "active_sdi.txt"
' Select correct disk to active !
Set objWMIService = GetObject("winmgmts:\\" & "." & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_DiskDrive where caption = 'SDIDisk'",,48)
' criteria = 'caption=sdDisk' is OK. it's the Drive ID include Hard disk ....
iThisSDIIndex = -1
For Each objItem In colItems
writeLog "DiskPart :: List all SDIDisk PnpDeviceID :" & objItem.pnpdeviceid
If sPnpDeviceID = objItem.pnpdeviceid Then
iThisSDIIndex = objItem.Index
writeLog "Target SDI disk " & objItem.pnpdeviceid & " index is ( " & iThisSDIIndex & " )"
End If
Next
Set objOutputFile = FS.CreateTextFile(strOutputFile, TRUE)
objOutputFile.WriteLine("SELECT DISK " & iThisSDIIndex)
objOutputFile.WriteLine("active")
objOutputFile.Close
oShell.Run "diskpart.exe /s " & strOutputFile,,true ''wait until finish
writeLog "Robocopy, PLEASE WAIT ......"
oShell.Run "robocopy.exe " & sSourceFolder & " " & sSDI_Driver_Letter & ": /E /ZB /COPY:DAT /R:3 /W:12 /REG /LOG:""" & Left(WScript.ScriptFullName, InstrRev(WScript.ScriptFullName, "\")) & "_Robocopy.log""" ,,true
writeLog "Defrag, PLEASE WAIT ......"
oShell.Run "defrag.exe -v -f " ,,true
' unmount SDI
Dim sTempImage, oFile, index
Dim oSDIMount : Set oSDIMount = CreateObject("SDIAUT.SDIMountedDisks")
sTempImage = sImage
index = FindImageIndex( oSDIMount, sTempImage)
If index = -1 Then
writeLog sTempImage & sTempImage & " doesn't seem to be mounted"
Else
'For some reason Item indexes at 1 and remove indexes at 0, wtf? Add -1 to fix
writeLog "wait 20 secs to unMount SDI " & index
writeLog "If you dont see ""unMount SDI successfully"" message "
writeLog "Please do it yourself"
WScript.Sleep CInt(20)*1000
oSDIMount.Remove index-1 ' MUST -1, first SDI = 0 (index = 1) ...
writeLog "unMount SDI successfully"
End If
Set oSDIMount = nothing
End Sub
Sub writeLog(x)
Dim objFileSystem, objOutputFile
Const OPEN_FILE_FOR_APPENDING = 8
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
If fs.FileExists(slogFile) Then
Set objOutputFile = objFileSystem.OpenTextFile(slogFile, OPEN_FILE_FOR_APPENDING)
Else
Set objOutputFile = objFileSystem.CreateTextFile(slogFile, TRUE)
End If
objOutputFile.WriteLine(DatePart("h", Now) & ":" & DatePart("n", Now) & ":" & DatePart("s", Now) & " :: " & x)
objOutputFile.Close
Set objFileSystem = Nothing
WScript.Echo x
End Sub |
|