|
19 | 19 | using System.Management.Automation.Language; |
20 | 20 | using System.Globalization; |
21 | 21 | using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; |
| 22 | +using System.Management.Automation.Runspaces; |
22 | 23 |
|
23 | 24 | namespace Microsoft.Windows.PowerShell.ScriptAnalyzer |
24 | 25 | { |
@@ -104,14 +105,14 @@ internal set |
104 | 105 | private string[] functionScopes = new string[] { "global:", "local:", "script:", "private:"}; |
105 | 106 |
|
106 | 107 | private string[] variableScopes = new string[] { "global:", "local:", "script:", "private:", "variable:", ":"}; |
107 | | - |
108 | 108 | #endregion |
109 | 109 |
|
110 | 110 | /// <summary> |
111 | 111 | /// Initializes the Helper class. |
112 | 112 | /// </summary> |
113 | 113 | private Helper() |
114 | 114 | { |
| 115 | + |
115 | 116 | } |
116 | 117 |
|
117 | 118 | /// <summary> |
@@ -229,6 +230,61 @@ public bool IsDscResourceModule(string filePath) |
229 | 230 |
|
230 | 231 | return false; |
231 | 232 | } |
| 233 | + |
| 234 | + /// <summary> |
| 235 | + /// Gets the module manifest |
| 236 | + /// </summary> |
| 237 | + /// <param name="filePath"></param> |
| 238 | + /// <param name="errorRecord"></param> |
| 239 | + /// <returns>Returns a object of type PSModuleInfo</returns> |
| 240 | + public PSModuleInfo GetModuleManifest(string filePath, out IEnumerable<ErrorRecord> errorRecord) |
| 241 | + { |
| 242 | + errorRecord = null; |
| 243 | + PSModuleInfo psModuleInfo = null; |
| 244 | + Collection<PSObject> psObj = null; |
| 245 | + var ps = System.Management.Automation.PowerShell.Create(); |
| 246 | + try |
| 247 | + { |
| 248 | + ps.AddCommand("Test-ModuleManifest"); |
| 249 | + ps.AddParameter("Path", filePath); |
| 250 | + ps.AddParameter("WarningAction", ActionPreference.SilentlyContinue); |
| 251 | + psObj = ps.Invoke(); |
| 252 | + } |
| 253 | + catch (CmdletInvocationException e) |
| 254 | + { |
| 255 | + // Invoking Test-ModuleManifest on a module manifest that doesn't have all the valid keys |
| 256 | + // throws a NullReferenceException. This is probably a bug in Test-ModuleManifest and hence |
| 257 | + // we consume it to allow execution of the of this method. |
| 258 | + if (e.InnerException == null || e.InnerException.GetType() != typeof(System.NullReferenceException)) |
| 259 | + { |
| 260 | + throw; |
| 261 | + } |
| 262 | + } |
| 263 | + if (ps.HadErrors && ps.Streams != null && ps.Streams.Error != null) |
| 264 | + { |
| 265 | + var errorRecordArr = new ErrorRecord[ps.Streams.Error.Count]; |
| 266 | + ps.Streams.Error.CopyTo(errorRecordArr, 0); |
| 267 | + errorRecord = errorRecordArr; |
| 268 | + } |
| 269 | + if (psObj != null && psObj.Any() && psObj[0] != null) |
| 270 | + { |
| 271 | + psModuleInfo = psObj[0].ImmediateBaseObject as PSModuleInfo; |
| 272 | + } |
| 273 | + ps.Dispose(); |
| 274 | + return psModuleInfo; |
| 275 | + } |
| 276 | + |
| 277 | + /// <summary> |
| 278 | + /// Checks if the error record is MissingMemberException |
| 279 | + /// </summary> |
| 280 | + /// <param name="errorRecord"></param> |
| 281 | + /// <returns>Returns a boolean value indicating the presence of MissingMemberException</returns> |
| 282 | + public static bool IsMissingManifestMemberException(ErrorRecord errorRecord) |
| 283 | + { |
| 284 | + return errorRecord.CategoryInfo != null |
| 285 | + && errorRecord.CategoryInfo.Category == ErrorCategory.ResourceUnavailable |
| 286 | + && string.Equals("MissingMemberException", errorRecord.CategoryInfo.Reason, StringComparison.OrdinalIgnoreCase); |
| 287 | + } |
232 | 288 |
|
233 | 289 | /// <summary> |
234 | 290 | /// Get the list of exported function by analyzing the ast |
@@ -1328,7 +1384,7 @@ public static string[] ProcessCustomRulePaths(string[] rulePaths, SessionState s |
1328 | 1384 | return outPaths.ToArray(); |
1329 | 1385 |
|
1330 | 1386 | } |
1331 | | - |
| 1387 | + |
1332 | 1388 | /// <summary> |
1333 | 1389 | /// Check if the function name starts with one of potentailly state changing verbs |
1334 | 1390 | /// </summary> |
@@ -1458,7 +1514,7 @@ public bool GetNamedArgumentAttributeValue(NamedAttributeArgumentAst namedAttrib |
1458 | 1514 | return false; |
1459 | 1515 | } |
1460 | 1516 |
|
1461 | | - #endregion |
| 1517 | + #endregion Methods |
1462 | 1518 | } |
1463 | 1519 |
|
1464 | 1520 |
|
|
0 commit comments