Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # WinPE 4.0 toolset in PowerShell
- #
- # Original PowerShell functions from
- # <http://www.jbmurphy.com/2012/01/13/powershell-scripts-to-create-a-winpe-4-0-wimiso/>
- # <http://www.jbmurphy.com/2012/01/24/powershell-script-to-make-a-winpe-usb-drive/>
- #
- # Change the $workdir argument to the place you want to use as your working directory
- #
- # Note that you must be running PowerShell as an administrator for this to work!
- #
- # Note that you can dot-source this file like `. winpe40.ps1`. It will display the
- # error message about not invoking it correctly, but you'll be able to use my
- # aliases for dismexe and imagexexe and stuff, and my functions.
- # TODO: Should probably make dot sourcing suck less. It's really useful.
- Param (
- # [Parameter(Position=0,Mandatory=$true)]
- [string]$Action,
- [string]$xmlfile="D:\winbacore.xml"
- )
- # Param (
- # [Parameter(Position=0,Mandatory=$true)]
- # [string]$Action,
- # # [Parameter(Position=1,Mandatory=$true)]
- # [Parameter(Position=1)]
- # [ValidateSet('x86', 'amd64')]
- # [string]$OSArchitecture = "x86",
- # [Parameter(Position=2)]
- # [string]$WorkDir = "D:\pe40"
- # )
- $cmdname = $myinvocation.MyCommand
- # required for {get,set}-privilege
- write-host ("Importing pscx module, this will take a minute...")
- import-module pscx
- if (-not (test-path $xmlfile)) {
- write-error ("No such file '$xmlfile'")
- return $null
- }
- $config = [xml](get-content $xmlfile)
- $OSArchitecture = $config.winpe.configuration.architecture
- $distlang = $config.winpe.configuration.distlang
- $WorkDir = $config.winpe.configuration.workdir
- $logfile = "$workdir\winpe.log"
- $WimFile="$workdir\ISO\sources\boot.wim"
- $mountdir = "$workdir\mount"
- $winsrc = $config.winpe.source.path
- $srcmountdir = "$workdir\srcmount"
- $vmxfile = $config.winpe.vmware.vmxpath
- $wadkdir = "${env:ProgramFiles(x86)}\Windows Kits\8.0\Assessment and Deployment Kit"
- function Write-Log {
- # if you want to see logs to the console, just comment out the redirection
- write-output ($args) >>$logfile
- }
- # NOTE! If you want to log to the console instead of a file, don't edit this function - edit write-log, above.
- function Echoexec-Expression {
- Param($whatif)
- write-log ("#: " + $args.count + "`r`nargs: $args")
- $expression = ""
- foreach ($a in $args) {
- if ("$a".contains(" ")) {
- $expression += "`"$a`" "
- }
- else {
- $expression += "$a "
- }
- }
- if (-not ($whatif)) {
- invoke-expression "$expression"
- }
- }
- set-alias echoexec echoexec-expression
- # alias setup
- set-alias bcdbootexe "$wadkdir\Deployment Tools\$OSArchitecture\BCDBoot\bcdboot.exe"
- set-alias bcdeditexe "$wadkdir\Deployment Tools\$OSArchitecture\BCDBoot\bcdedit.exe"
- set-alias bootsectexe "$wadkdir\Deployment Tools\$OSArchitecture\BCDBoot\bootsect.exe"
- set-alias dismexe "$wadkdir\Deployment Tools\$OSArchitecture\DISM\dism.exe"
- set-alias imagexexe "$wadkdir\Deployment Tools\$OSArchitecture\DISM\imagex.exe"
- set-alias pkgmgrexe "$wadkdir\Deployment Tools\$OSArchitecture\DISM\pkgmgr.exe"
- set-alias wimservexe "$wadkdir\Deployment Tools\$OSArchitecture\DISM\wimserv.exe"
- set-alias wimmountadksetupexe "$wadkdir\Deployment Tools\$OSArchitecture\DISM\winmountadksetup$OSArchitecture.exe"
- set-alias oscdimgexe "$wadkdir\Deployment Tools\$OSArchitecture\Oscdimg\oscdimg.exe"
- set-alias imagecatexe "$wadkdir\Deployment Tools\WSIM\imagecat.exe"
- set-alias imgmgrexe "$wadkdir\Deployment Tools\WSIM\imgmgr.exe"
- set-alias helpindexerexe "$wadkdir\Deployment Tools\HelpIndexer\helpindexer.exe"
- function WinPE-MakePEDirectory {
- remove-item -recurse -force "$workdir"
- New-Item $workdir\ISO\sources -type directory -force
- New-Item $mountdir -type directory -force
- copy-item -recurse "${env:ProgramFiles(x86)}\Windows Kits\8.0\Assessment and Deployment Kit\Windows Preinstallation Environment\$OSArchitecture\en-us\winpe.wim" "$workdir\ISO\sources\boot.wim"
- copy-item -recurse "${env:ProgramFiles(x86)}\Windows Kits\8.0\Assessment and Deployment Kit\Windows Preinstallation Environment\$OSArchitecture\Media\*" "$workdir\ISO\"
- copy-item -recurse "${env:ProgramFiles(x86)}\Windows Kits\8.0\Assessment and Deployment Kit\Deployment Tools\$OSArchitecture\Oscdimg\etfsboot.com" "$workdir\"
- }
- function WinPE-Mount {
- dismexe /Mount-Wim /WimFile:$WimFile /index:1 /MountDir:$mountdir
- }
- function WinPE-AddPAckages {
- $OCsPATH="${env:ProgramFiles(x86)}\Windows Kits\8.0\Assessment and Deployment Kit\Windows Preinstallation Environment\$OSArchitecture\WinPE_OCs"
- foreach ($syspkg in $config.winpe.packages.system) {
- if ($syspkg) {
- $packagename = $syspkg.filename
- $packagepath = "$OCsPATH\$packagename"
- if (-not (test-path $packagepath)) {
- write-error ("Expected system package '$packagename' to be found at path '$packagepath', but there was no package found there")
- }
- else {
- Echoexec-Expression dismexe /image:$mountdir /add-package /packagepath:$packagepath
- }
- }
- }
- foreach ($userpkg in $config.winpe.packages.user) {
- if ($userpkg) { # not sure why but we get a null one every once in a while
- $packagepath = $userpkg.filepath
- if (-not (test-path $packagepath)) {
- write-error ("There was no user package at path '$packagepath'.")
- }
- else {
- Echoexec-Expression dismexe /image:$mountdir /add-package /packagepath:$packagepath
- }
- }
- }
- foreach ($include in $config.winpe.include) {
- if ($include) {
- $src = $include.source
- $dst = $mountdir + $include.destination
- if (-not (test-path $src)) {
- write-error ("Supposed to copy '$src' to $dst' but no such source.")
- }
- else {
- Echoexec-Expression mkdir -force $dst
- Echoexec-Expression copy-item -recurse -force $src $dst
- }
- }
- }
- }
- function WinPE-MountSource {
- mkdir -force $srcmountdir
- dismexe /Mount-Wim /WimFile:$winsrc\sources\install.wim /index:1 /MountDir:$srcmountdir
- }
- function WinPE-CancelmountSource {
- dismexe /unmount-Wim /MountDir:$srcmountdir /discard
- }
- set-alias WinPE-UnmountSource WinPE-CancelmountSource
- function WinPE-Cancelmount {
- dismexe /unmount-Wim /MountDir:$mountdir /discard
- }
- function WinPE-CommitUnMount {
- dismexe /unmount-Wim /MountDir:$mountdir /Commit
- }
- set-alias WinPE-Unmount WinPE-CommitUnMount
- function WinPE-MakeISO {
- & oscdimgexe -m -n "-b$workdir\etfsboot.com" $workdir\ISO $workdir\winpe_$OSArchitecture.iso
- }
- # this function doesn't work at all! fucking VPC doesn't do Windows 8 lolololol
- function WinPE-StartVPCVM {
- # this doesn't work if you're running x86 powershell on x64 windows fuck
- start-process "C:\Windows\System32\vmwindow.exe" "$config.winpe.virtualpc.vmcxpath"
- }
- function WinPE-StartVMwareVM {
- start-process "${env:programfiles(x86)}\VMware\VMWare Player\vmplayer.exe" `""${vmxfile}"`"
- }
- set-alias WinPE-StartVM WinPE-StartVMwareVM
- # Steal-FullControlPrivs
- #
- # - *must* use takeown.exe otherwise it won't work
- # - You need PSCX for {get,set}-privilege
- #
- # <http://blog.salamandersoft.co.uk/index.php/2009/10/setting-the-owner-of-files-and-directories-in-c/>
- # <http://stackoverflow.com/questions/488310/can-i-change-the-owner-of-the-file-saved-through-iis-with-asp-net)
- # <http://stackoverflow.com/questions/8216510/how-do-i-change-the-owner-of-a-folder-with-powershell-when-get-acl-returns-acce>
- $myprivs=get-privilege
- $myprivs.enable("SeTakeOwnershipPrivilege")
- $myprivs.enable("SeBackupPrivilege")
- $myprivs.enable("SeRestorePrivilege")
- set-privilege $myprivs
- $MyIdentity = [Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()
- $MyAccount = New-Object System.Security.Principal.NTAccount($myidentity.identity.name)
- function Steal-FullControlPrivs {
- param([parameter(Position=0, Mandatory=$true)] $path)
- # $path = "D:\winbacore2\mount\Program Files\Common Files\System\ado\msado15.dll"
- $oldacl = get-acl $path
- write-log ("oldacl: Owner: " + $oldacl.Owner + "`r`nAccess:")
- foreach ($r in $oldacl.Access) {
- write-log (" User: " + $r.IdentityReference.Value + " // " + $r.AccessControlType + " // Rights: " + $r.Filesystemrights)
- }
- echoexec-expression start-process -nonewwindow -wait -RedirectStandardOutput "$logfile" -filepath $env:windir\system32\takeown.exe -argumentlist @("/f","`"$path`"")
- $newacl = get-acl $path
- $ar = New-Object system.security.AccessControl.FileSystemAccessRule($MyAccount, "FullControl", "Allow")
- $newacl.addaccessrule($ar)
- echoexec-expression set-acl -path $path -aclobject $newacl
- $OldOwnerAccount = New-Object System.Security.Principal.NTAccount($oldacl.Owner)
- $newacl.setowner($OldOwnerAccount)
- #echoexec-expression set-acl -path $path -aclobject $newacl
- echoexec-expression set-acl -path $path -aclobject $newacl
- write-log ("Final ACL: Owner: " + $newacl.Owner + "`r`nAccess:")
- foreach ($r in $newacl.Access) {
- write-log (" User: " + $r.IdentityReference.Value + " // " + $r.AccessControlType + " // Rights: " + $r.Filesystemrights)
- }
- }
- function WinPE-AddExplorer {
- param([switch]$whatif)
- if (-not (test-path $srcmountdir\Windows\explorer.exe)) {
- write-error ("There does not appear to be a source image mounted at $srcmountdir. Failed.")
- return
- }
- if ($whatif) {
- $w = "-whatif"
- }
- else {
- $w = ""
- }
- # Make the directories
- $dirs = @("$mountdir\Users\Administrator","$mountdir\ProgramData\Microsoft","$mountdir\ProgramData\Microsoft\Windows",
- "$mountdir\ProgramData\Microsoft\Windows\DeviceMetadataStore","$mountdir\Windows\Branding\Basebrd\$distlang","$mountdir\Windows\Branding\Basebrd\en-US",
- "$mountdir\Windows\Branding\ShellBrd","$mountdir\Windows\en-US","$mountdir\Windows\system32\en-US",
- "$mountdir\Windows\AppPatch","$mountdir\Windows\$distlang","$mountdir\Windows\System32\$distlang",
- "$mountdir\Windows\IME\$distlang","$mountdir\Program Files\Common Files\Microsoft Shared\ink\$distlang","$mountdir\Windows\winsxs\Manifests",
- "$mountdir\Windows\system32\config\Systemprofile\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch","$mountdir\Windows\servicing","$mountdir\Windows\Resources",
- "$mountdir\Windows\web","$mountdir\Windows\system32\oobe","$mountdir\Program Files\Internet Explorer\")
- foreach ($d in $dirs) {
- echoexec-expression $w mkdir -force $d
- }
- $s32files = @("oobe","dwm.exe","hdwwiz.*","wow*","*cpl.dll","*cpl","des*","dhcp*.dll","dm*","ie*","msv*.dll",
- "net*.dll","ole*.dll","PnP*.dll","SystemProperties*","wmd*.dll","*.cpl.mui","des*.mui","dhcp*.dll.mui",
- "network*.dll.mui","net*.dll.mui","old*.dll.mui","AuxiliaryDisplayApi.dll","AuxiliaryDisplayClassInstaller.dll","avicap.dll","avicap32.dll",
- "pnp*.mui","systempropertie*.exe.mui","actxprxy.dll","adsldp.dll","advapi32.dll","apphelp.dll","atl.dll",
- "avifil32.dll","avifile.dll","avrt.dll","AxInstSv.dll","browseui.dll",
- "catsrv.dll","catsrvps.dll","catsrvut.dll","certEnroll.dll","clbcatq.dll","colbact.dll",
- "collab.cpl","comctl32.dll","comm.drv","comrepl.dll","comres.dll",
- "comsnap.dll","comsvcs.dll","comuid.dll","control.exe","corpol.dll","crtdll.dll",
- "cscapi.dll","cttune.exe","d3d9.dll","dbghelp.dll","dbgeng.dll",
- "dcomcnfg.exe","devmgr.dll","diskcopy.dll","display.dll","DisplaySwitch.exe","dllhost.exe",
- "dllhst3g.exe","dsound.dll","dwm.exe","dwmapi.dll","Dwmredir.dll",
- "efsadu.dll","es.dll","eventcreate.exe","eventvwr.exe","fwpuclnt.dll","hlink.dll",
- "ie4uinit.exe","ieui.dll","ieuinit.inf","imgutil.dll","inetcomm.dll",
- "inetcpl.cpl","intl.cpl","IoLogMsg.dll","IPHLPAPI.DLL","jscript.dll","jsproxy.dll",
- "locale.nls","lpk.dll","lpksetup.exe","lpksetupproxyserv.dll","main.cpl",
- "mfcsubs.dll","mmdevapi.dll","mmsys.cpl","MSACM32.dll","mscories.dll","msoert2.dll",
- "msfeeds.dll","mshtml.dll","msi.dll","mstime.dll","msoert2.dll",
- "msrating.dll","msxml3.dll","msxml3r.dll","msxml6.dll","msxml6r.dll","mtstocom.exe",
- "mtxdm.dll","mtxex.dll","mtxlegih.dll","ndfapi.dll","normaliz.dll",
- "nsi.dll","ntdll.dll","objsel.dll","occache.dll","osbaseln.dll","pdh.dll",
- "printui.dll","puiapi.dll","quartz.dll","query.dll","rcphttp.dll",
- "rstrtmgr.dll","secur32.dll","sens.dll","Shwebsvc.dll","shimgvw.dll","shlwapi.dll",
- "Shsvcs.dll","shunimpl.dll","SLC.dll","stclient.dll","swprv.dll",
- "sysdm.cpl","tdh.dll","themecpl.dll","themeui.dll","thumbcache.dll","timedate.cpl",
- "tracerpt.exe","TSTheme.exe","txflog.dll","UIAutomationCore.dll","urlmon.dll",
- "user.exe","user32.dll","uxsms.dll","uxtheme.dll","van.dll","vaultcli.dll",
- "vbscript.dll","verclsid.exe","WcsPlugInService.dll","wdi.dll","wecapi.dll",
- "wecsvc.dll","wecutil.exe","wermgr.exe","wevtsvc.dll","wevtutil.exe","WindowsCodecs.dll",
- "WindowsCodecsExt.dll","wininet.dll","wininet.dll","winnsi.dll","winrnr.dll",
- "ws2_32.dll","rshx32.dll","aclui.dll","ntshrui.dll","shpafact.dll","twext.dll")
- $distlangfiles = @("rshx32.dll.mui","aclui.dll.mui","ntshrui.dll.mui","shpafact.dll.mui","twext.dll.mui",
- "actxprxy.dll.mui","adsldp.dll.mui","advapi32.dll.mui","apphelp.dll.mui","appwiz.cpl.mui","atl.dll.mui",
- "avrt.dll.mui","browseui.dll.mui","cdosys.dll.mui","clbcatq.dll.mui","collab.cpl.mui",
- "comctl32.dll.mui","control.exe.mui","cscript.exe.mui","cscui.dll.mui","cttune.exe.mui","des*.mui",
- "diskcopy.dll.mui","dnsapi.dll.mui","duser.dll.mui","dwmapi.dll.mui","Dwmredir.dll.mui",
- "dxtmsft.dll.mui","dxtrans.dll.mui","Explorer.exe.mui","ExplorerFrame.dll.mui","gdi32.dll.mui","gpscript.exe.mui",
- "hdwwiz.cpl.mui","ie4uinit.exe.mui","ieuinit.inf.mui","imm32.dll.mui","inetcpl.cpl.mui",
- "intl.cpl.mui","IPHLPAPI.DLL.mui","jscript.dll.mui","jsproxy.dll.mui","kernel32.dll.mui","main.cpl.mui",
- "mferror.dll.mui","mmsys.cpl.mui","mscories.dll.mui","msctf.dll.mui","msi.dll.mui",
- "msimsg.dll.mui","msvcrt.dll.mui","ndfapi.dll.mui","netplwiz.dll.mui","normaliz.dll.mui","nsi.dll.mui",
- "ntdll.dll.mui","objsel.dll.mui","osbaseln.dll.mui","powrprof.dll.mui","propsys.dll.mui",
- "rasauto.dll.mui","rpcrt4.dll.mui","secur32.dll.mui","sens.dll.mui","setupapi.dll.mui","shdocvw.dll.mui",
- "shell32.dll.mui","shellstyle.dll.mui","shlwapi.dll.mui","Shsvcs.dll.mui","Shwebsvc.dll.mui",
- "SLC.dll.mui","sysdm.cpl.mui","themecpl.dll.mui","themeui.dll.mui","thumbcache.dll.mui","timedate.cpl.mui",
- "TSTheme.exe.mui","urlmon.dll.mui","user32.dll.mui","uxtheme.dll.mui","van.dll.mui",
- "vbscript.dll.mui","verclsid.exe.mui","wdi.dll.mui","WindowsCodecs.dll.mui","WindowsCodecsExt.dll.mui","wininet.dll.mui",
- "winnsi.dll.mui","winrnr.dll.mui","ws2_32.dll.mui","xmllite.dll.mui")
- foreach ($f in (gci $srcmountdir\Windows\system32\* -include $s32files)) {
- $destlocation = "$mountdir\Windows\system32\" + $f.Name # $f.Name because $f is the *full path*
- write-log "About to attempt to copy $f into $destlocation"
- #if (test-path $destlocation 2>&1 > $null) {
- # write-log "Path at $destlocation seems to already exist, trying to steal full control..."
- Echoexec-Expression $w Steal-FullControlPrivs $destlocation
- #}
- Echoexec-Expression $w copy-item -force -recurse $f $mountdir\Windows\system32
- }
- foreach ($f in (gci $srcmountdir\Windows\system32\$distlang\* -include $distlangfiles)) {
- $destlocation = "$mountdir\Windows\system32\$distlang\" + $f
- #if (test-path $destlocation 2>&1 > $null) {
- # write-log "Path at $destlocation seems to already exist, trying to steal full control..."
- Echoexec-Expression $w Steal-FullControlPrivs $destlocation
- #}
- Echoexec-Expression $w copy-item -force -recurse $f $mountdir\Windows\system32\$distlang
- }
- Echoexec-Expression $w copy-item -force -recurse `
- "$srcmountdir\Users\Default\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\Shows Desktop.lnk" `
- "$mountdir\Windows\System32\config\Systemprofile\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch"
- Echoexec-Expression $w copy-item -force -recurse "$srcmountdir\Program Files\Internet Explorer\ieshims.dll" "$mountdir\Program Files\Internet Explorer\ieshims.dll"
- Echoexec-Expression $w copy-item -force -recurse $srcmountdir\ProgramData\Microsoft\Windows\DeviceMetadataStore $mountdir\ProgramData\Microsoft\Windows\
- Echoexec-Expression $w copy-item -force -recurse $srcmountdir\Windows\AppPatch\sysmain.sdb $mountdir\Windows\AppPatch
- Echoexec-Expression $w copy-item -force -recurse $srcmountdir\Windows\Branding\Basebrd\basebrd.dll $mountdir\Windows\Branding\Basebrd
- Echoexec-Expression $w copy-item -force -recurse $srcmountdir\Windows\Branding\ShellBrd\shellbrd.dll $mountdir\Windows\Branding\ShellBrd
- Echoexec-Expression $w copy-item -force -recurse $srcmountdir\Windows\explorer.exe $mountdir\Windows
- Echoexec-Expression $w copy-item -force -recurse $srcmountdir\Windows\Branding\Basebrd\$distlang\basebrd.dll.mui $mountdir\Windows\Branding\Basebrd\$distlang
- Echoexec-Expression $w copy-item -force -recurse $srcmountdir\Windows\$distlang\explorer.exe.mui $mountdir\Windows\$distlang
- }
- $helptext = "
- $cmdname is a script which automates part of the setup process for WinPE 4.0 / WADK.
- It requires that WADK for WinPE 4 (Windows 8) is installed.
- There are subcommands that perform different steps in the process:
- $cmdname mkdir
- $cmdname mount
- $cmdname addpackages
- $cmdname unmount -OR- $cmdname cancelmount
- $cmdname makeiso
- You can get help with the command:
- $cmdname help
- You can perform all of the steps with the command:
- $cmdname buildall
- "
- switch ($action) {
- "mkdir" {
- WinPE-MakePEDirectory
- }
- "mount" {
- WinPE-Mount
- }
- "addpackages" {
- WinPE-AddPackages
- }
- "unmount" {
- WinPE-UnMount
- }
- "cancelmount" {
- WinPE-Cancelmount
- }
- "makeiso" {
- WinPE-MakeISO
- }
- "help" {
- write-host $helptext
- }
- "buildall" {
- WinPE-MakePEDirectory
- WinPE-Mount
- WinPE-AddPackages
- WinPE-UnMount
- WinPE-MakeISO
- }
- "startvm" {
- WinPE-StartVM
- }
- "addexplorer" {
- WinPE-AddExplorer
- }
- default {
- write-host ("Wrong action $action...")
- write-host ($helptext)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement