📄 slipstream.vbs
字号:
' slipstream.vbs
' (c) 2004 Jesper M. Johansson, All Rights Reserved. Supplied As Is. No Warranties Expressed or Implied
' This script aids in creating slipstreamed OS installations
'
' There are several tasks that need to be performed. The first is copy the files and apply the
' latest service pack. Then we need to apply the patches. This script assumes that you have
' downloaded all the patches and that they are in the same directory. The names are not important
' Once that has been done, run the script and it will:
' 1. Ask you to type in the path to the patches.
' 2. Extract all the patches by running them with the /x switch. This does not work on all patches, e.g.
' for example Windows Media patches. However, you can't really slipstream those anyway, so if you
' get an error message about extraction, it is probably for a patch that can't be slipstreamed.
' 3. Ask you to type in the path to the slipstreamed installation directory
' 4. Copies the .cat files and the original patch files into the installation directory
' 5. Replaces the affected binaries in the installation directory
' 6. Prepares a new svcpack.inf file
' 7. Prepares the modifications to the dosnet.inf file
'TODO: Try IE patches with /r:n
Option Explicit 'We like errors. Errors are good.
'This is easier than having the define this variable everywhere in the script where I am using it.
dim continue
continue = 6
' we are using the fso object everywhere, so let's make it a global
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
main() 'Just call main and that's it. It's the shortest program I have ever written :-)
function main 'You can at least attempt to write good code in VBS
Dim Help
Help = "Slipstream - (c) 2004, Jesper M. Johansson, All Rights Reserved. Supplied As Is. No Warranties Expressed or Implied" & vbCrLf & vbCrLf &_
"This tool will help create slipstreamed installation disks." & vbCrLf &_
"Before using the tool copy the source files from CD to a folder and apply the " & vbCrLf &_
"latest service pack using the /s switch. Then download all the patches and put them into " &_
"a single directory. " & VbCrLf &_
"DO NOT RENAME THE PATCHES WHILE DOWNLOADING as the script will parse the patch names" & vbCrLf &_
"Then run the script and it will copy the files into the necessary locations and " & vbCrLf &_
"prepare your slipstreamed installation. " & vbCrLf & vbCrLf &_
"This script has been tested with the Windows 2000 Family, Windows XP, and Windows Server 2003. " & vbCrLf &_
"Please note that this script is for x86 platforms only. It would need to be modified to create " & vbCrLf &_
"slipstreamed ia64 and AMD64 installation points. Also note that this script has no undo function. " & vbCrLf &_
"Should something go wrong during the slipstreaming process, it is likely that the installation point is unusable. " & vbCrLf & vbCrLf &_
"Shall we continue?"
continue = 6
continue=MsgBox(Help,vbYesNo,"Slipstream")
if continue = 7 then
exit function
end if
Dim strPatchPath, strInstallPath, strTargetOS, strTargetSP
'DEBUG uncomment these in production code
strPatchPath = InputBox("Please type the path to where the patches are","Patch Path")
strInstallPath = InputBox("Please type the path to the i386 directory where the installation files are","Source Path")
strTargetOS = InputBox("Please enter the target OS you are trying to slip stream into. Use ""Win2000"" for Windows 2000" &_
" ""WinXP"" for Windows XP, and ""Win2003"" for Windows Server 2003. No other operating systems" &_
" are supported at this time.","Target OS")
strTargetSP = InputBox("Many patches for Windows XP and Server 2003 come with patch files for different service packs (SP) " &_
"(see KB328848 and KB824994 for details). When slipstreaming these patches, it is important to " &_
"know which SP you have slipstreamed into your install point. Please enter the SP here. Enter " &_
"""RTM"" for the original release (no service pack), ""SP1"" for Service Pack 1, and so on. " &_
"Do not enter any quotes.","Target SP")
'DEBUG
' strInstallPath = "C:\Downloads\slipstreaming\Windows 2000\W2SFPP_EN\i386"
' strPatchPath = "C:\Downloads\slipstreaming\Windows 2000\Patches"
' strTargetOS = "Win2000"
' strTargetSP = "SP4"
'DEBUG
'Make sure the OS makes sense
if(strTargetOS <> "Win2000") then
if(strTargetOS <> "WinXP") then
if(strTargetOS <> "Win2003") then
MsgBox "Illegal target operating system. Exiting",VbOKOnly,"ERROR"
exit function
end if
end if
end if
'Make sure the SP makes sense
if( len(strTargetSP) = 3) then
if(strTargetSP <> "RTM") then
if( StrComp(left(strTargetSP,2),"SP",vbTextCompare) <> 0 OR IsNumeric(right(strTargetSP,1)) = false) then
MsgBox "Illegal target service pack. Exiting",VbOKOnly,"ERROR"
exit function
end if 'Does not look like a service pack at all
end if 'not RTM
else
MsgBox "Illegal target service pack. Service pack designations are exactly three characters. Exiting",VbOKOnly,"ERROR"
end if
Dim bPatchesRemaining 'True if there are patches remaining after we are done installing
bPatchesRemaining = false
Dim aPatchList() ' An two-dimensional array holding the patch list
' The first row holds the full path to the patch
' The second row the name of the sub-directory where the patch is extracted
' The third row whether the patch was slipstreamable or not
' The fourth row has the syntax where 0 is the standard /q /n /z
' and 1 is the modified /q syntax. In that case, we will not include the
' path in the SetupHotfixesToRun section of svcpack.inf.
' The fifth row has the q-number for the patch
' In other words, the array looks like this
' Patch1 Patch2
' _________________
' fullpath | 0,i | 0,i+1 |
' extractdir | 1,i | 1,i+1 |
' slipstream y/n | 2,i | 2,i+1 |
' syntax | 3,i | 3,i+1 |
' qNumber | 4,i | 4,i+1 |
'
' This may be a bit counterintuitive, but in VBScript, we can only grow the
' last dimension of an array, so it is necessary to do it this way.
Dim bRetVal
bRetVal = extractPatches(strPatchPath,aPatchList)
if(bRetVal) then
bRetVal = movePatches(strInstallPath, strPatchPath, aPatchList, strTargetOS, strTargetSP)
if(bRetVal) then
' TODO: Print here a list of the patches that did not work
else
MsgBox "Unable to copy the patch files into the appropriate locations. Something is very wrong " &_
"and it is very likely that your install point has become corrupted.",vbExclamation,"ERROR"
exit function
end if
else
MsgBox "Unable to extract patches",vbExclamation,"ERROR"
exit function
end if
MsgBox "Done!" & vbCrLf & "Now you need to extract the boot sector from a CD and burn a CD. " &_
"This script cannot do that for you, but if you refer to Chapter 3 in ""Protecting Your Network"" " &_
"You will find complete instructions there on how to proceed.", vbOK,"Finished"
end function 'End main
' This function completes steps 4 and 5 - moving the cat files, the
' original patch files, and the patch binaries into the proper places
' It is also the function that discovers whether a patch can be slipstreamed or not
' setting the flag if it is not. In order for a patch to be slipstreamable
' we need to have a update\*.cat file as well as a few binaries.
' Some patces have the .cat file in the root of the patch directory
' That's fine as long as it is not called empty.cat.
' When the function returns, the aSvcPackInf and aDOSNetInf arrays contain the
' values to write into those files.
'Parameters:
' strInstallPath - Full path to the i386 directory that holds the original OS installation
' strPatchPath - Full path to the directory that holds all the extracted patchs. Each patch is a subdir of this one.
' aPatchList - The array declared above that holds the details for each patch
' strTargetOS - A string that holds the target OS
' strTargetSP - A string that holds the target SP
function movePatches(strInstallPath, strPatchPath, aPatchList, strTargetOS, strTargetSP)
Dim iNumPatches
iNumPatches = UBound(aPatchList, 2)
'Step 1: create an svcpack directory
if(fso.FolderExists(strInstallPath)) then
Dim fldrI386Dir
Set fldrI386Dir = fso.GetFolder(strInstallPath)
else
MsgBox "The source path to the installation files is invalid",vbExclamation,"ERROR"
exit function
end if
if(fso.FolderExists(strInstallPath & "\svcpack") = false) then
fso.CreateFolder(strInstallPath & "\svcpack")
end if
Dim i
For i=0 to iNumPatches ' Loop through all the patches
if(aPatchList(2,i)) then 'If this patch can be slipstreamed
'Step 2: parse the hotfix name and copy it into the svcpack directory
'Hotfix names have either a KBnnnnnn or Qnnnnnn in them. We need the nnnnnn part
'We have an absolute path name. The interesting part is after the last slash, so cut that
Dim strPatchName
strPatchName = right(aPatchList(0,i),len(aPatchList(0,i))-InStrRev(aPatchList(0,i),"\"))
'Now find a Q followed by six digits
Dim iQNumber, iQNumberStart, bContinueProcessing
bContinueProcessing = true
iQNumberStart = 1
while(bContinueProcessing)
Dim iStartPos
iStartPos = iQNumberStart
iQNumberStart = InStr(iStartPos,strPatchName,"q", vbTextCompare)
if(iQNumberStart = NULL) then
'Something has gone terribly wrong
MsgBox "Unable to parse patch names. Patch name " & i & " is null",vbCritical,"ERROR"
movePatches = false
exit function
end if
if(iQNumberStart = 0) then 'The q number may be prefixed by kb instead
iQNumberStart = InStr(iStartPos, strPatchName,"kb", vbTextCompare)
if(iQNumberStart = 0) then 'This one doesn't have a q number. bail
bContinueProcessing = false
else
'This may be a patch with a KB number instead
iQNumber = Mid(strPatchName,iQNumberStart+2,6)
end if
else
'We have something we think is a q number. Now we need to tell whether
'this really is it. If it is, the next 6 characters are numeric
iQNumber = Mid(strPatchName,iQNumberStart+1,6)
end if
if(iQNumberStart > 0 AND isNumeric(iQNumber)) then
bContinueProcessing = false
end if
wend
if(iQNumberStart = 0) then
'We don't have a iQNumber.
aPatchList(4,i) = "" 'We don't have a q number yet.
' Let's try this patch anyway. Note that this means the patch many not show up in
' add remove programs.
MsgBox "Patch " & strPatchName & " does not have a KnowledgeBase article number. I will try to " & vbCrLf &_
"slipstream it anyway, but it may not show up in Add/Remove Programs."
'aPatchList(2,i) = false
'MsgBox "The Patch" & vbCrLf & aPatchList(0,i) & vbCrLf &_
' "has no q number and cannot be slipstreamed. You must manually install it once you have " &_
' "finished building out the system.",vbOK,"Unable to slipstream"
else 'if(iQNumberStart = 0) then
'Store the q number
aPatchList(4,i) = iQNumber
end if 'if(iQNumberStart = 0) then
'Step 3: copy the .cat file and the original patch into the svcpack directory.
'First, find the .cat file. It should be in the update directory, but it may
'be in the patch directory itself.
Dim strPatchDir 'The patch directory holds the patch itself
Dim strPatchUpdateDir 'The strPatchUpdateDir holds the catalog file
if(findPatchDirs(aPatchList,i,strPatchDir,strPatchUpdateDir, strTargetOS, strTargetSP) = false) then
'We are in deep something. This can't happen
MsgBox "Extremely fatal error locating the patch directories",vbCritical,"FATAL ERROR"
movePatches = false
exit function
end if
' We have an update directory. Is there a .cat file there?
Dim fldrUpdateFolder, fileUpateFiles, strCatalog, file
Dim bFoundACatalog, bFoundLegalCatalog, bFoundAnyLegalCatalog
bFoundLegalCatalog = false 'This is true if we find a legal catalog on this iteration
bFoundAnyLegalCatalog = false 'This is true if we find any legal catalog at all
bFoundACatalog = false 'This is true if we find any catalog at all.
strCatalog = ""
Set fldrUpdateFolder = fso.GetFolder(strPatchUpdateDir)
Set fileUpateFiles = fldrUpdateFolder.Files
for each file in fileUpateFiles
strCatalog = "" 'empty the catalog string
if(StrComp(right(file.name,4),".cat",vbTextCompare) = 0 AND StrComp(file.name,"empty.cat",vbTextCompare) <> 0) then
bFoundACatalog = true
'We may have found it. The problem is that some patches have multiple catalogs
'Catalogs for Windows patches are called either KB<iQNumber>.cat or Q<iQNumber.cat>
'Ensure that it is one of those we have
if(StrComp(file.Name,"KB" & aPatchList(4,i) & ".cat",vbTextCompare) = 0) then
strCatalog = file.name 'This one is legit
bFoundLegalCatalog = true
bFoundAnyLegalCatalog = true
else
if(StrComp(file.Name,"Q" & aPatchList(4,i) & ".cat",vbTextCompare) = 0) then
strCatalog = file.Name 'This one is fine too
bFoundLegalCatalog = true
bFoundAnyLegalCatalog = true
end if
end if 'Uses the KB number
end if 'if(right(file.name,4) = ".cat") then
if(bFoundLegalCatalog = true) then
'Now copy the catalog
dim strSvcPackDir, strCatalogPath
strSvcPackDir = strInstallPath & "\svcpack\"
strCatalogPath = strPatchUpdateDir & "\" & strCatalog
fso.CopyFile strCatalogPath, strSvcPackDir 'Catalog
'Since we copied the catalog, we now need to reset the bool. Otherwise, we will try the copy
'again even though we did not find another catalog the next time through this loop
bFoundLegalCatalog = false
if(aPatchList(3,i) = 0) then 'if this is a normal update.exe patch
fso.CopyFile aPatchList(0,i), strSvcPackDir 'Original patch file
end if
'Update the svcpack.inf file
'We don't want to run anything if we have a non-update.exe patch
Dim strPatchExe
if(aPatchlist(3,i) = 0) then
strPatchExe = right(aPatchList(0,i),len(aPatchList(0,i)) - InStrRev(aPatchList(0,i),"\")) &_
" /q /z /n"
else
strPatchExe = ""
end if
if (writeSvcPackINF(strInstallPath,strCatalog,strPatchExe,strTargetOS) = false) then
continue = 6
continue=MsgBox("Error adding the catalog for patch " & aPatchlist(0,i) & " to the svcpack.inf file. " &_
"The file is copied into the right place, but you will need to " &_
"manually add it to the dosnet.inf file as per KB 828930. Continue?",vbYesNo,"ERROR")
if continue = 7 then
movePatches = false
exit function
end if
end if
end if 'if(bFoundLegalCatalog = true)
next 'for each file in fileUpateFiles
if(bFoundAnyLegalCatalog = false) then 'If we couldn't find a legal catalog
'It is possible that we found a catalog but that it was not a legit one. In that case
'we probably have a patch that includes multiple catalogs, one per language. We can't
'slipstream those safely, so we will bail on this one
if(bFoundACatalog = true) then
MsgBox "The Patch" & vbCrLf & vbCrLf & aPatchList(0,i) & vbCrLf & vbCrLf &_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -