PowerShellGetV2.cs (9518B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="PowerShellGetV2.cs" company="Microsoft Corporation"> 3 // Copyright (c) Microsoft Corporation. Licensed under the MIT License. 4 // </copyright> 5 // ----------------------------------------------------------------------------- 6 7 namespace Microsoft.Management.Configuration.Processor.PowerShell.Helpers 8 { 9 using System.Collections.Generic; 10 using System.Linq; 11 using System.Management.Automation; 12 using Microsoft.PowerShell.Commands; 13 using static Microsoft.Management.Configuration.Processor.PowerShell.Constants.PowerShellConstants; 14 using SemanticVersion = Microsoft.Management.Configuration.Processor.Helpers.SemanticVersion; 15 16 /// <summary> 17 /// PowerShellGet implementation for 2.2.5 . 18 /// </summary> 19 internal class PowerShellGetV2 : IPowerShellGet 20 { 21 private const string AllUsers = "AllUsers"; 22 23 /// <inheritdoc/> 24 public PSObject? FindModule( 25 PowerShell pwsh, 26 string moduleName, 27 SemanticVersion? semanticVersion, 28 SemanticVersion? semanticMinVersion, 29 SemanticVersion? semanticMaxVersion, 30 string? repository, 31 bool? allowPrerelease) 32 { 33 bool implicitAllowPrerelease = false; 34 35 var parameters = new Dictionary<string, object>() 36 { 37 { Parameters.Name, moduleName }, 38 }; 39 40 if (semanticVersion != null) 41 { 42 implicitAllowPrerelease |= semanticVersion.IsPrerelease; 43 parameters.Add(Parameters.RequiredVersion, semanticVersion.ToString()); 44 } 45 46 if (semanticMinVersion != null) 47 { 48 implicitAllowPrerelease |= semanticMinVersion.IsPrerelease; 49 parameters.Add(Parameters.MinimumVersion, semanticMinVersion.ToString()); 50 } 51 52 if (semanticMaxVersion != null) 53 { 54 implicitAllowPrerelease |= semanticMaxVersion.IsPrerelease; 55 parameters.Add(Parameters.MaximumVersion, semanticMaxVersion.ToString()); 56 } 57 58 if (!string.IsNullOrEmpty(repository)) 59 { 60 parameters.Add(Parameters.Repository, repository); 61 } 62 63 if (allowPrerelease.HasValue || implicitAllowPrerelease) 64 { 65 // If explicit allowPrerelease = false don't use implicit. 66 bool allow = allowPrerelease ?? implicitAllowPrerelease; 67 parameters.Add(Parameters.AllowPrerelease, allow); 68 } 69 70 pwsh.AddCommand(Commands.FindModule) 71 .AddParameters(parameters); 72 73 return pwsh.Invoke().FirstOrDefault(); 74 } 75 76 /// <inheritdoc/> 77 public PSObject? FindDscResource( 78 PowerShell pwsh, 79 string resourceName, 80 string? moduleName, 81 SemanticVersion? semanticVersion, 82 SemanticVersion? semanticMinVersion, 83 SemanticVersion? semanticMaxVersion, 84 string? repository, 85 bool? allowPrerelease) 86 { 87 var parameters = new Dictionary<string, object>() 88 { 89 { Parameters.Name, resourceName }, 90 }; 91 92 bool implicitAllowPrerelease = false; 93 94 if (!string.IsNullOrEmpty(moduleName)) 95 { 96 parameters.Add(Parameters.ModuleName, moduleName); 97 } 98 99 if (semanticVersion != null) 100 { 101 implicitAllowPrerelease |= semanticVersion.IsPrerelease; 102 parameters.Add(Parameters.RequiredVersion, semanticVersion.ToString()); 103 } 104 105 if (semanticMinVersion != null) 106 { 107 implicitAllowPrerelease |= semanticMinVersion.IsPrerelease; 108 parameters.Add(Parameters.MinimumVersion, semanticMinVersion.ToString()); 109 } 110 111 if (semanticMaxVersion != null) 112 { 113 implicitAllowPrerelease |= semanticMaxVersion.IsPrerelease; 114 parameters.Add(Parameters.MaximumVersion, semanticMaxVersion.ToString()); 115 } 116 117 if (!string.IsNullOrEmpty(repository)) 118 { 119 parameters.Add(Parameters.Repository, repository); 120 } 121 122 if (allowPrerelease.HasValue || implicitAllowPrerelease) 123 { 124 // If explicit allowPrerelease = false don't use implicit. 125 bool allow = allowPrerelease ?? implicitAllowPrerelease; 126 parameters.Add(Parameters.AllowPrerelease, allow); 127 } 128 129 pwsh.AddCommand(Commands.FindDscResource) 130 .AddParameters(parameters); 131 132 // The result is just a PSCustomObject with a type name of Microsoft.PowerShell.Commands.PSGetDscResourceInfo. 133 // When no module is passed and a resource is not found, this will return an empty list. If a module 134 // is specified and no resource is found then it will fail earlier because of a Write-Error. 135 return pwsh.Invoke().FirstOrDefault(); 136 } 137 138 /// <inheritdoc/> 139 public void SaveModule( 140 PowerShell pwsh, 141 ModuleSpecification moduleSpecification, 142 string location) 143 { 144 var parameters = new Dictionary<string, object>() 145 { 146 { Parameters.Name, moduleSpecification.Name }, 147 { Parameters.Path, location }, 148 }; 149 150 if (moduleSpecification.Version is not null) 151 { 152 parameters.Add(Parameters.MinimumVersion, moduleSpecification.Version); 153 } 154 155 if (moduleSpecification.MaximumVersion is not null) 156 { 157 parameters.Add(Parameters.MaximumVersion, moduleSpecification.MaximumVersion); 158 } 159 160 if (moduleSpecification.RequiredVersion is not null) 161 { 162 parameters.Add(Parameters.RequiredVersion, moduleSpecification.RequiredVersion); 163 } 164 165 _ = pwsh.AddCommand(Commands.SaveModule) 166 .AddParameters(parameters) 167 .AddParameter(Parameters.Force) 168 .Invoke(); 169 } 170 171 /// <inheritdoc/> 172 public void SaveModule( 173 PowerShell pwsh, 174 PSObject inputObject, 175 string location) 176 { 177 _ = pwsh.AddCommand(Commands.SaveModule) 178 .AddParameter(Parameters.Path, location) 179 .AddParameter(Parameters.InputObject, inputObject) 180 .AddParameter(Parameters.Force) 181 .Invoke(); 182 } 183 184 /// <inheritdoc/> 185 public void InstallModule( 186 PowerShell pwsh, 187 PSObject inputObject, 188 bool allUsers) 189 { 190 var parameters = new Dictionary<string, object>() 191 { 192 { Parameters.InputObject, inputObject }, 193 }; 194 195 if (allUsers) 196 { 197 parameters.Add(Parameters.Scope, AllUsers); 198 } 199 200 // If the repository is untrusted, it will fail with: 201 // Microsoft.PowerShell.Commands.WriteErrorException : Exception calling "ShouldContinue" with "5" 202 // argument(s): "A command that prompts the user failed because the host program or the command type 203 // does not support user interaction. 204 // If its trusted, PowerShellGets adds the Force parameter to the call to PackageManager\Install-Package. 205 // TODO: Once we have policies, we should remove Force. For hosted environments and depending 206 // on the policy we will trust PSGallery when we create the Runspace or add Force here. 207 _ = pwsh.AddCommand(Commands.InstallModule) 208 .AddParameters(parameters) 209 .AddParameter(Parameters.Force) 210 .Invoke(); 211 } 212 213 /// <inheritdoc/> 214 public void InstallModule( 215 PowerShell pwsh, 216 ModuleSpecification moduleSpecification, 217 bool allUsers) 218 { 219 var parameters = new Dictionary<string, object>() 220 { 221 { Parameters.Name, moduleSpecification.Name }, 222 }; 223 224 if (moduleSpecification.Version is not null) 225 { 226 parameters.Add(Parameters.MinimumVersion, moduleSpecification.Version); 227 } 228 229 if (moduleSpecification.MaximumVersion is not null) 230 { 231 parameters.Add(Parameters.MaximumVersion, moduleSpecification.MaximumVersion); 232 } 233 234 if (moduleSpecification.RequiredVersion is not null) 235 { 236 parameters.Add(Parameters.RequiredVersion, moduleSpecification.RequiredVersion); 237 } 238 239 if (allUsers) 240 { 241 parameters.Add(Parameters.Scope, AllUsers); 242 } 243 244 _ = pwsh.AddCommand(Commands.InstallModule) 245 .AddParameters(parameters) 246 .AddParameter(Parameters.Force) 247 .Invoke(); 248 } 249 } 250 }