Public/Python/Get-PythonVENVDetails.ps1
using namespace System.Text.RegularExpressions function Get-PythonVENVDetails { [CmdletBinding()] [OutputType([FMDevToolbox.PythonVenvObject])] param ( [Parameter(Mandatory)] [String] $Folder ) process { if(-not(Test-Path -LiteralPath $Folder -PathType Container)){ throw "Folder doesn't exist. Check your spelling and try again." } if(-not(Confirm-PythonFolderIsVENV -Folder $Folder)){ throw "Passed -Folder ($Folder) is not a Python VENV" } $VENVOriginalPython = "Not Found" $VENVIncludeSystemPackages = "Not Found" $VENVPythonVersion = "Not Found" try { Push-Location $Folder -StackName VENV $PythonVenvCfg = [System.IO.Path]::Combine($Folder, 'pyvenv.cfg') $DirectoryIsVENV = Test-Path -LiteralPath $PythonVenvCfg -PathType Leaf if(!$DirectoryIsVENV){ Write-Error "The directory specified is not a Python VENV. (Missing pyvenv.cfg)" return } $PythonVenvFolder = $Folder $PythonActivatePS1 = [System.IO.Path]::Combine($Folder, 'Scripts', 'Activate.ps1') if(-not($PythonActivatePS1 | Test-Path)){ $PythonActivatePS1 = "Not Found" } $PythonActivateBAT = [System.IO.Path]::Combine($Folder, 'Scripts', 'activate.bat') if(-not($PythonActivateBAT | Test-Path)){ $PythonActivateBAT = "Not Found" } $PythonDeactivateBAT = [System.IO.Path]::Combine($Folder, 'Scripts', 'deactivate.bat') if(-not($PythonDeactivateBAT | Test-Path)){ $PythonDeactivateBAT = "Not Found" } & $PythonActivatePS1 $PipCmdPath = Join-Path -Path (Join-Path $PythonVenvFolder -ChildPath 'Scripts') -ChildPath 'pip.exe' $PipCmd = Get-Command $PipCmdPath -CommandType Application $PackageList = & $PipCmd list $PackageContainer = [System.Collections.Generic.List[psobject]]@() # Split the string into lines, skip the first two lines (header and separator), and process each package line $PackageList -split "`n" | Select-Object -Skip 2 | ForEach-Object { # Trim and split each line by spaces, filtering out empty elements resulting from multiple spaces $parts = $_.Trim() -split '\s+' | Where-Object { $_ -ne '' } # The first part is the package name, the rest (if there are version parts) join together as the version $packageName = $parts[0] $packageVersion = $parts[1] # Create and output a PSObject for each package $obj = [pscustomobject]@{ Package = $packageName Version = $packageVersion } $PackageContainer.Add($obj) } $PythonExe = [System.IO.Path]::Combine($Folder, 'Scripts', 'python.exe') if(-not($PythonExe | Test-Path)){ $PythonExe = "Not Found" } $PythonDebugExe = [System.IO.Path]::Combine($Folder, 'Scripts', 'python_d.exe') if(-not($PythonDebugExe | Test-Path)){ $PythonDebugExe = "Not Found" } $PythonSitePKG = [System.IO.Path]::Combine($Folder, 'Lib', 'site-packages') if(-not($PythonSitePKG | Test-Path)){ $PythonSitePKG = "Not Found" } $PythonPipExe = [System.IO.Path]::Combine($Folder, 'Scripts', 'pip.exe') if(-not($PythonPipExe | Test-Path)){ $PythonPipExe = "Not Found" } $PipCmd = Get-Command $PythonPipExe -CommandType Application $PythonPipVersion = "Unknown" $PipParams = "--version" $PipVersionString = & $PipCmd $PipParams $VersionRegex = '\b\d+(\.\d+)*(\w?\d*)?\b' $VersionMatch = [regex]::Match($PipVersionString, $VersionRegex) if ($VersionMatch.Success) { $PythonPipVersion = $VersionMatch.Value } $PythonConfigLines = Get-Content -Path $PythonVenvCfg foreach ($Line in $PythonConfigLines) { if ($Line -match '^home\s*=\s*(.*)') { $VENVOriginalPython = $matches[1].Trim() } elseif ($Line -match '^version\s*=\s*(.*)') { $VENVPythonVersion = $matches[1].Trim() } elseif ($Line -match '^include-system-site-packages\s*=\s*(.*)') { $VENVIncludeSystemPackages = $matches[1].Trim() } } $ScriptsContents = Join-Path $Folder -ChildPath "Scripts" $PythonScriptsContents = Get-ChildItem $ScriptsContents if(-not($PythonScriptsContents)){ Write-Error "Python Scripts folder is Empty." $PythonScriptsContents = @("Error: Not Found") } & deactivate Pop-Location -StackName VENV [FMDevToolbox.PythonVenvObject]@{ IsVENV = $DirectoryIsVENV VENVPath = $PythonVenvFolder PythonVersion = $VENVPythonVersion PythonHome = $VENVOriginalPython ActivateFilePS1 = $PythonActivatePS1 ActivateFileBAT = $PythonActivateBAT DeactivateBAT = $PythonDeactivateBAT SitePackagesDir = $PythonSitePKG SitePackagesList = $PackageContainer PythonBinary = $PythonExe PythonDebugBinary = $PythonDebugExe PIPBinary = $PythonPipExe PIPVersion = $PythonPipVersion IncludeSystemPackages = $VENVIncludeSystemPackages ConfigFile = $PythonVenvCfg ScriptsContent = $PythonScriptsContents } } catch { & $PythonDeactivateBAT $PSCmdlet.ThrowTerminatingError($PSItem) } } } |