Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
196 lines (149 sloc) 9.13 KB
function ConvertTo-Dockerfile {
<#
.SYNOPSIS
Scans and converts a valid WIM or VHDX file into a Dockerfile.
.DESCRIPTION
This command is the main entrypoint into this PowerShell module.
.PARAMETER ImagePath
Use a Windows image file as the source for the artifacts. Specify the filesystem path to the valid WIM or VHDX file.
NOTE: You will need administrative permissions in order to mount and inspect image files.
.PARAMETER Local
Use the local machine as the source for the artifacts.
.PARAMETER RemotePath
Use a remote machine as the source for the artifacts. Specify the path to the system drive on the remote machine.
.PARAMETER OutputPath
An optional parameter that specifies the filesystem path where artifacts and the resulting
Dockerfile will be stored. If you do not specify a path, a temporary directory will be created for you within the $env:Temp location.
.PARAMETER MountPath
The filesystem path to the directory where the image will be mounted to for discovery.
The folder will be created if it does not exist.
If you do not specify a path, a temporary directory will be created for you within the $env:Temp location and will be removed
.PARAMETER Artifact
Specify the discovery artifacts that will be scanned during the ConvertTo-Dockerfile command.
You can use tab completion to find all of the supported artifacts that can be discovered.
.PARAMETER ArtifactParam
This paramater is used in conjunction with the artifact paramater and currently is used when specifying IIS Websites.
Please see the examples for how to use this parameter.
.PARAMETER Force
This Parameter is for use when you want to use a folder that you have either already used for creating a Dockerfile from an image
.EXAMPLE
ConvertTo-Dockerfile -ImagePath E:\VMVirtualHardDisks\WebServer.VHDX -OutputPath C:\Docker\IIS\ -MountPath C:\Image\ -Artifact IIS -Verbose
With this example we will be mounting a VHDX for a Virtual Machine called WebServer and the image will be mounted at the C:\Image\ location. We have specified that we want to only return the IIS Artifact from this machine so this will only perform the discovery of IIS related items and will output the required items to the OutputPath directory which in this case we have specified this to be C:\Docker\IIS\ and we will return all verbose output when running this command.
.EXAMPLE
ConvertTo-Dockerfile -ImagePath E:\VMVirtualHardDisks\WebServer.VHDX -OutputPath C:\Docker\WebServer\ -Verbose
With this example we will be mounting a VHDX for a Virtual Machine called WebServer.
As we have not specifiec a MountPath the Image will be mounted into a folder in the Temp path location and will be removed when this command finishes.
As we have not specified a specific Artifact from this machine, this function will return artifacts for all of the available artifacts that this tool can attempt to discover and will output the required items to the OutputPath directory which in this case we have specified this to be C:\Docker\WebServer\
.EXAMPLE
ConvertTo-Dockerfile -ImagePath E:\VMVirtualHardDisks\WebServer.VHDX
With this example we will be mounting a VHDX for a Virtual Machine called WebServer.
As we have not specifiec a MountPath the Image will be mounted into a folder in the Temp path location and will be removed when this command finishes.
As we have not specified a specific Artifact from this machine, this function will return artifacts for all of the available artifacts that this tool can attempt to discover and as we have not specified an OutputPath this command will create a folder in the $env:temp folder where all of the artifacts, required files and the resulting Dockerfile will be output to.
.EXAMPLE
ConvertTo-Dockerfile -ImagePath E:\VMVirtualHardDisks\WebServer.VHDX -OutputPath C:\Docker\IIS_SingleSite\ -MountPath C:\Image\ -Artifact IIS -ArtifactParam 'Default Web Site' -Force -Verbose
With this example we will be mounting a VHDX for a Virtual Machine called WebServer and the image will be mounted at the C:\Image\ location.
We have specified that we want to only return the IIS Artifact and for this we have provided the name of the WebSite that we want to return via the ArtifactParam Parameter, in this case we have specified that we want to return the 'Default Web Site' that is created when the IIS feature is activated on a new server.
We have also specified the Force Parameter which will remove any existing files and folders that are in the OutputPath directory and will reuse this directory for the output from this command.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidGlobalVars",'')]
[CmdletBinding()]
param (
[Parameter(Mandatory = $false)]
[ValidateScript({if (!(Test-Path -Path $PSItem)) { return $false } else { return $true } })]
[string] $ImagePath,
[Parameter(Mandatory = $false)]
[string] $OutputPath,
[Parameter(Mandatory = $false)]
[string] $MountPath,
[Parameter(Mandatory = $true)]
[string] $Artifact,
[Parameter(Mandatory = $false)]
[string[]] $ArtifactParam,
[Parameter(Mandatory = $false)]
[Switch] $Force,
[Parameter(Mandatory = $false)]
[Switch] $Local,
[Parameter(Mandatory = $false)]
[string] $RemotePath,
[Parameter(Mandatory = $false)]
[Switch] $IncludeWindowsFeatures
)
# TODO - validat eLOcal & ImagePath
### If the user doesn't specify an output path, then generate one
if (!$PSBoundParameters.Keys.Contains('OutputPath')) {
$OutputPath = GenerateOutputFolder
}
elseif(($PSBoundParameters.Keys.Contains('OutputPath')) -and ($PSBoundParameters.Keys.Contains('Force'))) {
$OutputPath = GenerateOutputFolder -Path $OutputPath -Force
}
else {
$OutputPath = GenerateOutputFolder -Path $OutputPath
}
# set features flag:
$global:IncludeWindowsFeatures = $IncludeWindowsFeatures
# load the source - local drive, or VHD
$global:SourceType = [SourceType]::Local
if ($Local) {
$MountPath = $env:SystemDrive
$version = [Environment]::OSVersion.Version
$ImageWindowsVersion = "$($version.Major).$($version.Minor)"
Write-Verbose -Message "Using local drive: $MountPath"
}
elseif ($RemotePath) {
$global:SourceType = [SourceType]::Remote
$MountPath = $RemotePath
$version = (Get-ItemProperty -Path "$RemotePath\windows\system32\hal.dll").VersionInfo.ProductVersion
$ImageWindowsVersion = $version.Substring(0, $version.IndexOf('.', $version.IndexOf('.')+1))
Write-Verbose -Message "Using remote drive: $RemotePath"
}
elseif ($ImagePath) {
$global:SourceType = [SourceType]::Image
# Verify the image type before proceeding
$ImageType = GetImageType -Path $ImagePath
Write-Verbose -Message ('Image type is: {0}' -f $ImageType)
try {
# Mount the image to a directory
$Mount = MountImage -ImagePath $ImagePath -MountPath $MountPath
$MountPath = $Mount.Path
Write-Verbose -Message ('Finished mounting image to: {0}' -f $MountPath)
}
catch {
throw 'Fatal error: couldn''t mount image file: {0}' -f $PSItem
}
# Get the Windows version in the image, returns Major.Minor - e.g. 6.2 is Server 2012
# https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions
$info = Get-WindowsImage -Index 1 -ImagePath $ImagePath
$ImageWindowsVersion = "$($info.MajorVersion).$($info.MinorVersion)"
}
else {
throw "Source not specified. One of -Local, -ImagePath or -RemotePath is required."
}
Write-Verbose -Message ('Starting conversion process')
try {
### Perform artifact discovery
if (!$PSBoundParameters.Keys.Contains('Artifact')) {
$Artifact = Get-WindowsArtifact
}
if (!$PSBoundParameters.Keys.Contains('ArtifactParam')) {
DiscoverArtifacts -MountPath $MountPath -Artifact $Artifact -OutputPath $OutputPath -ImageWindowsVersion $ImageWindowsVersion
}
else {
DiscoverArtifacts -MountPath $MountPath -Artifact $Artifact -OutputPath $OutputPath -ImageWindowsVersion $ImageWindowsVersion -ArtifactParam $ArtifactParam
}
### Generate Dockerfile
if (!$PSBoundParameters.Keys.Contains('ArtifactParam')) {
GenerateDockerfile -MountPath $MountPath -ArtifactPath $OutputPath -Artifact $Artifact
}
else {
GenerateDockerfile -MountPath $MountPath -ArtifactPath $OutputPath -Artifact $Artifact -ArtifactParam $ArtifactParam
}
Write-Verbose -Message 'Finished generating the Dockerfile'
}
finally {
if ($Mount) {
### Dismount the image when inspection is completed
$null = Dismount-WindowsImage -Path $MountPath -Discard
Write-Verbose -Message ('Finished dismounting the Windows image from {0}' -f $MountPath)
}
}
}