Skip to content

Instantly share code, notes, and snippets.

@tsmarvin
Last active April 8, 2025 00:19
Show Gist options
  • Save tsmarvin/3bc7427f4c98d6cd4642fb55d40752fa to your computer and use it in GitHub Desktop.
Save tsmarvin/3bc7427f4c98d6cd4642fb55d40752fa to your computer and use it in GitHub Desktop.
TM-DockerUtility

TM-DockerUtility Module

Introduction

TM-DockerUtility is a PowerShell module that provides various Docker-related utility functions. This module simplifies Docker operations within the PowerShell environment, making it easier to manage Docker containers and images.

This module is part of a suite of tools designed to improve and streamline the PowerShell command line and scripting experience.
Check out the rest of the modules by visiting my page on the PowerShell Gallery.

Features

  • New-MountPoint: Creates a custom MountPoint object for connecting to Docker images. MountPoints facilitate the mounting of local paths to container paths during Docker container creation.
  • Enter-DockerImageWithNewEntryPoint: Allows entry into a Docker container with a specified entry point. This is particularly useful when the default entry point is causing errors that prevent the container from running long enough to debug.
  • Remove-DockerResources: Cleans up the Docker environment by removing unused Docker resources such as containers, networks, images, and optionally volumes. This helps to keep the Docker environment clean and reduces clutter.

Requirements

Installation

Install TM-DockerUtility from the PowerShell Gallery:

Install-Module TM-DockerUtility -Scope CurrentUser -Repository PSGallery

For manual installation, download the module files and place them in a "TM-DockerUtility" folder in your PowerShell modules directory ($Env:PSModulePath).

MIT License
Copyright (c) 2023 Taylor Marvin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@{
# Script module or binary module file associated with this manifest.
RootModule = 'TM-DockerUtility.psm1'
# Version number of this module.
ModuleVersion = '0.0.9'
# Supported PSEditions
CompatiblePSEditions = @('Desktop','Core')
# ID used to uniquely identify this module
GUID = 'fdf3a018-72e7-404c-bcb8-150b5d49451a'
# Author of this module
Author = 'Taylor Marvin'
# Company or vendor of this module
CompanyName = 'N/A'
# Copyright statement for this module
Copyright = 'Taylor Marvin (2023)'
# Description of the functionality provided by this module
Description = 'Provides various Docker related utility functions.'
# Minimum version of the PowerShell engine required by this module
PowerShellVersion = '5.1'
# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @(
@{ModuleName='TM-RandomUtility'; ModuleVersion='0.0.10'; GUID='c07a9da5-9562-42b6-8aba-1279fdb25a8e'},
@{ModuleName='TM-ValidationUtility'; ModuleVersion='0.0.4'; GUID='1f1eebe8-7a0b-49ae-901e-c877f090a7fc'}
)
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = @('New-MountPoint', 'Enter-DockerImageWithNewEntryPoint', 'Remove-DockerResources')
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
AliasesToExport = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
Tags = @('Profile', 'Utility', 'docker')
# A URL to the license for this module.
LicenseUri = 'https://gist.github.com/tsmarvin/3bc7427f4c98d6cd4642fb55d40752fa#file-license'
# A URL to the main website for this project.
ProjectUri = 'https://gist.github.com/tsmarvin/3bc7427f4c98d6cd4642fb55d40752fa'
# Prerelease string of this module
# Prerelease = ''
# Flag to indicate whether the module requires explicit user acceptance for install/update/save
RequireLicenseAcceptance = $false
}
}
}
using namespace System.Collections.Generic
# Write verbose messages on import
if ((Get-PSCallStack)[1].Arguments -imatch 'Verbose=True') { $PSDefaultParameterValues['*:Verbose'] = $true }
if ((Test-ApplicationExistsInPath -ApplicationName 'docker') -eq $false) {
Write-Verbose 'docker does not exist in the Path. Skipping the import of docker ProfileUtility commands.'
# Do not export any module commands.
Export-ModuleMember
exit
}
# https://github.com/PowerShell/PowerShell/issues/17730#issuecomment-1190678484
$ExportedMembers = [List[string]]::new()
class MountPoint {
<#
.SYNOPSIS
Holds the HostPath and ContainerPath for use connecting to a given docker image.
#>
[string]$HostPath
[string]$ContainerPath
MountPoint(
[string]$hostPath = (Read-Host -Prompt 'Enter the local mount path'),
[string]$containerPath = (Read-Host -Prompt 'Enter the containers mount path')
) {
$this.HostPath = $hostPath
$this.ContainerPath = $containerPath
}
MountPoint() {
$this.HostPath = Read-Host -Prompt 'Enter the local mount path'
$this.ContainerPath = Read-Host -Prompt 'Enter the containers mount path'
}
[string]ToString() { return "-v ""$($this.HostPath)`:$($this.ContainerPath)"" " }
}
function New-MountPoint {
<#
.SYNOPSIS
Create a new MountPoint object.
.DESCRIPTION
This function allows the user to create a new MountPoint object from the TM-DockerUtility module.
MountPoint objects should be used with the Enter-DockerImageWithNewEntryPoint function's MountPoints parameter.
.PARAMETER HostPath
The path to a directory that exists on the local machine.
.PARAMETER ContainerPath
The path to create and mount the HostPath to inside the container.
.EXAMPLE
Enter-DockerImageWithNewEntryPoint -EntryPoint '/bin/bash' -DeleteDebugImage -MountPoints @(
(New-MountPoint -HostPath 'C:\Path\To\Folder1' -ContainerPath '/workspace/Folder1'),
(New-MountPoint -HostPath 'C:\Path\To\Folder2' -ContainerPath '/workspace/Folder2')
)
#>
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[Validation.ValidatePathExists('Folder')]
[string]$HostPath,
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$ContainerPath
)
return [MountPoint]::New($HostPath, $ContainerPath)
}
$ExportedMembers.Add('New-MountPoint')
function Enter-DockerImageWithNewEntryPoint {
<#
.SYNOPSIS
Enters a Docker container image with a new entry point.
.DESCRIPTION
This function allows you to enter a selected Docker container with a specified entry point.
This can be useful if your containers default entrypoint is causing errors and the container
will not stay running long enough for you to exec into it and debug the issue.
.PARAMETER EntryPoint
The entry point command to use with the debug image.
If no EntryPoint is provided then the user will be prompt to enter an EntryPoint instead.
.PARAMETER DeleteDebugImage
A boolean value that indicates whether to delete the debug image after exiting the container.
The default value is $true.
.PARAMETER MountPoints
An array of mount points to add to the Docker container.
Use the New-MountPoint function to create new mountpoint objects.
.EXAMPLE
Enter-DockerImageWithNewEntryPoint -EntryPoint '/bin/bash' -DeleteDebugImage -MountPoints @(
(New-MountPoint -HostPath 'C:\Path\To\Folder1' -ContainerPath '/workspace/Folder1'),
(New-MountPoint -HostPath 'C:\Path\To\Folder2' -ContainerPath '/workspace/Folder2')
)
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $false)]
[string]$EntryPoint = (
Read-Host -Prompt "Provide the entrypoint command to use with '$DebugName'.`nexample: /bin/bash "),
[Parameter(Mandatory = $false)]
[bool]$DeleteDebugImage = $true,
[Parameter(Mandatory = $false)]
[MountPoint[]]$MountPoints
)
if (($env:OS -eq 'Windows_NT') -and ($null -eq (Get-Process -Name 'Docker Desktop' -ErrorAction Ignore))) {
Write-Warning -Message 'Start Docker Desktop before trying to enter a docker image'
return
}
$DockerPSOut = docker ps -a --format '{{json .}}' | ConvertFrom-Json -ErrorAction Ignore
# Exit early if there are no containers to copy and enter.
if ($null -eq $DockerPSOut) {
Write-Warning 'Docker did not return any output from the ''docker ps -a'' command.'
return
}
Write-Host 'Select a container to enter:'
$Count = 0
$Container = $DockerPSOut | ForEach-Object {
Select-Object -InputObject $_ -Property @{n = '#'; e = { $Count } }, ID, Names, Status, Image
$Count++
} | Out-GridView -Title 'Available Containers' -OutputMode Single
# Make a copy of the selected container image
$ContainerImage = $Container.Image.Split('/')[-1]
$DebugName = "debug/$ContainerImage"
docker commit $Container.ID $DebugName | Write-Host
# Create start process arguments:
$dockerMount = ''
foreach ($MountPoint in $MountPoints) {
$dockerMount += $MountPoint.ToString()
}
$StartDockerRun = @{
FilePath = 'docker'
PassThru = $true
Wait = $true
NoNewWindow = $true
ArgumentList = @('run', '-it', $dockerMount, '--rm', '--entrypoint', $EntryPoint, $DebugName)
}
# Run the process in a try block in case something in the container sends a terminating error.
try {
$Process = Start-Process @StartDockerRun
if ($Process.ExitCode -ne 0) {
Write-Warning "Docker ExitCode is not 0. ExitCode: $($Process.ExitCode)"
}
} finally {
# Cleanup, Don't forget to delete the debug image if requested.
if ($DeleteDebugImage) {
$DockerImagesOut = docker images -a --format '{{json .}}' | ConvertFrom-Json -ErrorAction Ignore
$ImageName = "$DebugName".Split(':')[0]
$ImageId = $DockerImagesOut | Where-Object { $_.Repository -eq $ImageName } | Select-Object -ExpandProperty ID
docker.exe image rm $ImageId
}
}
}
$ExportedMembers.Add('Enter-DockerImageWithNewEntryPoint')
function Remove-DockerResources {
<#
.SYNOPSIS
Removes Docker resources, including unused containers, networks, images, and optionally volumes.
.DESCRIPTION
This function removes unused Docker resources such as containers, networks, images, and optionally volumes.
It serves as a cleanup tool to reset the docker environment state back to the default install state.
.PARAMETER IncludeVolumes
A boolean value that indicates whether to include volumes in the Docker resource removal.
The default value is $true.
#>
[Alias('Prune-DockerResources')]
[CmdletBinding()]
[OutputType([Void])]
param (
[Parameter(Mandatory = $false)]
[bool]$IncludeVolumes = $true
)
[List[string]]$DockerArgs = [List[string]]::new()
$DockerArgs.AddRange([string[]]@('system', 'prune', '--all', '--force'))
if ($IncludeVolumes) { $DockerArgs.Add('--volumes') }
docker @DockerArgs
}
$ExportedMembers.Add('Remove-DockerResources')
Export-ModuleMember -Function $ExportedMembers.ToArray()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment