Public/Invoke-DockerContainerCommand.ps1
function Invoke-DockerContainerCommand { <# .SYNOPSIS Invokes a command inside a Docker container. .DESCRIPTION Invokes a command inside a Docker container. .PARAMETER ContainerId An array of strings containing the full id(s) (64 characters) of the container(s) where the command will be run. .PARAMETER Container An array of pscustomobjects containing the container(s) where the command will be run. .PARAMETER ComputerName An array of string containing the computer(s) where the containers are hosted. .PARAMETER Command An array of string containing the command(s) to run in the container. .PARAMETER Expression A string containing the expression to run in the container. .PARAMETER ScriptBlock An script block describing the command(s) to run in the container. .PARAMETER FilePath A string containing the path of a local powershell script to run in the container. .PARAMETER RunAsAdministrator A switch sepcifying wheter or not this cmdlet invokes a command as an Administrator. .PARAMETER AsJob A switch specifying whether or not to run the command as a background job in the container. .PARAMETER JobName A string the name of the job if the command is run as a background job in the container. By default, jobs are named Job<n>, where <n> is an ordinal number. If you use the JobName parameter in a command, the command is run as a job, and Invoke-DockerContainerCommand returns a job object, even if you do not include AsJob in the command. .INPUTS System.Management.Automation.PSCustomObject You can pipe a value for the containers to this cmdlet. .OUTPUTS System.Management.Automation.PSRemotingJob, or the output of the invoked command This cmdlet returns a job object, if you use the AsJob parameter. Otherwise, it returns the output of the invoked command, which is the value of the ScriptBlock parameter. .EXAMPLE Invoke-DockerContainerCommand -Command "Get-Service -Name MyService" -ContainerId 4f657b6d8066b87455303c591873b0739aa14f589cd56365a46a256f726c6be0 -ComputerName MyHostServer Description ----------- This example will get the service MyService in the container with id '4f657b6d8066b87455303c591873b0739aa14f589cd56365a46a256f726c6be0' on computer 'MyHostServer'. .EXAMPLE Get-DockerContainer | Invoke-DockerContainerCommand -ScriptBlock { Get-Service -Name MyService | Stop-Service [...] Get-Service -Name MyService | Start-Service } Description ----------- This example will get all containers hosted on the current computer, stop the service MyService, do some processing and start the service on each of them. .EXAMPLE Get-ChildItem Directory: C:\Script Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2020-09-02 8:56 AM 4579 BackEndScript.ps1 -a---- 2020-09-02 11:25 AM 5979 FrontEndScript.ps1 Get-DockerContainer -Name "*BackEnd" -ComputerName MyHostServer | Invoke-DockerContainerCommand -FilePath C:\Scripts\BackEndScript.ps1 -RunAsAdministrator -RunAsJob Description ----------- This example will get all containers that match "*BackEnd" on computer MyHostServer and run the script C:\Scripts\BackEndScript.ps1 as administrator and as a job in each container. .NOTES .LINK #> [CmdLetBinding()] param( [Parameter(ParameterSetName = "FromContainerObjectAndCommand", Mandatory = $true, ValueFromPipeline = $true)] [Parameter(ParameterSetName = "FromContainerObjectAndScriptBlock", Mandatory = $true, ValueFromPipeline = $true)] [Parameter(ParameterSetName = "FromContainerObjectAndFilePath", Mandatory = $true, ValueFromPipeline = $true)] [Parameter(ParameterSetName = "FromContainerObjectAndExpression", Mandatory = $true, ValueFromPipeline = $true)] [pscustomobject[]] $Container, [Parameter(ParameterSetName = "FromContainerIdAndCommand", Mandatory = $true)] [Parameter(ParameterSetName = "FromContainerIdAndScriptBlock", Mandatory = $true)] [Parameter(ParameterSetName = "FromContainerIdAndFilePath", Mandatory = $true)] [Parameter(ParameterSetName = "FromContainerIdAndExpression", Mandatory = $true)] [ValidateNotNullOrEmpty()] [ValidateLength(64, 64)] [string] $ContainerId, [Parameter(ParameterSetName = "FromContainerIdAndCommand", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndScriptBlock", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndFilePath", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndExpression", Mandatory = $false)] [string] $ComputerName = $env:COMPUTERNAME, [Parameter(ParameterSetName = "FromContainerObjectAndCommand", Mandatory = $true)] [Parameter(ParameterSetName = "FromContainerIdAndCommand", Mandatory = $true)] [ValidateNotNullOrEmpty()] [string[]] $Command, [Parameter(ParameterSetName = "FromContainerObjectAndFilePath", Mandatory = $true)] [Parameter(ParameterSetName = "FromContainerIdAndFilePath", Mandatory = $true)] [ValidateNotNullOrEmpty()] [ValidateScript( { Test-Path $_ } )] [string] $FilePath, [Parameter(ParameterSetName = "FromContainerObjectAndExpression", Mandatory = $true)] [Parameter(ParameterSetName = "FromContainerIdAndExpression", Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Expression, [Parameter(ParameterSetName = "FromContainerObjectAndScriptBlock", Mandatory = $true)] [Parameter(ParameterSetName = "FromContainerIdAndScriptBlock", Mandatory = $true)] [scriptblock] $ScriptBlock, [Parameter(ParameterSetName = "FromContainerObjectAndCommand", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerObjectAndScriptBlock", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerObjectAndFilePath", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerObjectAndExpression", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndCommand", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndScriptBlock", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndFilePath", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndExpression", Mandatory = $false)] [switch] $RunAsAdministrator, [Parameter(ParameterSetName = "FromContainerObjectAndCommand", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerObjectAndScriptBlock", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerObjectAndFilePath", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerObjectAndExpression", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndCommand", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndScriptBlock", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndFilePath", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndExpression", Mandatory = $false)] [switch] $AsJob, [Parameter(ParameterSetName = "FromContainerObjectAndCommand", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerObjectAndScriptBlock", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerObjectAndFilePath", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerObjectAndExpression", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndCommand", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndScriptBlock", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndFilePath", Mandatory = $false)] [Parameter(ParameterSetName = "FromContainerIdAndExpression", Mandatory = $false)] [string] $JobName ) begin { Write-Debug ($script:LocalizedData.Global.Debug.Entering -f $PSCmdlet.MyInvocation.MyCommand) if ($PSCmdlet.ParameterSetName -match "FromContainerId") { $Container = New-Object -TypeName PSCustomObject @{ FullId = $ContainerId; ComputerName = $ComputerName } $PSBoundParameters.Remove("ContainerId") | Out-Null if ($PSBoundParameters.ComputerName) { $PSBoundParameters.Remove("ComputerName") | Out-Null } } } process { $Container | ForEach-Object { $CurrentContainer = $_ try { $Params = $PSBoundParameters if ($Params.Container) { $Params.Remove("Container") | Out-Null } $Params.ContainerId = $CurrentContainer.FullId if ($Params.FilePath) { $Params.FilePath = Get-Content $Params.FilePath } Invoke-Command -ComputerName $CurrentContainer.ComputerName -ScriptBlock { try { $Params = $using:Params if ($Params.Expression) { $Params.Add("Command", "Invoke-Expression `"$($Params.Expression)`"") $Params.Remove("Expression") | Out-Null } if ($Params.FilePath) { $FilePath = (Join-Path $env:TEMP ("{0}.ps1" -f (New-Guid).ToString())) $Params.FilePath | Set-Content $FilePath $Params.FilePath = $FilePath } if ($Params.Command) { $Params.Command = [scriptblock]::Create($Params.Command -join ";") } if ($Params.ScriptBlock) { $Params.ScriptBlock = [scriptblock]::Create($Params.ScriptBlock) } Invoke-Command @Params } catch { Write-Error $_ } finally { if ($Params.FilePath) { Remove-Item $Params.FilePath -Force -ErrorAction SilentlyContinue } } } } catch { Write-Error $_ } } } end { Write-Debug ($script:LocalizedData.Global.Debug.Leaving -f $PSCmdlet.MyInvocation.MyCommand) } } |