Skip to content

Instantly share code, notes, and snippets.

@digitalsleuth
Last active September 23, 2024 08:58
Show Gist options
  • Save digitalsleuth/f011cacef50e2b2bc7057dd4edd7c33b to your computer and use it in GitHub Desktop.
Save digitalsleuth/f011cacef50e2b2bc7057dd4edd7c33b to your computer and use it in GitHub Desktop.
WinFE-Installer Script
<#
.SYNOPSIS
This script is used to install the Windows Forensic Environment (WinFE) onto a USB
https://github.com/digitalsleuth/
.DESCRIPTION
.NOTES
Version : 1.1a
Author : Corey Forman (https://github.com/digitalsleuth)
Prerequisites : Windows 10 1909 or later
: Set-ExecutionPolicy must allow for script execution
.PARAMETER Mode
There are two modes to choose from for the installation:
online: Fetch the appropriate tools from online and use them to install the WinFE environment
offline: Assumes that you already have the WinFE package, FTK Imagers, and Win 10 ADK 1803 Setup
.PARAMETER DriveLetter <ltr>
Choose the desired drive letter for which to configure the installation, no trailing slash
.PARAMETER Installers <path>
Path to the offline installers, required if choosing the offline mode.
.PARAMETER Help
Displays the available options and their usage
.Example
.\winfe.ps1 -DriveLetter F: -Online
.\winfe.ps1 -DriveLetter E: -Offline -FilePath C:\Temp
.TODO
Make another TEMP directory besides Windows\Temp
#>
param (
[string]$DriveLetter,
[string]$Mode = "online",
[string]$FilePath = "C:\Temp",
[switch]$MakeIso,
[switch]$Help
)
[string]$VERSION = '1.1a'
[string]$FTKIMG_x86_VER="3.4.0.5"
[string]$FTKIMG_x86_SRC="https://ad-exe.s3.amazonaws.com/AccessData%20FTK%20Imager%203.4.0.5.exe"
[string]$FTKIMG_x86_FN="AccessData_FTK_Imager_3.4.0.5.exe"
[string]$FTKIMG_x86_HASH="F441D991DD1C1D31A427DF1520EC2705CC626D4A104BDD10F385ADE9E323A233"
[string]$FTKIMG_x64_VER="4.7.1"
[string]$FTKIMG_x64_SRC="https://ad-exe.s3.amazonaws.com/AccessData_FTK_Imager_4.7.1.exe"
[string]$FTKIMG_x64_FN="AccessData_FTK_Imager_4.7.1.exe"
[string]$FTKIMG_x64_HASH="57020F3E585D0F2A7EE783054C50886DB4C65AF1BBBE5E12E114DBF674326184"
[string]$WIN10ADK_SRC="https://go.microsoft.com/fwlink/?linkid=873065"
[string]$WIN10ADK_FN="adksetup.exe"
[string]$WIN10ADK_HASH="DF32DF3AD55419D1B8D3536F66EA87D00C0993FDB6534552A9B274249F1C0353"
[string]$WINFE_SRC="https://www.winfe.net/files/IntelWinFE.7z"
[string]$WINFE_FN="IntelWinFE.7z"
[string]$WINFE_HASH="5F277E71AC57330017ABA534D38B09CD26EDA443BFF58F29733C005BEFD1F358"
$ProgressPreference = "SilentlyContinue"
function Compare-Hash($FileName, $HashName) {
$fileHash = (Get-FileHash $FileName -Algorithm SHA256).Hash
if ($fileHash -eq $HashName) {
Write-Host "[+] Hashes match for $FileName, continuing..." -ForegroundColor Green
} else {
Write-Host "[+] Hashes do not match for $FileName, not continuing with install" -ForegroundColor Red
exit
}
}
function Install-ScriptRequirements {
Write-Host "[-] Checking for Script Requirements" -ForegroundColor Yellow
if (($Mode -eq 'offline') -and ($FilePath)) {
if (-Not(Test-Path 'C:\Program Files\PackageManagement\ProviderAssemblies\nuget')) {
Write-Host "[!] Missing the nuget module in your ProviderAssemblies folder. See -Help for more info" -ForegroundColor Red
exit 1
} else {
Write-Host "[+] Nuget is installed, importing 7Zip4Powershell Module" -ForegroundColor Yellow
New-Item -ItemType 'directory' -Path "C:\Temp" | Out-Null
if (Get-Module -ListAvailable -Name 7Zip4Powershell) {
Write-Host "[+] 7Zip4PowerShell module is already installed, continuing" -ForegroundColor Green
} elseif (Test-Path "$FilePath\7Zip4Powershell.*") {
Copy-Item -Path "$FilePath\7Zip4Powershell.*" -Destination "C:\Temp\"
Register-PSRepository -Name Temp -SourceLocation "C:\Temp" -InstallationPolicy Trusted
Install-Module -Name 7Zip4Powershell -Repository Temp
Unregister-PSRepository -Name Temp
} else {
Write-Host "[!] 7Zip4Powershell module not found - check to see that it exists in $FilePath" -ForegroundColor Red
exit 1
}
}
} elseif ($Mode -eq 'online') {
if(-not(Test-Path $FilePath)) {
New-Item -ItemType 'directory' -Path $FilePath | Out-Null
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Write-Host "[-] Installing NuGet > v2.8.5.201" -ForegroundColor Yellow
if (Test-Path 'C:\Program Files\PackageManagement\ProviderAssemblies\nuget') {
Write-Host "[+] NuGet module is already available, continuing..." -ForegroundColor Green
} else {
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force | Out-Null
}
if (Get-Module -ListAvailable -Name 7Zip4Powershell) {
Write-Host "[+] 7Zip4PowerShell module is already installed, continuing" -ForegroundColor Green
} else {
Write-Host "[-] Installing 7Zip4Powershell Module > v2.1" -ForegroundColor Yellow
Install-Module -Name 7Zip4Powershell -MinimumVersion 2.1 -Force | Out-Null
}
}
Write-Host "[+] Requirements met, continuing..." -ForegroundColor Green
}
function Start-Downloads {
Write-Host "[-] Beginning file downloads" -ForegroundColor Yellow
$DOWNLOADS = [ordered]@{
"$WIN10ADK_SRC" = "$WIN10ADK_FN" ;
"$FTKIMG_x86_SRC" = "$FTKIMG_x86_FN" ;
"$FTKIMG_x64_SRC" = "$FTKIMG_x64_FN" ;
"$WINFE_SRC" = "$WINFE_FN"
}
foreach ($DOWNLOAD in $DOWNLOADS.GetEnumerator()) {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Write-Host "[-] Downloading $($DOWNLOAD.Name) to $FilePath\$($DOWNLOAD.Value)" -ForegroundColor Yellow
Start-BitsTransfer -Source $($DOWNLOAD.Name) -Destination "$FilePath\$($DOWNLOAD.Value)"
}
$HASHES = [ordered]@{
"$FilePath\$WIN10ADK_FN" = "$WIN10ADK_HASH" ;
"$FilePath\$FTKIMG_x86_FN" = "$FTKIMG_x86_HASH" ;
"$FilePath\$FTKIMG_x64_FN" = "$FTKIMG_x64_HASH" ;
"$FilePath\$WINFE_FN" = "$WINFE_HASH"
}
foreach ($HASH in $HASHES.GetEnumerator()) {
Compare-Hash -FileName $($HASH.Name) -HashName $($HASH.Value)
}
}
function Install-WinFERequirements {
if (($Mode -eq 'offline') -and ($FilePath)) {
$FilePath = $FilePath.TrimEnd('\')
$HASHES = [ordered]@{
"$FilePath\$WIN10ADK_FN" = "$WIN10ADK_HASH" ;
"$FilePath\$FTKIMG_x86_FN" = "$FTKIMG_x86_HASH" ;
"$FilePath\$FTKIMG_x64_FN" = "$FTKIMG_x64_HASH" ;
"$FilePath\$WINFE_FN" = "$WINFE_HASH"
}
foreach ($HASH in $HASHES.GetEnumerator()) {
Compare-Hash -FileName $($HASH.Name) -HashName $($HASH.Value)
}
} elseif ($Mode -eq 'online') {
$FilePath = "C:\Temp"
}
$PROGRAMS = [ordered]@{ "$FTKIMG_x86_FN" = '/s /v/qn /v"INSTALLDIR="C:\FTKIMGx86""' ; "$FTKIMG_x64_FN" = '/s /v/qn /v"INSTALLDIR="C:\FTKIMGx64""'; "$WIN10ADK_FN" = "/quiet"}
foreach ($PROGRAM in $PROGRAMS.GetEnumerator()) {
Write-Host "[-] Installing $($PROGRAM.Name)" -ForegroundColor Yellow
Start-Process -Wait -FilePath "$FilePath\$($PROGRAM.Name)" -ArgumentList "$($PROGRAM.Value)" -PassThru | Out-Null
if ($?) {
Write-Host "[+] $($PROGRAM.Name) installed successfully" -ForegroundColor Green
if ($($PROGRAM.Name) -like "*FTK*") {
$INSTALLDIR = $($PROGRAM.Value).Split('=').Split('"')[3]
$DEST = $INSTALLDIR.Split('\')[1]
Write-Host "[-] Creating $FilePath\$DEST" -ForegroundColor Yellow
New-Item -ItemType "directory" -Path "$FilePath\" -Name "$DEST" -Force | Out-Null
Get-ChildItem -Path "$INSTALLDIR\FTK Imager\" | Copy-Item -Destination "$FilePath\$DEST" -Recurse -Container -Force
Write-Host "[+] $INSTALLDIR\FTK Imager\ copied to $FilePath\$DEST" -ForegroundColor Green
Start-Process -Wait -FilePath "$FilePath\$($PROGRAM.Name)" -ArgumentList "/x /s /v/qn" -PassThru | Out-Null
if ($?) {
Write-Host "[+] $($PROGRAM.Name) uninstalled" -ForegroundColor Green
} else {
Write-Host "[!] $($PROGRAM.Name) could not be uninstalled" -ForegroundColor Red
}
}
} else {
Write-Host "[!] Installation of $($PROGRAM.Name) failed. Please re-run the installer to try again" -ForegroundColor Red
exit 1
}
}
}
function Extract-WinFE {
Write-Host "[-] Extracting WinFE to $FilePath" -ForegroundColor Yellow
Expand-7Zip -ArchiveFileName "$FilePath\$WINFE_FN" -TargetPath "$FilePath\IntelWinFE"
}
function Move-Requirements {
New-Item -ItemType "directory" -Path "$FilePath\IntelWinFE\USB\x86-x64\tools\x86\" -Name "FTK Imager" -Force | Out-Null
New-Item -ItemType "directory" -Path "$FilePath\IntelWinFE\USB\x86-x64\tools\x64\" -Name "FTK Imager" -Force | Out-Null
Write-Host "[-] Copying FTK Imager x86 installation to $FilePath\IntelWinFE\USB\x86-x64\tools\x86\FTK Imager" -ForegroundColor Yellow
Get-ChildItem -Path "$FilePath\FTKIMGx86\" | Copy-Item -Destination "$FilePath\IntelWinFE\USB\x86-x64\tools\x86\FTK Imager" -Recurse -Container
Write-Host "[-] Copying FTK Imager x64 installation to $FilePath\IntelWinFE\USB\x86-x64\tools\x64\FTK Imager" -ForegroundColor Yellow
Get-ChildItem -Path "$FilePath\FTKIMGx64\" | Copy-Item -Destination "$FilePath\IntelWinFE\USB\x86-x64\tools\x64\FTK Imager" -Recurse -Container
}
function Run-WinFEBatch {
Set-Location -Path "$FilePath\IntelWinFE\"
Write-Host "[-] Running MakeWinFEx64-x86.bat" -ForegroundColor Yellow
Start-Process -Wait -FilePath "$FilePath\IntelWinFE\MakeWinFEx64-x86.bat" -PassThru -NoNewWindow
}
function Build-ISO {
Set-Location -Path "$FilePath\IntelWinFE\"
Write-Host "[-] Running Makex64-x86-CD.bat to create an ISO" -ForegroundColor Yellow
Start-Process -Wait -FilePath "$FilePath\IntelWinFE\Makex64-x86-CD.bat" -PassThru -NoNewWindow
}
function Prepare-Disk {
Write-Host "[-] Preparing USB drive for WinFE" -ForegroundColor Yellow
$DiskNumber = (Disk-Info | ? DriveLetter -eq $DriveLetter | Foreach { $_.DiskNumber})
Write-Host "[-] Clearing $DriveLetter, Disk Number $DiskNumber" -ForegroundColor Yellow
Get-Disk $DiskNumber | Clear-Disk -RemoveData -Confirm:$false
Set-Disk -Number $DiskNumber -PartitionStyle MBR
Write-Host "[-] Creating a new partition on $DriveLetter, making it active, creating FAT32 File System" -ForegroundColor Yellow
if ((Get-Disk $DiskNumber | foreach {$_.Size}) -gt 34359738368) {
New-Partition -DiskNumber $DiskNumber -Size 34359738368 -DriveLetter $DriveLetter.TrimEnd(':') -IsActive:$true |
Format-Volume -FileSystem FAT32 -NewFileSystemLabel WinFE | Out-Null
} else {
New-Partition -DiskNumber $DiskNumber -UseMaximumSize -DriveLetter $DriveLetter.TrimEnd(':') -IsActive:$true |
Format-Volume -FileSystem FAT32 -NewFileSystemLabel WinFE | Out-Null
}
Write-Host "[-] Copying contents of $FilePath\IntelWinFE\USB\x86-x64 to $DriveLetter" -ForegroundColor Yellow
Get-ChildItem -Path "$FilePath\IntelWinFE\USB\x86-x64" | Copy-Item -Destination $DriveLetter -Recurse -Container
Write-Host "[-] Modifying Boot Sector" -ForegroundColor Yellow
bootsect.exe /NT60 $DriveLetter /force /mbr | Out-Null
if ($?) {
Write-Host "[+] Installation complete! You may now safely eject your device." -ForegroundColor Green
} else {
Write-Host "[!] Installation failed! You may want to retry the installation again." -ForegroundColor Red
exit 1
}
}
function Disk-Info {
Get-CimInstance Win32_Diskdrive -pv Disk |
% { Get-CimAssociatedInstance $_ -Result Win32_DiskPartition -pv Partition }|
% { Get-CimAssociatedInstance $_ -Result Win32_LogicalDisk } |
Select-Object @{n='DriveLetter';e={$_.DeviceID}},
@{n='DiskNumber';e={$Partition.DiskIndex}},
@{n='PartitionNumber';e={$Partition.Index}},
@{n='Disk';e={$Disk.DeviceID}},
@{n='DiskSize';e={$Disk.size}},
@{n='DiskModel';e={$Disk.model}},
@{n='Partition';e={$Partition.name}},
@{n='RawSize';e={$Partition.size}}
}
function Build-All {
Extract-WinFE
Move-Requirements
Run-WinFEBatch
if ($MakeIso) {
Build-ISO
}
Prepare-Disk
}
function Invoke-WinFEInstaller {
$runningUser = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if (-not $runningUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Host "[!] Not running as administrator, please re-run this script as Administrator" -ForegroundColor Red
exit 1
}
if (-not($DriveLetter)) {
Write-Host "[!] You must supply a value for DriveLetter" -ForegroundColor Red
Get-WmiObject -class Win32_volume | Select DriveLetter,SerialNumber,Filesystem,@{n="Capacity / MB";e={[math]::truncate($_.Capacity / 1MB)}}
exit 1
}
$DriveLetter = $DriveLetter.TrimEnd("\")
$FilePath = $FilePath.TrimEnd("\")
if (($Mode -ne "online") -and ($Mode -ne "offline")) {
Write-Host "[!] The only valid modes are 'online' or 'offline'." -ForegroundColor Red
exit 1
}
if ($Mode -eq "online") {
Install-ScriptRequirements
Start-Downloads
Install-WinFERequirements
Build-All
} elseif ($Mode -eq "offline") {
Install-ScriptRequirements
Install-WinFERequirements
Build-All
}
}
function Show-WinFEInstallerHelp {
Write-Host -ForegroundColor Yellow @"
Windows Forensics Environment (WinFE) Installer $VERSION
https://winfe.net
Usage:
-DriveLetter <ltr> Choose the desired drive letter for which to configure the installation, no trailing slash
-Mode <mode> There are two modes to choose from for the installation:
online: Fetch the appropriate tools from online and use them to install the WinFE environment
offline: Assumes that you already have the WinFE package, FTK Imagers, and Win 10 ADK 1803 Setup
-Installers <path> Path to the offline installers, required if choosing the offline mode.
-MakeIso When selected, this will create a bootable ISO
When selecting the Offline mode, the following files will be required:
Nuget Powershell Module (Install Nuget on an online machine and copy nuget folder from
C:\Program Files\PackageManagement\ProviderAssemblies\ into the
same location on this computer)
7Zip4Powershell.2.1.0.nupkg https://www.powershellgallery.com/packages/7Zip4Powershell/2.1.0
AccessData FTK Imager 3.4.0.5 https://ad-exe.s3.amazonaws.com/AccessData%20FTK%20Imager%203.4.0.5.exe
AccessData FTK Imager 4.7.1.2 https://ad-exe.s3.amazonaws.com/AccessData_FTK_Imager_4.7.1.exe
Windows 10 ADK 1803 https://go.microsoft.com/fwlink/?linkid=873065
The latest Intel WinFE package https://www.winfe.net/files/IntelWinFE.7z
"@
}
if ($Help -and $PSBoundParameters.Count -eq 1) {
Show-WinFEInstallerHelp
exit 1
} elseif (($Mode -eq 'online') -and ($PSBoundParameter.ContainsKey('FilePath'))) {
Write-Host "[!] FilePath is only required for offline installation" -ForegroundColor Red
exit 1
} else {
Invoke-WinFEInstaller
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment