1

I have a Powershell script in which I need to know if Docker Desktop is currently running.

I have read that one way to do it is to use docker ps and see if I get back a container list or an error message. But I'm struggling to make use of this in an actual script. I haven't worked out how to capture and act on the result correctly.

Here's what I have so far:

function IsDockerDesktopRunning()
{
    $dockerPsResult = docker ps | Out-String

    Write-Host "Result is:"
    Write-Host $dockerPsResult

    if (($dockerPsResult).StartsWith("error"))
    {
        return $false
    }
    return $true
}

$isRunning = IsDockerDesktopRunning
Write-Host $isRunning

When when it's not running, the result looks like this:

error during connect: This error may indicate that the docker daemon is not running.: Get "http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/containers/json": open //./pipe/docker_engine: The system cannot find the file specified.
Result is:

True

As you can see, it looks the output from the docker ps command gets output as it's executed and the variable isn't populated.

Is there a way to correctly capture the output? Or, should I tackle the problem a different way?

Dan McCoy
  • 313
  • 2
  • 15
  • Could it be a white space before the error? Try `if ($dockerPSResult.Trim().StartsWith("error") {...`. That `$true` should be in a else block as well. Otherwise, it'll keep getting written to the success stream regardless if there's an error or not. – Abraham Zinala Jun 01 '22 at 17:49
  • As per Abraham's comment, redirection (for command output) must be contemplated with what you are after: Details are here: https://devblogs.microsoft.com/scripting/understanding-streams-redirection-and-write-host-in-powershell. If you are an earlier version of PS, know that Write-Host empties the buffer, thus nothing to output. Unless you are using colorized output or other special Write-Host needs, it's best not to use it. Output to the screen is the PS default, otherwise, you could use Write-Output. – postanote Jun 01 '22 at 20:19
  • @AbrahamZinala - No, it's not a leading whitespace issue. The `$dockerPSResult` variable is empty. It's not been populated with the error message. – Dan McCoy Jun 02 '22 at 10:42
  • @AbrahamZinala Also, the fact that the `if` statement has a return in it means that the final return statement wouldn't be hit. – Dan McCoy Jun 02 '22 at 10:44
  • @postanote - Sorry, but I'm not sure how that addresses the question? – Dan McCoy Jun 02 '22 at 10:46
  • @DanMcCoy, my comment is as per the answer you accepted from dougmaurer. – postanote Jun 02 '22 at 19:13

2 Answers2

5

To capture the error output as well, redirect stderr to stdout like this.

$docker = docker ps 2>&1

You can use this to determine if docker desktop is running.

if((docker ps 2>&1) -match '^(?!error)'){
   Write-Host "Docker is running"
}
Doug Maurer
  • 8,090
  • 3
  • 12
  • 13
  • Hi Doug. Thanks for your answer. I'm not actually interested in a specific container. The question is whether **Docker Desktop** is running or not. – Dan McCoy Jun 02 '22 at 10:48
  • 1
    Thanks Doug. The regex doesn't seem to be quite right. But the first comment on how to redirect the error output does work and is what I was looking for, so I'm marking as the correct answer (I quickly worked around the regex issue). – Dan McCoy Jun 02 '22 at 17:56
-2

Since it doesn't seem possible to capture the error message in a variable, I've decided to switch the logic around and rely on the variable being empty.

function IsDockerDesktopRunning()
{
    $dockerPsResult = docker ps
    if ($dockerPsResult)
    {
        return $true
    }
    return $false
}

$isRunning = IsDockerDesktopRunning
Write-Host $isRunning

The unfortunate side effect is that the error message is still printed to the screen and makes things look a bit messy. But the logic works, so I'll live with it.

EDIT: Since adding this not so great answer, Doug has updated his answer, which is now correct. Thanks Doug.

Dan McCoy
  • 313
  • 2
  • 15