Functions/Public/ConvertTo/ConvertTo-Dockerfile.ps1
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 ) # 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 } # 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) } } } |