public override string PathToPowerShellExecutable(IVariables variables) { var customVersion = variables[PowerShellVariables.CustomPowerShellVersion]; var customVersionIsDefined = !string.IsNullOrEmpty(customVersion); try { var availablePowerShellVersions = new[] { Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) } .Where(p => p != null) .Distinct() .Select(pf => Path.Combine(pf, "PowerShell")) .Where(fileSystem.DirectoryExists) .SelectMany(fileSystem.EnumerateDirectories) .Select <string, (string path, string versionId, int?majorVersion, string remaining)>(d => { var directoryName = fileSystem.GetDirectoryName(d); // Directories are typically versions like "6" or they might also have a prerelease component like "7-preview" var splitString = directoryName.Split(new[] { '-' }, 2); var majorVersionPart = splitString[0]; var preRelease = splitString.Length < 2 ? string.Empty : splitString[1]; // typically a prerelease tag, like "preview" if (int.TryParse(majorVersionPart, out var majorVersion)) { return(d, directoryName, majorVersion, preRelease); } return(d, directoryName, null, preRelease); }).ToList(); var latestPowerShellVersionDirectory = availablePowerShellVersions .Where(p => string.IsNullOrEmpty(customVersion) || p.versionId == customVersion) .OrderByDescending(p => p.majorVersion) .ThenBy(p => p.remaining) .Select(p => p.path) .FirstOrDefault(); if (customVersionIsDefined && latestPowerShellVersionDirectory == null) { throw new PowerShellVersionNotFoundException(customVersion, availablePowerShellVersions.Select(v => v.versionId)); } if (latestPowerShellVersionDirectory == null) { return(EnvPowerShellPath); } var pathToPwsh = Path.Combine(latestPowerShellVersionDirectory, EnvPowerShellPath); return(fileSystem.FileExists(pathToPwsh) ? pathToPwsh : EnvPowerShellPath); } catch (PowerShellVersionNotFoundException) { throw; } catch (Exception) { return(EnvPowerShellPath); } }