powershellconda

Log output conda activate in powershell script


I want to write a powershell script which activates a conda environment and runs some python commands afterwards. The script should log its progress and possible errors to a file.

When trying to activate a conda environment which doesn't exists, the following problem arises:

C:\Path\to\conda.exe shell.powershell hook | Out-String | Invoke-Expression 
Invoke-Expression "conda activate ABC"

results in the output:

EnvironmentNameNotFound: Could not find conda environment: ABC
You can list all discoverable environments with `conda info --envs`.

Invoke-Expression: Cannot bind argument to parameter 'Command' because it is an empty string

The first part is what I want to log, the second part is an error which is thrown because the result of the command is empty. I dont want to log this part.

Currently my script looks like this (I replaced my logging function by Write-Output):

C:\Path\to\conda.exe shell.powershell hook | Out-String | Invoke-Expression
Write-Output "Activating environment: ABC"
try {
    $envActivateOutput = Invoke-Expression "conda activate ABC" *>&1
} catch [System.Management.Automation.ParameterBindingException]{
    Write-Output "Error: $envActivateOutput" # this is empty
    throw
} catch {
    Write-Output "Error: $_"
    throw
}

How can I catch the result of conda activate ABC in $envActivateOutput and log it, while not logging the ParameterBindingException?, but possible other Exceptions?


Solution

  • Therefore:

    C:\Path\to\conda.exe shell.powershell hook | Out-String | Invoke-Expression 
    
    "Activating environment: ABC"
    
    $envActivateOutput =
      conda activate ABC *>&1 | 
        Where-Object FullyQualifiedErrorId -ne 'ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand' |
        ForEach-Object {
          # Fix for a Windows PowerShell bug (not needed in PowerShell 7): 
          # *Empty* stderr lines stringify to verbatim 'System.Management.Automation.RemoteException'
          if ("$_" -eq 'System.Management.Automation.RemoteException') { '' }
          else { "$_" } # stringify the [ErrorRecord]-wrapped stderr line.
        }
    

    Note: