From cafc4fe1d060eac70b4f157d63f3cfb5716a94dc Mon Sep 17 00:00:00 2001 From: Sergei Vorobev Date: Mon, 20 Jun 2016 15:15:48 -0700 Subject: [PATCH 1/5] Add ControlPanelItemCommand.cs into map.json and exclude from build --- src/Microsoft.PowerShell.Commands.Management/map.json | 1 + src/Microsoft.PowerShell.Commands.Management/project.json | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/Microsoft.PowerShell.Commands.Management/map.json b/src/Microsoft.PowerShell.Commands.Management/map.json index 7d4e51d0e..3e0402ac7 100644 --- a/src/Microsoft.PowerShell.Commands.Management/map.json +++ b/src/Microsoft.PowerShell.Commands.Management/map.json @@ -33,6 +33,7 @@ "monad/src/commands/management/GetComputerInfoCommand.cs": "commands/management/GetComputerInfoCommand.cs", "monad/src/singleshell/installer/MshManagementMshSnapin.cs": "singleshell/installer/MshManagementMshSnapin.cs", "monad/src/commands/management/CommandsCommon.cs": "commands/management/CommandsCommon.cs", + "monad/src/commands/management/ControlPanelItemCommand.cs": "commands/management/ControlPanelItemCommand.cs", "monad/src/commands/management/PassThroughContentCommandBase.cs": "commands/management/PassThroughContentCommandBase.cs", "monad/src/commands/management/PassThroughPropertyCommandBase.cs": "commands/management/PassThroughPropertyCommandBase.cs", "monad/src/commands/management/resources/ClearRecycleBinResources.resx": "resources/ClearRecycleBinResources.resx", diff --git a/src/Microsoft.PowerShell.Commands.Management/project.json b/src/Microsoft.PowerShell.Commands.Management/project.json index b44842321..9c0b63c2a 100644 --- a/src/Microsoft.PowerShell.Commands.Management/project.json +++ b/src/Microsoft.PowerShell.Commands.Management/project.json @@ -22,6 +22,7 @@ "compile": { "exclude": [ "commands/management/ClearRecycleBinCommand.cs", + "commands/management/ControlPanelItemCommand.cs", "commands/management/CommitTransactionCommand.cs", "commands/management/Computer.cs", "commands/management/Eventlog.cs", @@ -57,6 +58,13 @@ }, "dependencies": { "Microsoft.WSMan.Management": "1.0.0" + }, + "buildOptions": { + "compile": { + "exclude": [ + "commands/management/ControlPanelItemCommand.cs" + ] + } } } } From 5f87828710128cfa079e4fda52041f3fb87d164b Mon Sep 17 00:00:00 2001 From: PowerShell Team Date: Mon, 20 Jun 2016 15:19:20 -0700 Subject: [PATCH 2/5] Copy ControlPanelItemCommand.cs from [SD:715912] commit 77eda78 --- .../management/ControlPanelItemCommand.cs | 769 ++++++++++++++++++ 1 file changed, 769 insertions(+) create mode 100644 src/Microsoft.PowerShell.Commands.Management/commands/management/ControlPanelItemCommand.cs diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ControlPanelItemCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ControlPanelItemCommand.cs new file mode 100644 index 000000000..5e39e9d6f --- /dev/null +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ControlPanelItemCommand.cs @@ -0,0 +1,769 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using Microsoft.Win32; +using Shell32; +using System; +using System.Management.Automation; +using System.Management.Automation.Internal; +using System.Collections.Generic; +using Dbg = System.Management.Automation.Diagnostics; + +namespace Microsoft.PowerShell.Commands +{ + /// + /// Represent a control panel item + /// + public sealed class ControlPanelItem + { + /// + /// Control panel applet name + /// + public string Name + { + get { return _name; } + } + private string _name; + + /// + /// Control panel applet canonical name + /// + public string CanonicalName + { + get { return _canonicalName; } + } + private string _canonicalName; + + /// + /// Control panel applet category + /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public string[] Category + { + get { return _category; } + } + private string[] _category; + + /// + /// Control panel applet description + /// + public string Description + { + get { return _description; } + } + private string _description; + + /// + /// Control panel applet path + /// + internal string Path + { + get { return _path; } + } + private string _path; + + /// + /// Internal constructor for ControlPanelItem + /// + /// + /// + /// + /// + /// + internal ControlPanelItem(string name, string canonicalName, string[] category, string description, string path) + { + _name = name; + _path = path; + _canonicalName = canonicalName; + _category = category; + _description = description; + } + + /// + /// ToString method + /// + /// + public override string ToString() + { + return this.Name; + } + } + + /// + /// This class implements the base for ControlPanelItem commands + /// + public abstract class ControlPanelItemBaseCommand : PSCmdlet + { + /// + /// Locale specific verb action Open string exposed by the control panel item. + /// + private static string VerbActionOpenName = null; + + /// + /// Canonical name of the control panel item used as a refernece to fetch the verb + /// action Open string. This control panel item exists on all SKU's. + /// + private const string RegionCanonicalName = "Microsoft.RegionAndLanguage"; + + private const string ControlPanelShellFolder = "shell:::{26EE0668-A00A-44D7-9371-BEB064C98683}"; + private static readonly string[] ControlPanelItemFilterList = new string[] { "Folder Options", "Taskbar and Start Menu" }; + private const string TestHeadlessServerScript = @" +$result = $false +$serverManagerModule = Get-Module -ListAvailable | ? {$_.Name -eq 'ServerManager'} +if ($serverManagerModule -ne $null) +{ + Import-Module ServerManager + $Gui = (Get-WindowsFeature Server-Gui-Shell).Installed + if ($Gui -eq $false) + { + $result = $true + } +} +$result +"; + internal readonly Dictionary CategoryMap = new Dictionary(StringComparer.OrdinalIgnoreCase); + + internal string[] CategoryNames = { "*" }; + internal string[] RegularNames = { "*" }; + internal string[] CanonicalNames = { "*" }; + internal ControlPanelItem[] ControlPanelItems = new ControlPanelItem[0]; + + /// + /// Get all executable control panel items + /// + internal List AllControlPanelItems + { + get + { + if (_allControlPanelItems == null) + { + _allControlPanelItems = new List(); + string allItemFolderPath = ControlPanelShellFolder + "\\0"; + IShellDispatch4 shell2 = (IShellDispatch4)new Shell(); + Folder2 allItemFolder = (Folder2)shell2.NameSpace(allItemFolderPath); + FolderItems3 allItems = (FolderItems3)allItemFolder.Items(); + + bool applyControlPanelItemFilterList = IsServerCoreOrHeadLessServer(); + + foreach (ShellFolderItem item in allItems) + { + if (applyControlPanelItemFilterList) + { + bool match = false; + foreach (string name in ControlPanelItemFilterList) + { + if (name.Equals(item.Name, StringComparison.OrdinalIgnoreCase)) + { + match = true; + break; + } + } + if (match) + continue; + } + + if (ContainVerbOpen(item)) + _allControlPanelItems.Add(item); + } + } + return _allControlPanelItems; + } + } + private List _allControlPanelItems; + + #region Cmdlet Overrides + + /// + /// Does the preprocessing for ControlPanelItem cmdlets + /// + protected override void BeginProcessing() + { + System.OperatingSystem osInfo = System.Environment.OSVersion; + PlatformID platform = osInfo.Platform; + Version version = osInfo.Version; + + if (platform.Equals(PlatformID.Win32NT) && + ((version.Major < 6) || + ((version.Major == 6) && (version.Minor < 2)) + )) + { + // Below Win8, this cmdlet is not supported because of Win8:794135 + // throw terminating + string message = string.Format(CultureInfo.InvariantCulture, + ControlPanelResources.ControlPanelItemCmdletNotSupported, + this.CommandInfo.Name); + throw new PSNotSupportedException(message); + } + } + + #endregion + + /// + /// Test if an item can be invoked + /// + /// + /// + private bool ContainVerbOpen(ShellFolderItem item) + { + bool result = false; + FolderItemVerbs verbs = item.Verbs(); + foreach (FolderItemVerb verb in verbs) + { + if (!String.IsNullOrEmpty(verb.Name) && + (verb.Name.Equals(ControlPanelResources.VerbActionOpen, StringComparison.OrdinalIgnoreCase) || + CompareVerbActionOpen(verb.Name))) + { + result = true; + break; + } + } + return result; + } + + /// + /// CompareVerbActionOpen is a helper function used to perform locale specific + /// comparision of the verb action Open exposed by various control panel items. + /// + /// Locale spcific verb action exposed by the control panel item. + /// True if the control panel item supports verb action open or else returns false. + private static bool CompareVerbActionOpen(string verbActionName) + { + if (VerbActionOpenName == null) + { + const string allItemFolderPath = ControlPanelShellFolder + "\\0"; + IShellDispatch4 shell2 = (IShellDispatch4)new Shell(); + Folder2 allItemFolder = (Folder2)shell2.NameSpace(allItemFolderPath); + FolderItems3 allItems = (FolderItems3)allItemFolder.Items(); + + foreach (ShellFolderItem item in allItems) + { + string canonicalName = (string)item.ExtendedProperty("System.ApplicationName"); + canonicalName = !String.IsNullOrEmpty(canonicalName) + ? canonicalName.Substring(0, canonicalName.IndexOf("\0", StringComparison.OrdinalIgnoreCase)) + : null; + + if (canonicalName != null && canonicalName.Equals(RegionCanonicalName, StringComparison.OrdinalIgnoreCase)) + { + // The 'Region' control panel item always has '&Open' (english or other locale) as the first verb name + VerbActionOpenName = item.Verbs().Item(0).Name; + break; + } + } + + Dbg.Assert(VerbActionOpenName != null, "The 'Region' control panel item is available on all SKUs and it always " + + "has '&Open' as the first verb item, so VerbActionOpenName should never be null at this point"); + } + + return VerbActionOpenName.Equals(verbActionName, StringComparison.OrdinalIgnoreCase); + } + + /// + /// IsServerCoreORHeadLessServer is a helper function that checks if the current SKU is a + /// Server Core machine or if the Server-GUI-Shell feature is removed on the machine. + /// + /// True if the current SKU is a Server Core machine or if the Server-GUI-Shell + /// feature is removed on the machine or else returns false. + private bool IsServerCoreOrHeadLessServer() + { + bool result = false; + + using (RegistryKey installation = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion")) + { + Dbg.Assert(installation != null, "the CurrentVersion subkey should exist"); + + string installationType = (string)installation.GetValue("InstallationType", ""); + + if (installationType.Equals("Server Core")) + { + result = true; + } + else if (installationType.Equals("Server")) + { + using (System.Management.Automation.PowerShell ps = System.Management.Automation.PowerShell.Create()) + { + ps.AddScript(TestHeadlessServerScript); + Collection psObjectCollection = ps.Invoke(new object[0]); + Dbg.Assert(psObjectCollection != null && psObjectCollection.Count == 1, "invoke should never return null, there should be only one return item"); + if (LanguagePrimitives.IsTrue(PSObject.Base(psObjectCollection[0]))) + { + result = true; + } + } + } + } + + return result; + } + + /// + /// Get the category number and name map + /// + internal void GetCategoryMap() + { + if (CategoryMap.Count != 0) + { + return; + } + + IShellDispatch4 shell2 = (IShellDispatch4)new Shell(); + Folder2 categoryFolder = (Folder2)shell2.NameSpace(ControlPanelShellFolder); + FolderItems3 catItems = (FolderItems3)categoryFolder.Items(); + + foreach (ShellFolderItem category in catItems) + { + string path = category.Path; + string catNum = path.Substring(path.LastIndexOf("\\", StringComparison.OrdinalIgnoreCase) + 1); + + CategoryMap.Add(catNum, category.Name); + } + } + + /// + /// Get control panel item by the category + /// + /// + /// + internal List GetControlPanelItemByCategory(List controlPanelItems) + { + List list = new List(); + HashSet itemSet = new HashSet(StringComparer.OrdinalIgnoreCase); + + foreach (string pattern in CategoryNames) + { + bool found = false; + WildcardPattern wildcard = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase); + foreach (ShellFolderItem item in controlPanelItems) + { + string path = item.Path; + int[] categories = (int[])item.ExtendedProperty("System.ControlPanel.Category"); + foreach (int cat in categories) + { + string catStr = (string)LanguagePrimitives.ConvertTo(cat, typeof (string), CultureInfo.InvariantCulture); + Dbg.Assert(CategoryMap.ContainsKey(catStr), "the category should be contained in _categoryMap"); + string catName = CategoryMap[catStr]; + + if (!wildcard.IsMatch(catName)) + continue; + if (itemSet.Contains(path)) + { + found = true; + break; + } + + found = true; + itemSet.Add(path); + list.Add(item); + break; + } + } + + if (!found && !WildcardPattern.ContainsWildcardCharacters(pattern)) + { + string errMsg = StringUtil.Format(ControlPanelResources.NoControlPanelItemFoundForGivenCategory, pattern); + ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), + "NoControlPanelItemFoundForGivenCategory", + ErrorCategory.InvalidArgument, pattern); + WriteError(error); + } + } + + return list; + } + + /// + /// Get control panel item by the regular name + /// + /// + /// + /// + internal List GetControlPanelItemByName(List controlPanelItems, bool withCategoryFilter) + { + List list = new List(); + HashSet itemSet = new HashSet(StringComparer.OrdinalIgnoreCase); + + foreach (string pattern in RegularNames) + { + bool found = false; + WildcardPattern wildcard = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase); + foreach (ShellFolderItem item in controlPanelItems) + { + string name = item.Name; + string path = item.Path; + if (!wildcard.IsMatch(name)) + continue; + if (itemSet.Contains(path)) + { + found = true; + continue; + } + + found = true; + itemSet.Add(path); + list.Add(item); + } + + if (!found && !WildcardPattern.ContainsWildcardCharacters(pattern)) + { + string formatString = withCategoryFilter + ? ControlPanelResources.NoControlPanelItemFoundForGivenNameWithCategory + : ControlPanelResources.NoControlPanelItemFoundForGivenName; + string errMsg = StringUtil.Format(formatString, pattern); + ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), + "NoControlPanelItemFoundForGivenName", + ErrorCategory.InvalidArgument, pattern); + WriteError(error); + } + } + + return list; + } + + /// + /// Get control panel item by the canonical name + /// + /// + /// + /// + internal List GetControlPanelItemByCanonicalName(List controlPanelItems, bool withCategoryFilter) + { + List list = new List(); + HashSet itemSet = new HashSet(StringComparer.OrdinalIgnoreCase); + + if (CanonicalNames == null) + { + bool found = false; + foreach (ShellFolderItem item in controlPanelItems) + { + string canonicalName = (string)item.ExtendedProperty("System.ApplicationName"); + if (canonicalName == null) + { + found = true; + list.Add(item); + } + } + + if (!found) + { + string errMsg = withCategoryFilter + ? ControlPanelResources.NoControlPanelItemFoundWithNullCanonicalNameWithCategory + : ControlPanelResources.NoControlPanelItemFoundWithNullCanonicalName; + ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "", + ErrorCategory.InvalidArgument, CanonicalNames); + WriteError(error); + } + return list; + } + + foreach (string pattern in CanonicalNames) + { + bool found = false; + WildcardPattern wildcard = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase); + foreach (ShellFolderItem item in controlPanelItems) + { + string path = item.Path; + string canonicalName = (string)item.ExtendedProperty("System.ApplicationName"); + canonicalName = canonicalName != null + ? canonicalName.Substring(0, canonicalName.IndexOf("\0", StringComparison.OrdinalIgnoreCase)) + : null; + + if (canonicalName == null) + { + if (pattern.Equals("*", StringComparison.OrdinalIgnoreCase)) + { + found = true; + if (!itemSet.Contains(path)) + { + itemSet.Add(path); + list.Add(item); + } + } + } + else + { + if (!wildcard.IsMatch(canonicalName)) + continue; + if (itemSet.Contains(path)) + { + found = true; + continue; + } + + found = true; + itemSet.Add(path); + list.Add(item); + } + } + + if (!found && !WildcardPattern.ContainsWildcardCharacters(pattern)) + { + string formatString = withCategoryFilter + ? ControlPanelResources.NoControlPanelItemFoundForGivenCanonicalNameWithCategory + : ControlPanelResources.NoControlPanelItemFoundForGivenCanonicalName; + string errMsg = StringUtil.Format(formatString, pattern); + ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), + "NoControlPanelItemFoundForGivenCanonicalName", + ErrorCategory.InvalidArgument, pattern); + WriteError(error); + } + } + + return list; + } + + /// + /// Get control panel item by the ControlPanelItem instances + /// + /// + /// + internal List GetControlPanelItemsByInstance(List controlPanelItems) + { + List list = new List(); + HashSet itemSet = new HashSet(StringComparer.OrdinalIgnoreCase); + + foreach (ControlPanelItem controlPanelItem in ControlPanelItems) + { + bool found = false; + + foreach (ShellFolderItem item in controlPanelItems) + { + string path = item.Path; + if (!controlPanelItem.Path.Equals(path, StringComparison.OrdinalIgnoreCase)) + continue; + if (itemSet.Contains(path)) + { + found = true; + break; + } + + found = true; + itemSet.Add(path); + list.Add(item); + break; + } + + if (!found) + { + string errMsg = StringUtil.Format(ControlPanelResources.NoControlPanelItemFoundForGivenInstance, + controlPanelItem.GetType().Name); + ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), + "NoControlPanelItemFoundForGivenInstance", + ErrorCategory.InvalidArgument, controlPanelItem); + WriteError(error); + } + } + + return list; + } + } + + /// + /// Get all control panel items that is available in the "All Control Panel Items" category + /// + [Cmdlet(VerbsCommon.Get, "ControlPanelItem", DefaultParameterSetName = RegularNameParameterSet, HelpUri = "http://go.microsoft.com/fwlink/?LinkID=219982")] + [OutputType(typeof(ControlPanelItem))] + public sealed class GetControlPanelItemCommand : ControlPanelItemBaseCommand + { + private const string RegularNameParameterSet = "RegularName"; + private const string CanonicalNameParameterSet = "CanonicalName"; + + #region "Parameters" + + /// + /// Control panel item names + /// + [Parameter(Position = 0, ParameterSetName = RegularNameParameterSet, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public string[] Name + { + get { return RegularNames; } + set + { + RegularNames = value; + _nameSpecified = true; + } + } + private bool _nameSpecified = false; + + /// + /// Canonical names of control panel items + /// + [Parameter(Mandatory = true, ParameterSetName = CanonicalNameParameterSet)] + [AllowNull] + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public string[] CanonicalName + { + get { return CanonicalNames; } + set + { + CanonicalNames = value; + _canonicalNameSpecified = true; + } + } + private bool _canonicalNameSpecified = false; + + /// + /// Category of control panel items + /// + [Parameter] + [ValidateNotNullOrEmpty] + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public string[] Category + { + get { return CategoryNames; } + set + { + CategoryNames = value; + _categorySpecified = true; + } + } + private bool _categorySpecified = false; + + #endregion "Parameters" + + /// + /// + /// + protected override void ProcessRecord() + { + GetCategoryMap(); + List items = GetControlPanelItemByCategory(AllControlPanelItems); + + if (_nameSpecified) + { + items = GetControlPanelItemByName(items, _categorySpecified); + } + else if (_canonicalNameSpecified) + { + items = GetControlPanelItemByCanonicalName(items, _categorySpecified); + } + + List results = new List(); + foreach (ShellFolderItem item in items) + { + string name = item.Name; + string path = item.Path; + string description = (string)item.ExtendedProperty("InfoTip"); + string canonicalName = (string)item.ExtendedProperty("System.ApplicationName"); + canonicalName = canonicalName != null + ? canonicalName.Substring(0, canonicalName.IndexOf("\0", StringComparison.OrdinalIgnoreCase)) + : null; + int[] categories = (int[])item.ExtendedProperty("System.ControlPanel.Category"); + string[] cateStrings = new string[categories.Length]; + for (int i = 0; i < categories.Length; i++) + { + string catStr = (string)LanguagePrimitives.ConvertTo(categories[i], typeof(string), CultureInfo.InvariantCulture); + Dbg.Assert(CategoryMap.ContainsKey(catStr), "the category should be contained in CategoryMap"); + cateStrings[i] = CategoryMap[catStr]; + } + + ControlPanelItem controlPanelItem = new ControlPanelItem(name, canonicalName, cateStrings, description, path); + results.Add(controlPanelItem); + } + + // Sort the reuslts by Canonical Name + results.Sort(CompareControlPanelItems); + foreach (ControlPanelItem controlPanelItem in results) + { + WriteObject(controlPanelItem); + } + } + + #region "Private Methods" + + private static int CompareControlPanelItems(ControlPanelItem x, ControlPanelItem y) + { + // In the case that at least one of them is null + if (x.CanonicalName == null && y.CanonicalName == null) + return 0; + if (x.CanonicalName == null) + return 1; + if (y.CanonicalName == null) + return -1; + + // In the case that both are not null + return string.Compare(x.CanonicalName, y.CanonicalName, StringComparison.OrdinalIgnoreCase); + } + + #endregion "Private Methods" + } + + /// + /// Show the specified control panel applet + /// + [Cmdlet(VerbsCommon.Show, "ControlPanelItem", DefaultParameterSetName = RegularNameParameterSet, HelpUri = "http://go.microsoft.com/fwlink/?LinkID=219983")] + public sealed class ShowControlPanelItemCommand : ControlPanelItemBaseCommand + { + private const string RegularNameParameterSet = "RegularName"; + private const string CanonicalNameParameterSet = "CanonicalName"; + private const string ControlPanelItemParameterSet = "ControlPanelItem"; + + #region "Parameters" + + /// + /// Control panel item names + /// + [Parameter(Position = 0, Mandatory = true, ParameterSetName = RegularNameParameterSet, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public string[] Name + { + get { return RegularNames; } + set { RegularNames = value; } + } + + /// + /// Canonical names of control panel items + /// + [Parameter(Mandatory = true, ParameterSetName = CanonicalNameParameterSet)] + [AllowNull] + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public string[] CanonicalName + { + get { return CanonicalNames; } + set { CanonicalNames = value; } + } + + /// + /// Control panel items returned by Get-ControlPanelItem + /// + [Parameter(Position = 0, ParameterSetName = ControlPanelItemParameterSet, ValueFromPipeline = true)] + [ValidateNotNullOrEmpty] + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public ControlPanelItem[] InputObject + { + get { return ControlPanelItems; } + set { ControlPanelItems = value; } + } + + #endregion "Parameters" + + /// + /// + /// + protected override void ProcessRecord() + { + List items; + if (ParameterSetName == RegularNameParameterSet) + { + items = GetControlPanelItemByName(AllControlPanelItems, false); + } + else if (ParameterSetName == CanonicalNameParameterSet) + { + items = GetControlPanelItemByCanonicalName(AllControlPanelItems, false); + } + else + { + items = GetControlPanelItemsByInstance(AllControlPanelItems); + } + + foreach (ShellFolderItem item in items) + { + item.InvokeVerb(); + } + } + } +} From f4ff460b9f598a2f886e7f69eb6b509069107763 Mon Sep 17 00:00:00 2001 From: Sergei Vorobev Date: Mon, 20 Jun 2016 17:22:54 -0700 Subject: [PATCH 3/5] Add OdataUtils to map.json --- src/Modules/map.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Modules/map.json b/src/Modules/map.json index f42e2a356..c3b277a68 100644 --- a/src/Modules/map.json +++ b/src/Modules/map.json @@ -20,5 +20,11 @@ "monad/src/LocalAccounts/LocalAccounts.format.ps1xml": "Microsoft.PowerShell.LocalAccounts/LocalAccounts.format.ps1xml", "monad/src/oneget/PowerShell.Module/PackageManagement.psd1": "PackageManagement/PackageManagement.psd1", "monad/src/oneget/PowerShell.Module/PackageManagement.format.ps1xml": "PackageManagement/PackageManagement.format.ps1xml", - "monad/src/oneget/providers/inbox/powershell.metaprovider/PackageProviderFunctions.psm1": "PackageManagement/PackageProviderFunctions.psm1" + "monad/src/oneget/providers/inbox/powershell.metaprovider/PackageProviderFunctions.psm1": "PackageManagement/PackageProviderFunctions.psm1", + "wmi/psws/PSODataUtils/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataAdapter.ps1": "Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataAdapter.ps1", + "wmi/psws/PSODataUtils/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psd1": "Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psd1", + "wmi/psws/PSODataUtils/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psm1": "Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psm1", + "wmi/psws/PSODataUtils/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtilsHelper.ps1": "Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtilsHelper.ps1", + "wmi/psws/PSODataUtils/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataV4Adapter.ps1": "Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataV4Adapter.ps1", + "wmi/psws/PSODataUtils/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtilsStrings.psd1": "Microsoft.PowerShell.ODataUtils/en-US/Microsoft.PowerShell.ODataUtilsStrings.psd1" } From 5790595da302a7e0f4bf5b9c7c202884f97888ce Mon Sep 17 00:00:00 2001 From: PowerShell Team Date: Mon, 20 Jun 2016 17:23:37 -0700 Subject: [PATCH 4/5] Copy Microsoft.PowerShell.ODataUtils from [SD:715912] commit 570d318 --- .../Microsoft.PowerShell.ODataAdapter.ps1 | Bin 0 -> 171100 bytes .../Microsoft.PowerShell.ODataUtils.psd1 | Bin 0 -> 24980 bytes .../Microsoft.PowerShell.ODataUtils.psm1 | Bin 0 -> 20362 bytes .../Microsoft.PowerShell.ODataUtilsHelper.ps1 | Bin 0 -> 51530 bytes .../Microsoft.PowerShell.ODataV4Adapter.ps1 | 2668 +++++++++++++++++ ...icrosoft.PowerShell.ODataUtilsStrings.psd1 | Bin 0 -> 12018 bytes 6 files changed, 2668 insertions(+) create mode 100644 src/Modules/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataAdapter.ps1 create mode 100644 src/Modules/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psd1 create mode 100644 src/Modules/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psm1 create mode 100644 src/Modules/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtilsHelper.ps1 create mode 100644 src/Modules/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataV4Adapter.ps1 create mode 100644 src/Modules/Microsoft.PowerShell.ODataUtils/en-US/Microsoft.PowerShell.ODataUtilsStrings.psd1 diff --git a/src/Modules/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataAdapter.ps1 b/src/Modules/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataAdapter.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..c5db4047d39bde4811e7c8450228d2dbb0928495 GIT binary patch literal 171100 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 literal 0 HcmV?d00001 diff --git a/src/Modules/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psd1 b/src/Modules/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psd1 new file mode 100644 index 0000000000000000000000000000000000000000..7f85bb3ae794c73d11cfbc4c7f2ccdddb0e78461 GIT binary patch literal 24980 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 literal 0 HcmV?d00001 diff --git a/src/Modules/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psm1 b/src/Modules/Microsoft.PowerShell.ODataUtils/Microsoft.PowerShell.ODataUtils.psm1 new file mode 100644 index 0000000000000000000000000000000000000000..685e4786aac9455f9ccec0f91313ebe4cf7204ab GIT binary patch literal 20362 zcmeI4Yi}FJ6^8d~3-mv*lmN?UNLzO7CIO7bw(LY`WE;K~aE(HiEQPUd5oyb6kiXvc zedh3RW|yD_6()+_Gojvd|cKx21x>=bJ{vmvz?)h`}S zW_hMjz!~cLNTUYDUa_rTec?D1Hp|7Iia$=?3!3Gr;0$!FqgnSg;$6U^qi_3yKh*t~ z1gWEM?*zjs?G(2KeOKpSYZMf}(+IEzQ?736)f4n%-NX3}jou8fM`8X&(E@E7VHPMn z3@|qWKBEA2B&dhs?puPeRD7rJaQTH`4Mg?p;-~Srj?Vt9(QxKiW4ods?tmNEgKZx2 zmagmvN?rtRT`#T`|H|OjEiQ|Tb#R=kaP+F);QOKYs<;_w{_uZ=ual+uZ_>& z7PbeXeSLD}`uIwe`J>|Qhp zt)*fzAdn6vE8iy?*Wwfg+IY4zc z%=>Hj1do2W1}#tY!gdDY=}2Su1H^xx(5Ai*I)y$TjxB0=jDzuiK{7bcmrEVH*b7+U zYp~jmcrfiLsy4o%F?+gWJ!ro93M>`x1w^y^fjEx^`)mh6x*vj_rB=z1BS?H0@ad&5YpU)P38?e?VaDaDMybqsvC&v=JH-n#o9(?A- z$j11!CCc{#g@eHBPH|6u!M$iN@!a<+c$;@LE<-`t#$L)3M1OiG@N+YKZp%+H-mP&( z9NH4!@arRK#d_d55ytqBpBzo1&MkTSyNV|Nkfr>f?_ZQ)l`WDO^P{K&@}?lC-u#v< zpZJ4EF2isedZw!b`N^(ejPyDvzA3KgwJnJK;NPpU4{hDmh%I>*G<2_ct6zT;p7woJ zSlp6NT9yaCDi8OyU|%j?l_+>Aj=u}D@#)cNsdy<`j-^HLWLNXAYFvL3lUFs@mS%r7 z1@B=f-KZexwNg!>ng-kKnz$ygJy@mN<!+q$*UybN4-1PA7{i5os6S5K3k4Hlb81> zFpHy6W+(SgH$MT6#;lb}cs;~B@>SQ`2f_awg~_de=8t7K=y;r`e9be$lf>V@o|}BW7w3l|zg$=C0AI~JqK$MM=q}KI@C=8XiyjBr z)3&gL$~>hp@AEvG{)BmkG?)8IP|hP#4wVx#FMiKxydQK6>YC_imoa^P;S#$mS)s#J z04tIbvAc<`w(_A?xF`wH@!1hYN3ws8ul2(6PlqnD+>6n?NY^vj5q0`Tu(UU0KSyOk z&2RP2=}=2fdLGnPvyyUk(^SvY`6BA!^^n6IidU((vEEvG=8kHo?^K&UQ09}KFZTvK zr}N(4pH(~M^Ie<4$NMo4&98bLW<5^-)mJS|wYDn^sana?uIQbgA;QYzRfgRu{t`01 zE23jp+)DHIOC>%yTt8YT@Q!SYE(|@2YWHKP%D-E~oo?`?w?gfi$1|0I&l$Use#Var zf>hNX?}zOQv$vwn`s`%&X)le{gZCOiT~80~nL3)QI$Gb}JM&z%9ve~5dTa-x+EJW9vx>po7WKIqGReudWsg~a-5%q zHNKS$>oCZBC?2gV%EM`73`X^tj9*3nAMw5ause&|D%VdN!|V(gy;^gZx?Z+8bj`ej4#b zcj40k+=!zmwFzYFQ*_USGtH6e?CUuRk z3DVui+RE#U*5#z@zp49}hcUKZ0AyP)@YO~0gk|V)1rHu}6e01HRzrPhDJX#PDmd1SL{@2p$k6DdC&xxYo%O`!3 zLHHI|ci=W-m_4rRkP&c4)Tb+fKbJIWDabu$g?NaY;@WjxD^uDNPgv1FLKf{T8bY7z z5_jzA7yc4mbRGc9*0+a(&w6goCKojRMYzkg4$ZY#8zU>LEhc&VpzHWi&~ejr&VI~l z&yg@UYFHOxJpw=Pk$qcNU8AA6%Abx#=2pO5)BT9<;y3DJIqS2pg$X?gvWPb!e}cBY zblfF86t8UM&T_u0gy|UIm18&mt{_4a8Uk1G5$0hZ>Wr;oVZp1iz&%|BA|4sfaJeR< zJX!2-j{If)vy7jZvsdMd zd{|dC&~yLk%xz7vbyZZom-kAugT5mCap;2VinqqU{-pb8xw&PzeD97cBqCKVPNnu+ ztq1aTnBjzPrH=gntt;qDk$W}urOf~QUR#`AZLuhgi+eB9HEFUWGJ%oarnygpXJD@% zJsWZkJWl*x4=Ww#`#Y#lZH2{hC!z`#m9r}MkL_@cUJyRTo_q9~i^{XGxUQA-p0ozSu%ato_Gu2*vZ}AzxqAVzphAL_!TO6Dz;gdB8UPgK{-bDWwzxsR&1cF!2*#j8oK%^J}ZmmJ@= zR1pVkJ?Csa=>4%SrTgFA&;FJ@s?!i-MH8jJd(yMX_+9INl^4s|mDyA73jV}au+0CM zHCNYn?KzD)4`t5_PG5aIhK$#$i@cUAhwR~bL=lg@(aJn>_*M>uINRgThi)Vj5t z)Z$ZY&ntJDkHXL2(rwpMy1(~g_7con;m)#ygWwUi^=T_Xca&f895gGDJSptG!&&_> zd%md(ry6CwmT20gN7#2Z6Wc zzKZX~XtS%1^$XU*StF-+YtO8+n#77O6(=*Wo@aTk?MCojAKd*q^ong49QSQ%WPFa% z_rvjgVcZAD-oPBqbdAuJGCjU-y;6c~JM;`Lwd%K_Z3ieKejSJM^>nix;}zKNL2r$ku6cK6 zeJ?ME@hoajtKw*bw^`E1Nd+y6|8{^zvQxtM8|0-moA!RPLpm=x_hd6FBmAzsc3>IZAsV99Z&XzI4w=b6Ho`04$n7|8q?IXoNI^%7g_OhLIwx64< z#&{HW%+8Ogd)+3A$^C7o$ECS3p0(58HKd)5`RI01Y8D~h`4#L0F_My^&fkhAP#_^i$LX#39D&$FYImnIEwXOn3> zsdf>tC|@b&83Fz=1@D>qsCNG#giiFrt_b#BlV=gZn)fZ|`A|M@?5p+be^@6Ca*oam&7e&$9V+0E3SV-p9>W3k7Vz@tK`_VE8QC z5nnXFwC{|<-%Eq{q8<0OeR^V_7R^0_zGwIDHNUg}4{c1x>TUbP!tUVTYs2`lT|2a= zB6S|xSg#GzeVg5@_S2EUISEfkSY?*fax#KaMx2h-e_(ZCJFmRBTN>J zp8l!banS4J_S{{g$;(!njt$z;Oc=j99sP?|_K+<2DGF=+zxL=IG0OD+9)s}Eo?QLuo5t&{B zg3mkNacCN{TtQcJO4i_)-!EK6`Q(>$B|@CT;j-iiZq9+t@EC|W)G~L*XV2CBGkJWk ziW|`q+-+?h9DaT3!<^Tvz;de>rR3zy;|Str=luQ#=e!E6@i})Px;%>0IVGYt=e{JD zfCr{?$3bc~CyT;L$B0psnmP6*$6wl%^jBv#t+zi!N{w5f6veGWE8=gD({t&&94Y$B zr1{8VtvH{u{N+;Qyd`Q)zRAzkK>Ebu4kFG2i!olFMt%>BCgd`=Et`32N2d}Q!>SNJ zF^C?KmSV~B9EUIi5AY>AUmE|wn+&A}H|bZ`D!X^TZ?KN+k9@+ju&zg+<3aDXQ1(va z@V&EaZCcViVM{%Cs%puc1hD&a7`4_4Zr-99yQ> zrDu-W+hDoNc#cE6-n>(UQHI=~#cE?l+8tX2Ojb(<8Lz-4_%a7aVMK-C(73&O7R@Xg za(Inami7MA@=X4;Fsgm}-z^%V(s0;THLy-pGr;4e&FlNlj9rJ`+S#oF=dU+kwXnXm zCzWsAH^|VA5rFuK(Xy+Vn!!iSe^~v4%pVBv*cglEuLC+?%juk7j(usyWonJZ1F|yn zpVVyQll}R`(ewCdTw}aqBRP3n)Sd`?9Nu}@%`c6=cpdDXdo*P5mU$_+_gHA;W!=cH zD`}DDqEVzqE-?$s_;XD0LHj-VjZo)s@}A8RAAqmJ8_l(y5!aiiUK}c}juY}ZRmu6P z`T3f-mbIXUBXcw_)!N1@T{Yvnr#m*%ArF4@E}NcGYzK3?-#%k>&aQ3{C< zhV;d?wf_EY^i!TmS5B$5M#+t{n4<$V@}}4l>OEUi^57%BH)33#chs+8uFaWm9>YtP z(Wiw~`(uQ!tI8eMwGQ~;J(Iqgnb&XytX|LGjQsQgMQ3u743WO zNy&ngYfwjjc@~T1&%X^4r*R_Gh_$TSP_$hG<7OK()$*%6exy^)sG@Vtlha&3v3L&( z@1N4SR$98xb!GOirYUeJ=ThWH&gER=JZs*Z|N0?tIG?}x>lR1fBDd#Svu`a2A`^aL zl?{Aj&Xv`5C*o8iyD9sK&#p2bQD!r9`5{P2v>?B0wH9tZw~WoLq-YYUTjorPeOTrE z%%JR<=kDrp`B~((D^qScaw+S=n#1KhQvPw-g2?5Z4mDiOElIMZF>0x=OG=))S(@{@ zUs+m*WuV)Nnn@OkW1(!yrGQE9S^}A}OeW(wB+zkd^)@oAClQ zGmNyJLz~3o@mzO~os4-T)sH)^7CkrKQLEkzUCzTht~bl|=Jh+1>%&f#H3uKO9JK;^ z#W;GbMt0b}qU>lczDt9f`m0jkl&?>*BGIoQm3?)DRGN9sbKQBZ3TIx<)R%6zCjIkW z&r>re>UvL&dvy05hn2fn4I;);zF1=+`t}$3aLoJHz+Bksm`jV!#q24EBO6p6MOW)6 zG@Nfc{=?VLV;=C~McV~((7ZYGLv=G5r;w=PGC=g4cZ=3?nHX4*5`Xivb-3nHUgBbY zwhm4=c1W z2km^J_O~`~G%&4n?;0H*7=MoJF5-){Hnb?7te$kaD>yOHzum zKC`Efs=E@>bNDDayuY^@d8fBmO={*+f2L{a#)*>`K4Sx_frj2rNqF#l;HAkB|u;o4xUT9jhk#=$O+< z=OVpI($OD5KCEjw=fYgaUza=0eD02M`HniAb6+ZGN&C7mTpIoVE!(pJo%!3o@P9t) zqWQI13+$oi9ohr3XuaUV?DL}C&GNkM*Q?oUBH6`Ewf=%ZRU_G(t*yR%Q8L!=M zw|B8mESLIG=!#;$4c>auTHJ+M&I7A7FKmy>m*%N=FNtKF6`wfBN|8`nwC4VNjiqVsIYUT9a9-(E@fak4m1tz<@ zzH8@B2PLtK_wMm2$?+58j(X%4Mkk_5uyJV>rbzj97Wsf$DNckCNo zSZECzM4uLLKDW;f>#+H+7B9($N4L-H`4oexPITK~00qr{*D&(#F5<8>hpo2zZEL_% zY_%9gFZ+9ghle>ZnCg3d)kZ4QxW@a*2%x;LLdZ%v?XgXc^N>FDIZo}PW>4Bq8&MtF z2p`$sqp*{1*Q^io`^Hx7KQvoNuN)lc+B(0hkAoy&+aS{ur=5kW7tm|?+D3R~nJHI^ zoxSrUMaz=TrQ!M7{=q>>BRS2Yr8Y6DM~2u^#|I7^nk=#(j*-x#V}r0XK1K=6@%)XA zfbIRx{*V=37K zTAbsl5z}ZM=>UmcnNOPkG-$q0Gxs-I=R%@VlunEw3YKDP_#``ypL5!D*TW4I|YR~$9!A0{ACZ%b1HQ58ZB$sW5N_VnnWvg_& z?zFUVOM@1(BhIrz*RW{|rp&1Z>+T4$5@WV@*J7ZPw#NOPNgH=+y~wY41WLwA_P%>o zw?lGeE%?0Ei=|xeu#+W@N-Chx8yok)WJ)8Kt)YfA6sI z963sOSqD9CL(`s^{`V`b@0yMgNhF&Yp^6q|=(@Udmbc?ayq>PTC0Hlo!*?yJz&cSS z$UmnzTKS9XZ+@4mN(;++$Pb7`-#zs*`*tR;9S_emS;V}CR*Sxv{pUH5DCHOy=3*@%@Y?7YUXDvSK zxDLOQ=f(2Ojf2b9>Qkc#u)eS(>&?VHEsbT2bZ z)60+dQtUazg_2Gs9$d7~(a6!##cw6~FWb3(y+!cL_vd zbGlYRenq9pI}M1f$SypZer44tYNWrn{~x#e4gX^KqQ^(P(W|cmC0h}7QLz$VYELy?CS4!vvB0>8O#@l37SZiO6dcXOZ{TsKC;}|3!yfB#k zSbxZRdIwjE{-I%sj)Jdanz6>q*O2;aY&9_JW+)8SwW+r)9-=aQ(u?KSi}Hn^jyaxr zZSXv6OI?dZRU^&!|9gxt%IkP}c1alMSdJ{}u9k8HJ*i`z2IUfoq|D8kW972Dp5Re2 zwJ_jL>5{LI%(0r|R#KG6=Xg{FSb@LgGIMg7 zXv4a3gj=o4$z3GXW2?Shd_5B@=|Pf^%gtGYN8bYBLA9?l*Y2qM%q=~8d0nsGWro%4 z$J4PFfz_+k`e2#swmqAAHM|2t-BYQ`c*80{^bxUFh?=DL&E|2=pX@q#c!w>!2Iv|C zH{N9H9fovUXw19^iQXqVZPmNt-|45}dEf7+exu9bNWYV|o?aMZ*fID8b>F=W%f^w1l&$-Nb?4O@eoHkd!Qtc&QnLqDN;JH|;Q@B=p zOTEL>6dKl%t45_^OxK}QU!Lge9MXxHe@06w+qi9ZDfMjgP7n2I^*xb#Ntd>E!TUY& zCf~OAYdxL}TRV*CrXVgTcNXVaFR@VW@yHSAQ<*D+DT5!gfmo4WN-gAxM*Mue8U#`yLml86%9#jK%xidSg*}*+b=8m*ikP8c#ZvG^)1yGG@M|Y8tyh zYW|fm|K2P{ia6(M->_}F7!9nYe8dy#kIg)4mGj^#>z(GYUB`v)g#+vk#3nK zpqnoBvf~{Sue;ZWaG~!k?qBdKV85m{1cBc^`*SN-$EOuURtEL9+scT}$#_d~V z?7yLSaBAb&3&_q&Dsk|UjOm$G>pXvn-$t|Occ798Gl<7}P z^jI|{m#oW~8?{Jv1g$ow+?&ZmPs;$aeP&}XtmBB!sz2n==E~?CnDyG}P^rvMV;bi@ zte-iiF*k{pFOLb(9Co>XYWkQm^xTeU1-2H88@6jQ+O2wf(B~6=-uJ8$ErPArURcS% zv#UpzyJ{`tqWOu@-E-@j`Tw)s-K_wXEKsDmsGRb8b}q4xGWV?PAon-GVAH9<`&fP3 z0C#h};=Zn?-#2>ryQa#NnxRi?Cu7^g~Th=e|<=LC?^wxt_ z-bw=%wv7|WS{gV0axlC?G8IL^JyzWu3-Vw3vky;K^jvnYTJD?Au9m9MCfbt}N#)X0 zpZ|)I@`6KALHS)SXlCjCjN~i4?ZQ_{bIgXLgDxiMT)*G*ydwk2wCEuZ8l|z8UwNdE zQ(&976sJgj9hYMm+0wNl)vTL-8@w^ZGvZr1xPQm<>5>V`@R@pPzHN&}(`g+)J)fVOg5Yt2$31A}eUl<~KLgEmf=EEU0>gTh z>$ot9=cX{}O8z~I5}%r%BlZ%+@q5Z6>>Gp>Z$>*KjV{|8T}@fRwDrf1clVBQZa6>C zC_2`88Q*c>`6%$~auJQ83Md-cY2gO%W|Hg01@5o@dWHSe8P zo90GV!gc7lWl;t(!q6-{N*I$WK^~Vb-BlxHx_2Ho_+8Tnp^jfCPvdx(ug0_f&Hsl| zmshQRU{XU)cFU><-mRVQm0d0W@);?o;=NytKvtzO{2ildM{ep^B%9Hb-rM@~j6eBT<{=NrE3;`7=*9?ERT{WpM=&{`aOk zN7lRNaRoZpT64oNubVvJQe#nkT$Z*{EDiEJvYu{+Ge>zj%D;7ClhDY|VXNXpPFM?C>{UABh&)>3K z8tW^`11DxQJ*zZFuf_8wUEYSk>WEfhub)aogvOdEzU0Jm6uq5FnRC3eM9nlVy2$H`#^YCFr&wJ1N+;k{q45H(UHegzJlY}@7joc-&dx2!a7mw zwn<8Qw={2uJQ$_#$GX^Q)(k z6A{%YM#o3R*oitBu?`)?REYfzb@YvTR1XEW?H-~``kBY;g55gTRj;{4E-=?nS7;xP;d)3;=e*{V&$u+R-7NFGZ4$X}9SJeVh!N<;!Klj& z`!phZ=C_miLlGtQuaAZuX>yX&l)k zR?iu&lmpW_sNc_dlEv$IXj!($X46>pW*pCnscax?SW7G;tMtIps=aqOQ{Ck*o^l-c z6|DY!vVpz_0AF@!I_xzR_xspj&+=3MzGv^A=~06?Y_ahyi2L0hdmj`L19;F6r&%#` zjitLwc}$763xl_3)Z({+9NtB*L@{dDmn_;CdrIbbavd8^KZgGznS?O!YQ65j)UM*H_7=uW&EZLhM zt4^afKkm3@4vn`o?NUVS)N+dDIu-SI2vX_270}-8n!})~-_qxp=e+cPGs3RH#YrJ;&NB;}DJ{SN-t z9=$t*Xp=aRUl5mO`XXX}&qnX`+Gg&R9Ii?8hW0M@?cKBY)`C`Vtd z)&o!b8Z$J;Ch5Q$lHTCsvHj4fs*~XD*+;M})ZB)i?N)1izN&rJKgDmTOJ9ecs;QDF zdKk_++!y6iS?1BA`ER4guk4R^yzMl9wEz1#-NIHl{my@E@66#!>Pu3Vd$M_%?NDAj zHOftshPe93xT>^yznFAZ)mOz}S`Fq`sddhG`?FU*ajxv=H$eySb!hf!4E&1jPPh`4 z-7?RWcAeMm^M&)Nrkfzf3``>q%bhUPaTEMXGZlwQvtN%ZV{ukV+H2=GCiQt|Oy4F> z^)Lzp9XCU1abA?p>(SDMTtC*M`n0x^*C1_iZN#x7%PiaRcUoC~Wjd1UzRrGb8sZ(J zbOrOybnF9T9JlMG=RK$UHa`6l>OxMm=KT2Rs!>|189@m#6|IG?&YoE1I z!3$e^;QhS^7JuTe`Gw5xs?f=q#dT_2YdHsuDO(t`p1HFb)B8=rD)B{;@K0=4X?{KB zY{Ecya#y-~(Xn&N=;%O)kHo%2{_Gz)K3$o9W4z5RTgpp(@7?oO5?F`m$Kh#hnwf6f zJ)U!P*WLB5=XV?4uH&&M^?}*Lws^o z4op+Tvn?uc>{h#De^^Q08zD^K4mC4&c&&=ZSd^062ib`!%8yB|OVgjs_OY|B9F0!F zpQc+rO3XR<74_GxRU@)EKMdBFrV{1Ff#J20)Vo-s;' + $newFunction.Returntype = $innerXML.Params.ReturnType.Type + } + catch + { + # Do nothing + } + } + + # Keep only EntityType name + $newFunction.ReturnType = $newFunction.ReturnType.Replace('Collection(', '') + $newFunction.ReturnType = $newFunction.ReturnType.Replace(')', '') + + # Actions are always SideEffecting, otherwise it's an OData function + foreach ($parameter in $function.Parameter) + { + if ($parameter.Nullable -ne $null) + { + $parameterIsNullable = [System.Convert]::ToBoolean($parameter.Nullable); + } + + $newParameter = [ODataUtils.Parameter] @{ + "Name" = $parameter.Name; + "Type" = $parameter.Type; + "Nullable" = $parameterIsNullable; + } + + $newFunction.Parameters += $newParameter + } + + $Metadata.Functions += $newFunction + } + } +} + +######################################################### +# Processes plain text xml metadata (OData V4 schema version) into our custom structure +# MetadataSet contains all parsed so far referenced Metadatas (for base class lookup) +######################################################### +function ParseMetadata +{ + param + ( + [xml] $MetadataXML, + [string] $ODataVersion, + [string] $MetadataUri, + [string] $Uri, + [System.Collections.ArrayList] $MetadataSet + ) + + if($MetadataXML -eq $null) { throw ($LocalizedData.ArguementNullError -f "MetadataXML", "ParseMetadata") } + + # This is a processing queue for those types that require base types that haven't been defined yet + $entityAndComplexTypesQueue = @{} + [System.Collections.ArrayList] $metadatas = [System.Collections.ArrayList]::new() + + foreach ($schema in $MetadataXML.Edmx.DataServices.Schema) + { + if ($schema -eq $null) + { + Write-Error $LocalizedData.EmptySchema + continue + } + + [ODataUtils.MetadataV4] $metadata = [ODataUtils.MetadataV4]::new() + $metadata.ODataVersion = $ODataVersion + $metadata.MetadataUri = $MetadataUri + $metadata.Uri = $Uri + $metadata.Namespace = $schema.Namespace + $metadata.Alias = $schema.Alias + + ParseEntityTypes -SchemaXML $schema -metadata $metadata -GlobalMetadata $MetadataSet -EntityAndComplexTypesQueue $entityAndComplexTypesQueue -CustomNamespace $CustomNamespace -Alias $metadata.Alias + ParseComplexTypes -SchemaXML $schema -metadata $metadata -GlobalMetadata $MetadataSet -EntityAndComplexTypesQueue $entityAndComplexTypesQueue -CustomNamespace $CustomNamespace -Alias $metadata.Alias + ParseTypeDefinitions -SchemaXML $schema -metadata $metadata -GlobalMetadata $MetadataSet -CustomNamespace $CustomNamespace -Alias $metadata.Alias + ParseEnumTypes -SchemaXML $schema -metadata $metadata + + foreach ($entityContainer in $schema.EntityContainer) + { + if ($entityContainer.IsDefaultEntityContainer) + { + $metadata.DefaultEntityContainerName = $entityContainer.Name + } + + ParseSingletonTypes -SchemaEntityContainerXML $entityContainer -Metadata $metadata + ParseEntitySets -SchemaEntityContainerXML $entityContainer -Metadata $metadata -Namespace $schema.Namespace -Alias $schema.Alias + } + + if ($schema.Action) + { + ParseActions -SchemaActionsXML $schema.Action -Metadata $metadata + } + + if ($schema.Function) + { + ParseFunctions -SchemaFunctionsXML $schema.Function -Metadata $metadata + } + + # In this call we check if the Namespace or Alias have to be normalized because it has invalid combination of dots and numbers. + # Note: In ParseEntityTypes and ParseComplexTypes we check for scenario where namespace/alias collide with inheriting class name. + NormalizeNamespace $metadata.Namespace $metadata.Uri $script:normalizedNamespaces $false + NormalizeNamespace $metadata.Alias $metadata.Uri $script:normalizedNamespaces $false + + $metadatas.Add($metadata) | Out-Null + } + + $metadatas +} + +######################################################### +# Verifies processed metadata for correctness +######################################################### +function VerifyMetadata +{ + param + ( + [System.Collections.ArrayList] $metadataSet, + [boolean] $allowClobber, + $callerPSCmdlet, + [string] $progressBarStatus + ) + + if($callerPSCmdlet -eq $null) { throw ($LocalizedData.ArguementNullError -f "PSCmdlet", "VerifyMetaData") } + if($progressBarStatus -eq $null) { throw ($LocalizedData.ArguementNullError -f "ProgressBarStatus", "VerifyMetaData") } + + Write-Verbose $LocalizedData.VerboseVerifyingMetadata + + $reservedProperties = @("Filter", "OrderBy", "Skip", "Top", "ConnectionUri", "CertificateThumbPrint", "Credential") + $validEntitySets = @() + $sessionCommands = Get-Command -All + + + foreach ($metadata in $metadataSet) + { + foreach ($entitySet in $metadata.EntitySets) + { + if ($entitySet.Type -eq $null) + { + $errorMessage = ($LocalizedData.EntitySetUndefinedType -f $metadata.MetadataUri, $entitySet.Name) + $exception = [System.InvalidOperationException]::new($errorMessage) + $errorRecord = CreateErrorRecordHelper "ODataEndpointProxyInvalidMetaDataUri" $null ([System.Management.Automation.ErrorCategory]::InvalidArgument) $exception $metadata.MetadataUri + $callerPSCmdlet.ThrowTerminatingError($errorRecord) + } + + $hasConflictingProperty = $false + $hasConflictingCommand = $false + $entityAndNavigationProperties = $entitySet.Type.EntityProperties + $entitySet.Type.NavigationProperties + foreach($entityProperty in $entityAndNavigationProperties) + { + if($reservedProperties.Contains($entityProperty.Name)) + { + $hasConflictingProperty = $true + if(!$allowClobber) + { + # Write Error message and skip current Entity Set. + $errorMessage = ($LocalizedData.SkipEntitySetProxyCreation -f $entitySet.Name, $entitySet.Type.Name, $entityProperty.Name) + $exception = [System.InvalidOperationException]::new($errorMessage) + $errorRecord = CreateErrorRecordHelper "ODataEndpointDefaultPropertyCollision" $null ([System.Management.Automation.ErrorCategory]::InvalidOperation) $exception $metadata.MetadataUri + $callerPSCmdlet.WriteError($errorRecord) + } + else + { + $warningMessage = ($LocalizedData.EntitySetProxyCreationWithWarning -f $entitySet.Name, $entityProperty.Name, $entitySet.Type.Name) + $callerPSCmdlet.WriteWarning($warningMessage) + } + } + } + + foreach($currentCommand in $sessionCommands) + { + if(($null -ne $currentCommand.Noun -and $currentCommand.Noun -eq $entitySet.Name) -and + ($currentCommand.Verb -eq "Get" -or + $currentCommand.Verb -eq "Set" -or + $currentCommand.Verb -eq "New" -or + $currentCommand.Verb -eq "Remove")) + { + $hasConflictingCommand = $true + VerifyMetadataHelper $LocalizedData.SkipEntitySetConflictCommandCreation ` + $LocalizedData.EntitySetConflictCommandCreationWithWarning ` + $entitySet.Name $currentCommand.Name $metadata.MetadataUri $allowClobber $callerPSCmdlet + } + } + + foreach($currentAction in $metadata.Actions) + { + $actionCommand = "Invoke-" + "$($entitySet.Name)$($currentAction.Verb)" + + foreach($currentCommand in $sessionCommands) + { + if($actionCommand -eq $currentCommand.Name) + { + $hasConflictingCommand = $true + VerifyMetadataHelper $LocalizedData.SkipEntitySetConflictCommandCreation ` + $LocalizedData.EntitySetConflictCommandCreationWithWarning $entitySet.Name ` + $currentCommand.Name $metadata.MetadataUri $allowClobber $callerPSCmdlet + } + } + } + + if(!($hasConflictingProperty -or $hasConflictingCommand)-or $allowClobber) + { + $validEntitySets += $entitySet + } + } + + $metadata.EntitySets = $validEntitySets + + $validServiceActions = @() + $hasConflictingServiceActionCommand + foreach($currentAction in $metadata.Actions) + { + $serviceActionCommand = "Invoke-" + "$($currentAction.Verb)" + + foreach($currentCommand in $sessionCommands) + { + if($serviceActionCommand -eq $currentCommand.Name) + { + $hasConflictingServiceActionCommand = $true + VerifyMetadataHelper $LocalizedData.SkipConflictServiceActionCommandCreation ` + $LocalizedData.ConflictServiceActionCommandCreationWithWarning $entitySet.Name ` + $currentCommand.Name $metadata.MetadataUri $allowClobber $callerPSCmdlet + } + } + + if(!$hasConflictingServiceActionCommand -or $allowClobber) + { + $validServiceActions += $currentAction + } + } + + $metadata.Actions = $validServiceActions + } + + # Update Progress bar. + ProgressBarHelper "Export-ODataEndpointProxy" $progressBarStatus 5 20 1 1 +} + +######################################################### +# Takes xml definition of a class from metadata document, +# plus existing metadata structure and finds its base class +######################################################### +function GetBaseType +{ + param + ( + [System.Xml.XmlElement] $MetadataEntityDefinition, + [ODataUtils.MetadataV4] $Metadata, + [string] $Namespace, + [System.Collections.ArrayList] $GlobalMetadata + ) + + if ($metadataEntityDefinition -ne $null -and + $metaData -ne $null -and + $MetadataEntityDefinition.BaseType -ne $null) + { + $baseType = $Metadata.EntityTypes | Where { $_.Namespace + "." + $_.Name -eq $MetadataEntityDefinition.BaseType -or $_.Alias + "." + $_.Name -eq $MetadataEntityDefinition.BaseType } + if ($baseType -eq $null) + { + $baseType = $Metadata.ComplexTypes | Where { $_.Namespace + "." + $_.Name -eq $MetadataEntityDefinition.BaseType -or $_.Alias + "." + $_.Name -eq $MetadataEntityDefinition.BaseType } + } + + if ($baseType -eq $null) + { + # Look in other metadatas, since the class can be defined in referenced metadata + foreach ($referencedMetadata in $GlobalMetadata) + { + if (($baseType = $referencedMetadata.EntityTypes | Where { $_.Namespace + "." + $_.Name -eq $MetadataEntityDefinition.BaseType -or $_.Alias + "." + $_.Name -eq $MetadataEntityDefinition.BaseType }) -ne $null -or + ($baseType = $referencedMetadata.ComplexTypes | Where { $_.Namespace + "." + $_.Name -eq $MetadataEntityDefinition.BaseType -or $_.Alias + "." + $_.Name -eq $MetadataEntityDefinition.BaseType }) -ne $null) + { + # Found base class + break + } + } + } + } + + if ($baseType -ne $null) + { + $baseType[0] + } +} + +######################################################### +# Takes base class name and global metadata structure +# and finds its base class +######################################################### +function GetBaseTypeByName +{ + param + ( + [String] $BaseTypeStr, + [System.Collections.ArrayList] $GlobalMetadata + ) + + if ($BaseTypeStr -ne $null) + { + + # Look for base class definition in all referenced metadatas (including entry point) + foreach ($referencedMetadata in $GlobalMetadata) + { + if (($baseType = $referencedMetadata.EntityTypes | Where { $_.Namespace + "." + $_.Name -eq $BaseTypeStr -or $_.Alias + "." + $_.Name -eq $BaseTypeStr }) -ne $null -or + ($baseType = $referencedMetadata.ComplexTypes | Where { $_.Namespace + "." + $_.Name -eq $BaseTypeStr -or $_.Alias + "." + $_.Name -eq $BaseTypeStr }) -ne $null) + { + # Found base class + break + } + } + } + + if ($baseType -ne $null) + { + $baseType[0] + } + else + { + $null + } +} + +######################################################### +# Processes derived types of a newly added type, +# that were previously waiting in the queue +######################################################### +function AddDerivedTypes { + param( + [ODataUtils.EntityTypeV4] $baseType, + $entityAndComplexTypesQueue, + [ODataUtils.MetadataV4] $metadata, + [string] $namespace + ) + + if($baseType -eq $null) { throw ($LocalizedData.ArguementNullError -f "BaseType", "AddDerivedTypes") } + if($entityAndComplexTypesQueue -eq $null) { throw ($LocalizedData.ArguementNullError -f "EntityAndComplexTypesQueue", "AddDerivedTypes") } + if($namespace -eq $null) { throw ($LocalizedData.ArguementNullError -f "Namespace", "AddDerivedTypes") } + + $baseTypeFullName = $baseType.Namespace + '.' + $baseType.Name + $baseTypeShortName = $baseType.Alias + '.' + $baseType.Name + + if ($entityAndComplexTypesQueue.ContainsKey($baseTypeFullName) -or $entityAndComplexTypesQueue.ContainsKey($baseTypeShortName)) + { + $types = $entityAndComplexTypesQueue[$baseTypeFullName] + $entityAndComplexTypesQueue[$baseTypeShortName] + + foreach ($type in $types) + { + if ($type.type -eq 'EntityType') + { + $newType = ParseMetadataTypeDefinition ($type.value) $baseType $metadata $namespace $true + $metadata.EntityTypes += $newType + } + else + { + $newType = ParseMetadataTypeDefinition ($type.value) $baseType $metadata $namespace $false + $metadata.ComplexTypes += $newType + } + + AddDerivedTypes $newType $entityAndComplexTypesQueue $metadata $namespace + } + } +} + +######################################################### +# Parses types definitions element of metadata xml +######################################################### +function ParseMetadataTypeDefinitionHelper +{ + param + ( + [System.Xml.XmlElement] $metadataEntityDefinition, + [ODataUtils.EntityTypeV4] $baseType, + [string] $baseTypeStr, + [ODataUtils.MetadataV4] $metadata, + [string] $namespace, + [AllowEmptyString()] + [string] $alias, + [bool] $isEntity + ) + + if($metadataEntityDefinition -eq $null) { throw ($LocalizedData.ArguementNullError -f "MetadataEntityDefinition", "ParseMetadataTypeDefinition") } + if($namespace -eq $null) { throw ($LocalizedData.ArguementNullError -f "Namespace", "ParseMetadataTypeDefinition") } + + [ODataUtils.EntityTypeV4] $newEntityType = CreateNewEntityType -metadataEntityDefinition $metadataEntityDefinition -baseType $baseType -baseTypeStr $baseTypeStr -namespace $namespace -alias $alias -isEntity $isEntity + + if ($baseType -ne $null) + { + # Add properties inherited from BaseType + ParseMetadataBaseTypeDefinitionHelper $newEntityType $baseType + } + + # properties defined on EntityType + $newEntityType.EntityProperties += $metadataEntityDefinition.Property | % { + if ($_ -ne $null) + { + if ($_.Nullable -ne $null) + { + $newPropertyIsNullable = [System.Convert]::ToBoolean($_.Nullable) + } + else + { + $newPropertyIsNullable = $true + } + + [ODataUtils.TypeProperty] @{ + "Name" = $_.Name; + "TypeName" = $_.Type; + "IsNullable" = $newPropertyIsNullable; + } + } + } + + # odataId property will be inherited from base type, if it exists. + # Otherwise, it should be added to current type + if ($baseType -eq $null) + { + # @odata.Id property (renamed to odataId) is required for dynamic Uri creation + # This property is only available when user executes auto-generated cmdlet with -AllowAdditionalData, + # but ODataAdapter needs it to construct Uri to access navigation properties. + # Thus, we need to fetch this info for scenario when -AllowAdditionalData isn't used. + $newEntityType.EntityProperties += [ODataUtils.TypeProperty] @{ + "Name" = "odataId"; + "TypeName" = "Edm.String"; + "IsNullable" = $True; + } + } + + # Property name can't be identical to entity type name. + # If such property exists, "Property" suffix will be added to its name. + foreach ($property in $newEntityType.EntityProperties) + { + if ($property.Name -eq $newEntityType.Name) + { + $property.Name += "Property" + } + } + + if ($metadataEntityDefinition -ne $null -and $metadataEntityDefinition.Key -ne $null) + { + foreach ($entityTypeKey in $metadataEntityDefinition.Key.PropertyRef) + { + ($newEntityType.EntityProperties | Where-Object { $_.Name -eq $entityTypeKey.Name }).IsKey = $true + } + } + + $newEntityType +} + +######################################################### +# Add base class entity and navigation properties to inheriting class +######################################################### +function ParseMetadataBaseTypeDefinitionHelper +{ + param + ( + [ODataUtils.EntityTypeV4] $EntityType, + [ODataUtils.EntityTypeV4] $BaseType + ) + + if ($EntityType -ne $null -and $BaseType -ne $null) + { + # Add properties inherited from BaseType + $EntityType.EntityProperties += $BaseType.EntityProperties + $EntityType.NavigationProperties += $BaseType.NavigationProperties + } +} + +######################################################### +# Create new EntityType object +######################################################### +function CreateNewEntityType +{ + param + ( + [System.Xml.XmlElement] $metadataEntityDefinition, + [ODataUtils.EntityTypeV4] $baseType, + [string] $baseTypeStr, + [string] $namespace, + [AllowEmptyString()] + [string] $alias, + [bool] $isEntity + ) + $newEntityType = [ODataUtils.EntityTypeV4] @{ + "Namespace" = $namespace; + "Alias" = $alias; + "Name" = $metadataEntityDefinition.Name; + "IsEntity" = $isEntity; + "BaseType" = $baseType; + "BaseTypeStr" = $baseTypeStr; + } + + $newEntityType +} + +######################################################### +# Parses navigation properties from metadata xml +######################################################### +function ParseMetadataTypeDefinitionNavigationProperties +{ + param + ( + [System.Xml.XmlElement] $metadataEntityDefinition, + [ODataUtils.EntityTypeV4] $entityType + ) + + # navigation properties defined on EntityType + $newEntityType.NavigationProperties = @{} + $newEntityType.NavigationProperties.Clear() + + foreach ($navigationProperty in $metadataEntityDefinition.NavigationProperty) + { + $tmp = [ODataUtils.NavigationPropertyV4] @{ + "Name" = $navigationProperty.Name; + "Type" = $navigationProperty.Type; + "Nullable" = $navigationProperty.Nullable; + "Partner" = $navigationProperty.Partner; + "ContainsTarget" = $navigationProperty.ContainsTarget; + "OnDelete" = $navigationProperty.OnDelete; + } + + $referentialConstraints = @{} + foreach ($constraint in $navigationProperty.ReferentialConstraints) + { + $tmp = [ODataUtils.ReferencedConstraint] @{ + "Property" = $constraint.Property; + "ReferencedProperty" = $constraint.ReferencedProperty; + } + } + + $newEntityType.NavigationProperties += $tmp + } +} + +######################################################### +# Parses types definitions element of metadata xml for OData V4 schema +######################################################### +function ParseMetadataTypeDefinition +{ + param + ( + [System.Xml.XmlElement] $metadataEntityDefinition, + [ODataUtils.EntityTypeV4] $baseType, + [ODataUtils.MetadataV4] $metadata, + [string] $namespace, + [AllowEmptyString()] + [string] $alias, + [bool] $isEntity, + [string] $baseTypeStr + ) + + if($metadataEntityDefinition -eq $null) { throw ($LocalizedData.ArguementNullError -f "MetadataEntityDefinition", "ParseMetadataTypeDefinition") } + if($namespace -eq $null) { throw ($LocalizedData.ArguementNullError -f "Namespace", "ParseMetadataTypeDefinition") } + + [ODataUtils.EntityTypeV4] $newEntityType = ParseMetadataTypeDefinitionHelper -metadataEntityDefinition $metadataEntityDefinition -baseType $baseType -baseTypeStr $baseTypeStr -metadata $metadata -namespace $namespace -alias $alias -isEntity $isEntity + ParseMetadataTypeDefinitionNavigationProperties -metadataEntityDefinition $metadataEntityDefinition -entityType $newEntityType + + $newEntityType +} + +######################################################### +# Create psd1 and cdxml files required to auto-generate +# cmdlets for given service. +######################################################### +function GenerateClientSideProxyModule +{ + param + ( + [System.Collections.ArrayList] $GlobalMetadata, + [ODataUtils.ODataEndpointProxyParameters] $ODataEndpointProxyParameters, + [string] $OutputModule, + [string] $CreateRequestMethod, + [string] $UpdateRequestMethod, + [string] $CmdletAdapter, + [Hashtable] $resourceNameMappings, + [Hashtable] $CustomData, + [string] $UriResourcePathKeyFormat, + [string] $progressBarStatus, + $NormalizedNamespaces + ) + + if($progressBarStatus -eq $null) { throw ($LocalizedData.ArguementNullError -f "ProgressBarStatus", "GenerateClientSideProxyModule") } + + Write-Verbose ($LocalizedData.VerboseSavingModule -f $OutputModule) + + # Save ComplexTypes for all metadata schemas in single file + $typeDefinationFileName = "ComplexTypeDefinitions.psm1" + $complexTypeMapping = GenerateComplexTypeDefinition $GlobalMetadata $OutputModule $typeDefinationFileName $NormalizedNamespaces + + ProgressBarHelper "Export-ODataEndpointProxy" $progressBarStatus 20 20 1 1 + + $actions = @() + $functions = @() + + $currentEntryCount = 0 + foreach ($Metadata in $GlobalMetadata) + { + foreach ($entitySet in $Metadata.EntitySets) + { + $currentEntryCount += 1 + SaveCDXML $entitySet $Metadata $GlobalMetadata $Metadata.Uri $OutputModule $CreateRequestMethod $UpdateRequestMethod $CmdletAdapter $resourceNameMappings $CustomData $complexTypeMapping $UriResourcePathKeyFormat $NormalizedNamespaces + + ProgressBarHelper "Export-ODataEndpointProxy" $progressBarStatus 40 20 $Metadata.EntitySets.Count $currentEntryCount + } + + $currentEntryCount = 0 + foreach ($singleton in $Metadata.SingletonTypes) + { + $currentEntryCount += 1 + SaveCDXMLSingletonCmdlets $singleton $Metadata $GlobalMetadata $Metadata.Uri $OutputModule $CreateRequestMethod $UpdateRequestMethod $CmdletAdapter $resourceNameMappings $CustomData $complexTypeMapping $NormalizedNamespaces + + ProgressBarHelper "Export-ODataEndpointProxy" $progressBarStatus 40 20 $Metadata.Singletons.Count $currentEntryCount + } + + $actions += $Metadata.Actions | Where-Object { $_.EntitySet -eq '' -or $_.EntitySet -eq $null } + $functions += $Metadata.Functions | Where-Object { $_.EntitySet -eq '' -or $_.EntitySet -eq $null } + } + + if ($actions.Count -gt 0 -or $functions.Count -gt 0) + { + # Save Service Actions for all metadata schemas in single file + SaveServiceActionsCDXML $GlobalMetadata $ODataEndpointProxyParameters "$OutputModule\ServiceActions.cdxml" $complexTypeMapping $progressBarStatus $CmdletAdapter + } + + $moduleDirInfo = [System.IO.DirectoryInfo]::new($OutputModule) + $moduleManifestName = $moduleDirInfo.Name + ".psd1" + + if ($actions.Count -gt 0 -or $functions.Count -gt 0) + { + $additionalModules = @($typeDefinationFileName, 'ServiceActions.cdxml') + } + else + { + $additionalModules = @($typeDefinationFileName) + } + + GenerateModuleManifest $GlobalMetadata $OutputModule\$moduleManifestName $additionalModules $resourceNameMappings $progressBarStatus +} + +######################################################### +# Generates CDXML module for a specific OData EntitySet +######################################################### +function SaveCDXML +{ + param + ( + [ODataUtils.EntitySetV4] $EntitySet, + [ODataUtils.MetadataV4] $Metadata, + [System.Collections.ArrayList] $GlobalMetadata, + [string] $Uri, + [string] $OutputModule, + [string] $CreateRequestMethod, + [string] $UpdateRequestMethod, + [string] $CmdletAdapter, + [Hashtable] $resourceNameMappings, + [Hashtable] $CustomData, + [Hashtable] $compexTypeMapping, + [string] $UriResourcePathKeyFormat, + $normalizedNamespaces + ) + + if($EntitySet -eq $null) { throw ($LocalizedData.ArguementNullError -f "EntitySet", "GenerateClientSideProxyModule") } + if($Metadata -eq $null) { throw ($LocalizedData.ArguementNullError -f "metadata", "GenerateClientSideProxyModule") } + + $entitySetName = $EntitySet.Name + if(($null -ne $resourceNameMappings) -and + $resourceNameMappings.ContainsKey($entitySetName)) + { + $entitySetName = $resourceNameMappings[$entitySetName] + } + else + { + $entitySetName = $EntitySet.Type.Name + } + + $Path = "$OutputModule\$entitySetName.cdxml" + + $xmlWriter = New-Object System.XMl.XmlTextWriter($Path,$Null) + + if ($xmlWriter -eq $null) + { + throw ($LocalizedData.XmlWriterInitializationError -f $EntitySet.Name) + } + + $xmlWriter = SaveCDXMLHeader $xmlWriter $Uri $EntitySet.Name $entitySetName $CmdletAdapter + + # Get the keys + $keys = $EntitySet.Type.EntityProperties | Where-Object { $_.IsKey } + + $navigationProperties = $EntitySet.Type.NavigationProperties + + SaveCDXMLInstanceCmdlets $xmlWriter $Metadata $GlobalMetadata $EntitySet.Type $keys $navigationProperties $CmdletAdapter $compexTypeMapping $false + + $nonKeyProperties = $EntitySet.Type.EntityProperties | ? { -not $_.isKey } + $nullableProperties = $nonKeyProperties | ? { $_.isNullable } + $nonNullableProperties = $nonKeyProperties | ? { -not $_.isNullable } + + $xmlWriter.WriteStartElement('StaticCmdlets') + + $keyProperties = $keys + + SaveCDXMLNewCmdlet $xmlWriter $Metadata $GlobalMetadata $keyProperties $nonNullableProperties $nullableProperties $navigationProperties $CmdletAdapter $compexTypeMapping + + GenerateSetProxyCmdlet $xmlWriter $keyProperties $nonKeyProperties $compexTypeMapping + + SaveCDXMLRemoveCmdlet $xmlWriter $Metadata $GlobalMetadata $keyProperties $navigationProperties $CmdletAdapter $compexTypeMapping + + $entityActions = $Metadata.Actions | Where-Object { ($_.EntitySet.Namespace -eq $EntitySet.Namespace) -and ($_.EntitySet.Name -eq $EntitySet.Name) } + + if ($entityActions.Length -gt 0) + { + foreach($action in $entityActions) + { + $xmlWriter = SaveCDXMLAction $xmlWriter $Metadata $action $EntitySet.Name $true $keys $complexTypeMapping + } + } + + $entityFunctions = $Metadata.Functions | Where-Object { ($_.EntitySet.Namespace -eq $EntitySet.Namespace) -and ($_.EntitySet.Name -eq $EntitySet.Name) } + + if ($entityFunctions.Length -gt 0) + { + foreach($function in $entityFunctions) + { + $xmlWriter = SaveCDXMLFunction $xmlWriter $Metadata $function $EntitySet.Name $true $keys $complexTypeMapping + } + } + + $xmlWriter.WriteEndElement() + + $normalizedDotNetNamespace = GetNamespace $EntitySet.Type.Namespace $normalizedNamespaces + $normalizedDotNetAlias = GetNamespace $EntitySet.Alias $normalizedNamespaces + $normalizedDotNetEntitySetNamespace = $normalizedDotNetNamespace + + $xmlWriter.WriteStartElement('CmdletAdapterPrivateData') + + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'EntityTypeName') + $xmlWriter.WriteString("$($normalizedDotNetNamespace).$($EntitySet.Type.Name)") + $xmlWriter.WriteEndElement() + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'EntityTypeAliasName') + if (!$EntitySet.Alias) + { + $xmlWriter.WriteString("") + } + else + { + $xmlWriter.WriteString("$($normalizedDotNetAlias).$($EntitySet.Type.Name)") + } + $xmlWriter.WriteEndElement() + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'EntitySetName') + $xmlWriter.WriteString("$($normalizedDotNetEntitySetNamespace).$($EntitySet.Name)") + $xmlWriter.WriteEndElement() + + # Add URI resource path format (webservice.svc/ResourceName/ResourceId vs webservice.svc/ResourceName(QueryKeyName=ResourceId)) + if ($UriResourcePathKeyFormat -ne $null -and $UriResourcePathKeyFormat -ne '') + { + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'UriResourcePathKeyFormat') + $xmlWriter.WriteString("$UriResourcePathKeyFormat") + $xmlWriter.WriteEndElement() + } + + # Add information about navigation properties and their types + # Used in scenario where user requests navigation property in -Select query + foreach ($navProperty in $navigationProperties) + { + if ($navProperty) + { + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', $navProperty.Name + 'NavigationProperty') + $xmlWriter.WriteString($navProperty.Type) + $xmlWriter.WriteEndElement() + } + } + + # Add CreateRequestMethod and UpdateRequestMethod to privateData + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'CreateRequestMethod') + $xmlWriter.WriteString("$CreateRequestMethod") + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'UpdateRequestMethod') + $xmlWriter.WriteString("$UpdateRequestMethod") + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteEndElement() + + SaveCDXMLFooter $xmlWriter + + Write-Verbose ($LocalizedData.VerboseSavedCDXML -f $($entitySetName), $Path) +} + +######################################################### +# Save Singleton Cmdlets to CDXML +######################################################### +function SaveCDXMLSingletonCmdlets +{ + param + ( + [ODataUtils.SingletonType] $Singleton, + [ODataUtils.MetadataV4] $Metadata, + [System.Collections.ArrayList] $GlobalMetadata, + [string] $Uri, + [string] $OutputModule, + [string] $CreateRequestMethod, + [string] $UpdateRequestMethod, + [string] $CmdletAdapter, + [Hashtable] $resourceNameMappings, + [Hashtable] $CustomData, + [Hashtable] $compexTypeMapping, + $normalizedNamespaces + ) + + if($Singleton -eq $null) { throw ($LocalizedData.ArguementNullError -f "Singleton", "SaveCDXMLSingletonCmdlets") } + if($Metadata -eq $null) { throw ($LocalizedData.ArguementNullError -f "Metadata", "SaveCDXMLSingletonCmdlets") } + + $singletonName = $singleton.Name + $singletonType = $singleton.Type + + $Path = "$OutputModule\$singletonName" + "Singleton" + ".cdxml" + + $xmlWriter = New-Object System.XMl.XmlTextWriter($Path,$Null) + + if ($xmlWriter -eq $null) + { + throw ($LocalizedData.XmlWriterInitializationError -f $singletonName) + } + + # Get associated EntityType + $associatedEntityType = $Metadata.EntityTypes | Where-Object { $_.Namespace + "." + $_.Name -eq $singletonType -or $_.Alias + "." + $_.Name -eq $singletonType} + + if ($associatedEntityType -eq $null) + { + # Look in other metadatas, since the class can be defined in referenced metadata + foreach ($referencedMetadata in $GlobalMetadata) + { + if (($associatedEntityType = $referencedMetadata.EntityTypes | Where { $_.Namespace + "." + $_.Name -eq $singletonType -or $_.Alias + "." + $_.Name -eq $singletonType }) -ne $null) + { + # Found associated class + break + } + } + } + + if ($associatedEntityType -ne $null) + { + $xmlWriter = SaveCDXMLHeader $xmlWriter $Uri $singletonName $singletonName $CmdletAdapter + + if ($associatedEntityType.BaseType -eq $null -and $associatedEntityType.BaseTypeStr -ne $null -and $associatedEntityType.BaseTypeStr -ne '') + { + $associatedEntitybaseType = GetBaseTypeByName $associatedEntityType.BaseTypeStr $GlobalMetadata + + # Make another pass on base class to make sure its properties were added to associated entity type + ParseMetadataBaseTypeDefinitionHelper $associatedEntityType $associatedEntitybaseType + } + + # Get the keys depending on whether the url contains variables or not + $keys = $associatedEntityType.EntityProperties | Where-Object { $_.IsKey } + + $navigationProperties = $associatedEntityType.NavigationProperties + + SaveCDXMLInstanceCmdlets $xmlWriter $Metadata $GlobalMetadata $associatedEntityType $keys $navigationProperties $CmdletAdapter $compexTypeMapping $true + + $nonKeyProperties = $associatedEntityType.EntityProperties | ? { -not $_.isKey } + $nullableProperties = $nonKeyProperties | ? { $_.isNullable } + $nonNullableProperties = $nonKeyProperties | ? { -not $_.isNullable } + + $xmlWriter.WriteStartElement('StaticCmdlets') + + $keyProperties = $keys + + GenerateSetProxyCmdlet $xmlWriter $keyProperties $nonKeyProperties $compexTypeMapping + + $entityActions = $Metadata.Actions | Where-Object { $_.EntitySet.Name -eq $associatedEntityType.Name } + + if ($entityActions.Length -gt 0) + { + foreach($action in $entityActions) + { + $xmlWriter = SaveCDXMLAction $xmlWriter $Metadata $action $EntitySet.Name $true $keys $complexTypeMapping + } + } + + $entityFunctions = $Metadata.Functions | Where-Object { $_.EntitySet.Name -eq $associatedEntityType.Name } + + if ($entityFunctions.Length -gt 0) + { + foreach($function in $entityFunctions) + { + $xmlWriter = SaveCDXMLFunction $xmlWriter $Metadata $function $associatedEntityType.Name $true $keys $complexTypeMapping + } + } + + $xmlWriter.WriteEndElement() + + $normalizedDotNetNamespace = GetNamespace $associatedEntityType.Namespace $normalizedNamespaces + $normalizedDotNetAlias = GetNamespace $associatedEntityType.Alias $normalizedNamespaces + + $xmlWriter.WriteStartElement('CmdletAdapterPrivateData') + + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'EntityTypeAliasName') + if (!$associatedEntityType.Alias) + { + $xmlWriter.WriteString("") + } + else + { + $xmlWriter.WriteString("$($normalizedDotNetAlias).$($associatedEntityType.Name)") + } + $xmlWriter.WriteEndElement() + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'EntityTypeName') + $xmlWriter.WriteString("$($normalizedDotNetNamespace).$($associatedEntityType.Name)") + $xmlWriter.WriteEndElement() + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'IsSingleton') + $xmlWriter.WriteString("True") + $xmlWriter.WriteEndElement() + + # Add information about navigation properties and their types + # Used in scenario where user requests navigation property in -Select query + foreach ($navProperty in $navigationProperties) + { + if ($navProperty) + { + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', $navProperty.Name + 'NavigationProperty') + $xmlWriter.WriteString($navProperty.Type) + $xmlWriter.WriteEndElement() + } + } + + # Add UpdateRequestMethod to privateData + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'UpdateRequestMethod') + $xmlWriter.WriteString("$UpdateRequestMethod") + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteEndElement() + + SaveCDXMLFooter $xmlWriter + + Write-Verbose ($LocalizedData.VerboseSavedCDXML -f $($associatedEntityType.Name), $Path) + } +} + +######################################################### +# Saves InstanceCmdlets node to CDXML +######################################################### +function SaveCDXMLInstanceCmdlets +{ + param + ( + [System.XMl.XmlTextWriter] $xmlWriter, + [ODataUtils.MetadataV4] $Metadata, + [System.Collections.ArrayList] $GlobalMetadata, + [ODataUtils.EntityTypeV4] $EntityType, + $keys, + $navigationProperties, + $CmdletAdapter, + [Hashtable] $complexTypeMapping, + [bool] $isSingleton + ) + + if($xmlWriter -eq $null) { throw ($LocalizedData.ArguementNullError -f "xmlWriter", "SaveCDXMLInstanceCmdlets") } + if($Metadata -eq $null) { throw ($LocalizedData.ArguementNullError -f "Metadata", "SaveCDXMLInstanceCmdlets") } + + $xmlWriter.WriteStartElement('InstanceCmdlets') + $xmlWriter.WriteStartElement('GetCmdletParameters') + # adding key parameters and association parameters to QueryableProperties, each in a different parameter set + # to be used by GET cmdlet + if (($keys.Length -gt 0) -or ($navigationProperties.Length -gt 0)) + { + $querableNavProperties = @{} + + if ($isSingleton -eq $false) + { + foreach ($navProperty in $navigationProperties) + { + if ($navProperty -ne $null) + { + $associatedType = GetAssociatedType $Metadata $GlobalMetadata $navProperty + $associatedTypeKeyProperties = $associatedType.EntityProperties | ? { $_.IsKey } + + # Make sure associated parameter (based on navigation property) has EntitySet or Singleton, which makes it accessible from the service root + # Otherwise the Uri for associated navigation property won't be valid + if ($associatedTypeKeyProperties.Length -gt 0 -and (ShouldBeAssociatedParameter $GlobalMetadata $EntityType $associatedType $isSingleton)) + { + $querableNavProperties.Add($navProperty, $associatedTypeKeyProperties) + } + } + } + } + + $defaultCmdletParameterSet = 'Default' + if ($isSingleton -eq $true -and $querableNavProperties.Count -gt 0) + { + foreach($item in $querableNavProperties.GetEnumerator()) + { + $defaultCmdletParameterSet = $item.Key.Name + break + } + } + $xmlWriter.WriteAttributeString('DefaultCmdletParameterSet', $defaultCmdletParameterSet) + + + $xmlWriter.WriteStartElement('QueryableProperties') + + $position = 0 + + if ($isSingleton -eq $false) + { + $keys | ? { $_ -ne $null } | % { + $xmlWriter.WriteStartElement('Property') + $xmlWriter.WriteAttributeString('PropertyName', $_.Name) + + $xmlWriter.WriteStartElement('Type') + $PSTypeName = Convert-ODataTypeToCLRType $_.TypeName $complexTypeMapping + $xmlWriter.WriteAttributeString('PSType', $PSTypeName) + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('RegularQuery') + $xmlWriter.WriteStartElement('CmdletParameterMetadata') + $xmlWriter.WriteAttributeString('PSName', $_.Name) + $xmlWriter.WriteAttributeString('CmdletParameterSets', 'Default') + $xmlWriter.WriteAttributeString('IsMandatory', $_.IsMandatory.ToString().ToLower()) + $xmlWriter.WriteAttributeString('Position', $position) + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + + $position++ + } + } + + if ($querableNavProperties.Count -gt 0) + { + foreach($item in $querableNavProperties.GetEnumerator()) + { + $xmlWriter.WriteStartElement('Property') + $xmlWriter.WriteAttributeString('PropertyName', $item.Key.Name + ':' + $item.Value.Name + ':Key') + + $xmlWriter.WriteStartElement('Type') + $PSTypeName = Convert-ODataTypeToCLRType $item.Value.TypeName $complexTypeMapping + $xmlWriter.WriteAttributeString('PSType', $PSTypeName) + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('RegularQuery') + $xmlWriter.WriteStartElement('CmdletParameterMetadata') + $xmlWriter.WriteAttributeString('PSName', 'Associated' + $item.Key.Name + $item.Value.Name) + $xmlWriter.WriteAttributeString('CmdletParameterSets', $item.Key.Name) + $xmlWriter.WriteAttributeString('IsMandatory', 'false') + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + } + } + + if ($isSingleton -eq $false) + { + # Add Query Parameters (i.e., Top, Skip, OrderBy, Filter) to the generated Get-* cmdlets. + $queryParameters = + @{ + "Filter" = "Edm.String"; + "IncludeTotalResponseCount" = "switch"; + "OrderBy" = "Edm.String"; + "Select" = "Edm.String"; + "Skip" = "Edm.Int32"; + "Top" = "Edm.Int32"; + } + } + else + { + $queryParameters = + @{ + "Select" = "Edm.String"; + } + } + + foreach($currentQueryParameter in $queryParameters.Keys) + { + $xmlWriter.WriteStartElement('Property') + $xmlWriter.WriteAttributeString('PropertyName', "QueryOption:" + $currentQueryParameter) + $xmlWriter.WriteStartElement('Type') + $PSTypeName = Convert-ODataTypeToCLRType $queryParameters[$currentQueryParameter] + $xmlWriter.WriteAttributeString('PSType', $PSTypeName) + $xmlWriter.WriteEndElement() + $xmlWriter.WriteStartElement('RegularQuery') + $xmlWriter.WriteStartElement('CmdletParameterMetadata') + $xmlWriter.WriteAttributeString('PSName', $currentQueryParameter) + + if($queryParameters[$currentQueryParameter] -eq "Edm.String") + { + $xmlWriter.WriteStartElement('ValidateNotNullOrEmpty') + $xmlWriter.WriteEndElement() + } + + if($queryParameters[$currentQueryParameter] -eq "Edm.Int32") + { + $xmlWriter.WriteStartElement('ValidateRange') + $xmlWriter.WriteAttributeString('Min', "1") + $xmlWriter.WriteAttributeString('Max', [int]::MaxValue) + $xmlWriter.WriteEndElement() + } + + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + } + + + $xmlWriter.WriteEndElement() + } + + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('GetCmdlet') + $xmlWriter.WriteStartElement('CmdletMetadata') + $xmlWriter.WriteAttributeString('Verb', 'Get') + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteEndElement() +} + +# Helper Method +# Returns true if navigation property of $AssociatedType has coresponding EntitySet or Singleton +# If yes, then it should become an associated parameter in CDXML +function ShouldBeAssociatedParameter +{ + param + ( + [System.Collections.ArrayList] $GlobalMetadata, + [ODataUtils.EntityTypeV4] $EntityType, + [ODataUtils.EntityTypeV4] $AssociatedType + ) + + # Check if associated type has navigation property, which links back to current type + $associatedTypeNavProperties = $AssociatedType.NavigationProperties | ? { + $_.Type -eq ($EntityType.Namespace + "." + $EntityType.Name) -or + $_.Type -eq ($EntityType.Alias + "." + $EntityType.Name) -or + $_.Type -eq ("Collection(" + $EntityType.Namespace + "." + $EntityType.Name + ")") -or + $_.Type -eq ("Collection(" + $EntityType.Alias + "." + $EntityType.Name + ")") + } + + if ($associatedTypeNavProperties.Length -lt 1) + { + return $false + } + + # Now check if associated parameter type (i.e, type of navigation property) has corresponding EntitySet or Singleton, + # which makes it accessible from the service root. + # Otherwise the Uri for associated navigation property won't be valid + foreach ($currentMetadata in $GlobalMetadata) + { + # Look for EntitySet with given type + foreach ($currentEntitySet in $currentMetadata.EntitySets) + { + if ($currentEntitySet.Type.Namespace -eq $EntityType.Namespace -and + $currentEntitySet.Type.Name -eq $EntityType.Name) + { + return $true + } + } + + # Look for Singleton with given type + foreach ($currentSingleton in $currentMetadata.Singletons) + { + if ($currentSingleton.Type.Namespace -eq $EntityType.Namespace -and + $currentSingleton.Type.Name -eq $EntityType.Name) + { + return $true + } + } + } + + return $false +} + +######################################################### +# Saves NewCmdlet node to CDXML +######################################################### +function SaveCDXMLNewCmdlet +{ + param + ( + [System.XMl.XmlTextWriter] $xmlWriter, + [ODataUtils.MetadataV4] $Metadata, + [System.Collections.ArrayList] $GlobalMetadata, + $keyProperties, + $nonNullableProperties, + $nullableProperties, + $navigationProperties, + $CmdletAdapter, + $complexTypeMapping + ) + + if($xmlWriter -eq $null) { throw ($LocalizedData.ArguementNullError -f "xmlWriter", "SaveCDXMLNewCmdlet") } + if($Metadata -eq $null) { throw ($LocalizedData.ArguementNullError -f "Metadata", "SaveCDXMLNewCmdlet") } + + $xmlWriter.WriteStartElement('Cmdlet') + $xmlWriter.WriteStartElement('CmdletMetadata') + $xmlWriter.WriteAttributeString('Verb', 'New') + $xmlWriter.WriteAttributeString('DefaultCmdletParameterSet', 'Default') + $xmlWriter.WriteAttributeString('ConfirmImpact', 'Medium') + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('Method') + $xmlWriter.WriteAttributeString('MethodName', 'Create') + $xmlWriter.WriteAttributeString('CmdletParameterSet', 'Default') + + AddParametersNode $xmlWriter $keyProperties $nonNullableProperties $nullableProperties $null $true $true $complexTypeMapping + + $xmlWriter.WriteEndElement() + + $navigationProperties | ? { $_ -ne $null } | % { + $associatedType = GetAssociatedType $Metadata $GlobalMetadata $_ + $associatedEntitySet = GetEntitySetForEntityType $Metadata $associatedType + + $xmlWriter.WriteStartElement('Method') + $xmlWriter.WriteAttributeString('MethodName', "Association:Create:$($associatedEntitySet.Name)") + $xmlWriter.WriteAttributeString('CmdletParameterSet', $_.Name) + + $associatedKeys = ($associatedType.EntityProperties | ? { $_.isKey }) + + AddParametersNode $xmlWriter $associatedKeys $keyProperties $null "Associated$($_.Name)" $true $true $complexTypeMapping + + $xmlWriter.WriteEndElement() + } + + $xmlWriter.WriteEndElement() +} + +######################################################### +# Get corresponding EntityType for given EntitySet +######################################################### +function GetEntitySetForEntityType { + param( + [ODataUtils.MetadataV4] $Metadata, + [ODataUtils.EntityTypeV4] $entityType + ) + + if($entityType -eq $null) { throw ($LocalizedData.ArguementNullError -f "EntityType", "GetEntitySetForEntityType") } + + $result = $Metadata.EntitySets | ? { ($_.Type.Namespace -eq $entityType.Namespace) -and ($_.Type.Name -eq $entityType.Name) } + + if (($result.Count -eq 0) -and ($entityType.BaseType -ne $null)) + { + GetEntitySetForEntityType $Metadata $entityType.BaseType + } + elseif ($result.Count -gt 1) + { + throw ($LocalizedData.WrongCountEntitySet -f (($entityType.Namespace + "." + $entityType.Name), $result.Count)) + } + + $result +} + +######################################################### +# Saves RemoveCmdlet node to CDXML +######################################################### +function SaveCDXMLRemoveCmdlet +{ + param + ( + [System.XMl.XmlTextWriter] $xmlWriter, + [ODataUtils.MetadataV4] $Metadata, + [System.Collections.ArrayList] $GlobalMetadata, + $keyProperties, + $navigationProperties, + $CmdletAdapter, + $complexTypeMapping + ) + + if($xmlWriter -eq $null) { throw ($LocalizedData.ArguementNullError -f "xmlWriter", "SaveCDXMLRemoveCmdlet") } + if($Metadata -eq $null) { throw ($LocalizedData.ArguementNullError -f "Metadata", "SaveCDXMLRemoveCmdlet") } + + $xmlWriter.WriteStartElement('Cmdlet') + $xmlWriter.WriteStartElement('CmdletMetadata') + $xmlWriter.WriteAttributeString('Verb', 'Remove') + $xmlWriter.WriteAttributeString('DefaultCmdletParameterSet', 'Default') + $xmlWriter.WriteAttributeString('ConfirmImpact', 'Medium') + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('Method') + $xmlWriter.WriteAttributeString('MethodName', 'Delete') + $xmlWriter.WriteAttributeString('CmdletParameterSet', 'Default') + + AddParametersNode $xmlWriter $keyProperties $nul $null $null $true $true $complexTypeMapping + + $xmlWriter.WriteEndElement() + + $navigationPrperties | ? { $_ -ne $null } | % { + + $associatedType = GetAssociatedType $Metadata $GlobalMetadata $_ + $associatedEntitySet = GetEntitySetForEntityType $Metadata $associatedType + + $xmlWriter.WriteStartElement('Method') + $xmlWriter.WriteAttributeString('MethodName', "Association:Delete:$($associatedEntitySet.Name)") + $xmlWriter.WriteAttributeString('CmdletParameterSet', $_.Name) + + $associatedType = GetAssociatedType $Metadata $GlobalMetadata $_ + $associatedKeys = ($associatedType.EntityProperties | ? { $_.isKey }) + + AddParametersNode $xmlWriter $associatedKeys $keyProperties $null "Associated$($_.Name)" $true $true $complexTypeMapping + + $xmlWriter.WriteEndElement() + } + $xmlWriter.WriteEndElement() +} + +######################################################### +# Gets associated instance's EntityType for a given navigation property +######################################################### +function GetAssociatedType { + param( + [ODataUtils.MetadataV4] $Metadata, + [System.Collections.ArrayList] $GlobalMetadata, + [ODataUtils.NavigationPropertyV4] $navProperty + ) + + $associationType = $navProperty.Type + $associationType = $associationType.Replace($Metadata.Namespace + ".", "") + $associationType = $associationType.Replace($Metadata.Alias + ".", "") + $associationType = $associationType.Replace("Collection(", "") + $associationType = $associationType.Replace(")", "") + + $associatedType = $Metadata.EntityTypes | ? { $_.Name -eq $associationType } + + if (!$associatedType -and $GlobalMetadata -ne $null) + { + $associationFullTypeName = $navProperty.Type.Replace("Collection(", "").Replace(")", "") + + foreach ($referencedMetadata in $GlobalMetadata) + { + if (($associatedType = $referencedMetadata.EntityTypes | Where { $_.Namespace + "." + $_.Name -eq $associationFullTypeName -or $_.Alias + "." + $_.Name -eq $associationFullTypeName }) -ne $null -or + ($associatedType = $referencedMetadata.ComplexTypes | Where { $_.Namespace + "." + $_.Name -eq $associationFullTypeName -or $_.Alias + "." + $_.Name -eq $associationFullTypeName }) -ne $null -or + ($associatedType = $referencedMetadata.EnumTypes | Where { $_.Namespace + "." + $_.Name -eq $associationFullTypeName -or $_.Alias + "." + $_.Name -eq $associationFullTypeName }) -ne $null) + { + # Found associated class + break + } + } + } + + if ($associatedType.Count -lt 1) + { + throw ($LocalizedData.AssociationNotFound -f $associationType) + } + elseif ($associatedType.Count -gt 1) + { + throw ($LocalizedData.TooManyMatchingAssociationTypes -f $associatedType.Count, $associationType) + } + + # return associated EntityType + $associatedType +} + +######################################################### +# Saves CDXML for Instance/Service level actions +######################################################### +function SaveCDXMLAction +{ + param + ( + [System.Xml.XmlWriter] $xmlWriter, + [ODataUtils.ActionV4] $action, + [AllowEmptyString()] + [string] $noun, + [bool] $isInstanceAction, + [ODataUtils.TypeProperty] $keys, + [Hashtable] $complexTypeMapping + ) + + if($xmlWriter -eq $null) { throw ($LocalizedData.ArguementNullError -f "xmlWriter", "SaveCDXMLAction") } + if($action -eq $null) { throw ($LocalizedData.ArguementNullError -f "action", "SaveCDXMLAction") } + + $xmlWriter.WriteStartElement('Cmdlet') + + $xmlWriter.WriteStartElement('CmdletMetadata') + $xmlWriter.WriteAttributeString('Verb', 'Invoke') + $xmlWriter.WriteAttributeString('Noun', "$($noun)$($action.Name)") + $xmlWriter.WriteAttributeString('ConfirmImpact', 'Medium') + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('Method') + $xmlWriter.WriteAttributeString('MethodName', "Action:$($action.Name):$($action.EntitySet.Name)") + + $xmlWriter.WriteStartElement('Parameters') + + $keys | ? { $_ -ne $null } | % { + $xmlWriter.WriteStartElement('Parameter') + $xmlWriter.WriteAttributeString('ParameterName', $_.Name + ':Key') + + $xmlWriter.WriteStartElement('Type') + $PSTypeName = Convert-ODataTypeToCLRType $_.TypeName $complexTypeMapping + $xmlWriter.WriteAttributeString('PSType', $PSTypeName) + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('CmdletParameterMetadata') + $xmlWriter.WriteAttributeString('PSName', $_.Name) + $xmlWriter.WriteAttributeString('IsMandatory', 'true') + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + } + + $i = -1 + foreach ($parameter in $action.Parameters) + { + $i++ + + # for Instance actions, first parameter is Entity Set which we refer to using keys + if ($isInstanceAction -and ($i -eq 0)) + { + continue + } + + $xmlWriter.WriteStartElement('Parameter') + $xmlWriter.WriteAttributeString('ParameterName', $parameter.Name) + + $xmlWriter.WriteStartElement('Type') + $PSTypeName = Convert-ODataTypeToCLRType $parameter.TypeName + $xmlWriter.WriteAttributeString('PSType', $PSTypeName) + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('CmdletParameterMetadata') + $xmlWriter.WriteAttributeString('PSName', $parameter.Name) + if (-not $parameter.IsNullable) + { + $xmlWriter.WriteAttributeString('IsMandatory', 'true') + } + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + } + + # Add -Force parameter to Service Action cmdlets. + AddParametersNode $xmlWriter $null $null $null $null $true $false $complexTypeMapping + + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteEndElement() + + $xmlWriter +} + +######################################################### +# Saves CDXML for Instance/Service level functions +######################################################### +function SaveCDXMLFunction +{ + param + ( + [System.Xml.XmlWriter] $xmlWriter, + [ODataUtils.FunctionV4] $function, + [AllowEmptyString()] + [string] $noun, + [bool] $isInstanceAction, + [ODataUtils.TypeProperty] $keys, + [Hashtable] $complexTypeMapping + ) + + if($xmlWriter -eq $null) { throw ($LocalizedData.ArguementNullError -f "xmlWriter", "SaveCDXMLFunction") } + if($function -eq $null) { throw ($LocalizedData.ArguementNullError -f "function", "SaveCDXMLFunction") } + + $xmlWriter.WriteStartElement('Cmdlet') + + $xmlWriter.WriteStartElement('CmdletMetadata') + $xmlWriter.WriteAttributeString('Verb', 'Invoke') + $xmlWriter.WriteAttributeString('Noun', "$($noun)$($function.Name)") + $xmlWriter.WriteAttributeString('ConfirmImpact', 'Medium') + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('Method') + if (!$function.EntitySet) + { + $xmlWriter.WriteAttributeString('MethodName', "Action:$($function.Name):$($function.ReturnType)") + } + else + { + $xmlWriter.WriteAttributeString('MethodName', "Action:$($function.Name):$($function.EntitySet)") + } + + $xmlWriter.WriteStartElement('Parameters') + + $keys | ? { $_ -ne $null } | % { + $xmlWriter.WriteStartElement('Parameter') + $xmlWriter.WriteAttributeString('ParameterName', $_.Name + ':Key') + + $xmlWriter.WriteStartElement('Type') + $PSTypeName = Convert-ODataTypeToCLRType $_.TypeName $complexTypeMapping + $xmlWriter.WriteAttributeString('PSType', $PSTypeName) + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('CmdletParameterMetadata') + $xmlWriter.WriteAttributeString('PSName', $_.Name) + $xmlWriter.WriteAttributeString('IsMandatory', 'true') + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + } + + $i = -1 + foreach ($parameter in $function.Parameters) + { + $i++ + + # for Instance actions, first parameter is Entity Set which we refer to using keys + if ($isInstanceAction -and ($i -eq 0)) + { + continue + } + + $xmlWriter.WriteStartElement('Parameter') + $xmlWriter.WriteAttributeString('ParameterName', $parameter.Name) + + $xmlWriter.WriteStartElement('Type') + $PSTypeName = Convert-ODataTypeToCLRType $parameter.Type + $xmlWriter.WriteAttributeString('PSType', $PSTypeName) + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('CmdletParameterMetadata') + $xmlWriter.WriteAttributeString('PSName', $parameter.Name) + if (-not $parameter.IsNullable) + { + $xmlWriter.WriteAttributeString('IsMandatory', 'true') + } + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + } + + # Add -Force parameter to Service Function cmdlets. + AddParametersNode $xmlWriter $null $null $null $null $true $false $complexTypeMapping + + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteEndElement() + + $xmlWriter +} + +######################################################### +# Saves CDXML for Service-level actions and functions +######################################################### +function SaveServiceActionsCDXML +{ + param + ( + [System.Collections.ArrayList] $GlobalMetadata, + [ODataUtils.ODataEndpointProxyParameters] $ODataEndpointProxyParameters, + [string] $Path, + [Hashtable] $complexTypeMapping, + [string] $progressBarStatus, + [string] $CmdletAdapter + ) + + $xmlWriter = New-Object System.XMl.XmlTextWriter($Path,$Null) + + if ($xmlWriter -eq $null) + { + throw $LocalizedData.XmlWriterInitializationError -f "ServiceActions" + } + + $xmlWriter = SaveCDXMLHeader $xmlWriter $ODataEndpointProxyParameters.Uri 'ServiceActions' 'ServiceActions' -CmdletAdapter $CmdletAdapter + + $actions = @() + $functions = @() + + foreach ($Metadata in $GlobalMetadata) + { + $actions += $Metadata.Actions | Where-Object { $_.EntitySet -eq '' -or $_.EntitySet -eq $null } + $functions += $Metadata.Functions | Where-Object { $_.EntitySet -eq '' -or $_.EntitySet -eq $null } + } + + if ($actions.Length -gt 0 -or $functions.Length -gt 0) + { + $xmlWriter.WriteStartElement('StaticCmdlets') + } + + # Save actions + if ($actions.Length -gt 0) + { + foreach ($action in $actions) + { + if ($action -ne $null) + { + $xmlWriter = SaveCDXMLAction $xmlWriter $action '' $false $null $complexTypeMapping + } + } + } + + # Save functions + if ($functions.Length -gt 0) + { + foreach ($function in $functions) + { + if ($function -ne $null) + { + $xmlWriter = SaveCDXMLFunction $xmlWriter $function '' $false $null $complexTypeMapping + } + } + } + + if ($actions.Length -gt 0 -or $functions.Length -gt 0) + { + $xmlWriter.WriteEndElement() + } + + $xmlWriter.WriteStartElement('CmdletAdapterPrivateData') + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'Namespace') + $xmlWriter.WriteString("$($EntitySet.Namespace)") + $xmlWriter.WriteEndElement() + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'Alias') + if (!$EntitySet.Alias) + { + $xmlWriter.WriteString("") + } + else + { + $xmlWriter.WriteString("$($EntitySet.Alias)") + } + $xmlWriter.WriteEndElement() + + $xmlWriter.WriteStartElement('Data') + $xmlWriter.WriteAttributeString('Name', 'CreateRequestMethod') + $xmlWriter.WriteString("Post") + $xmlWriter.WriteEndElement() + $xmlWriter.WriteEndElement() + + SaveCDXMLFooter $xmlWriter + + Write-Verbose ($LocalizedData.VerboseSavedServiceActions -f $Path) + + # Write progress bar message + ProgressBarHelper "Export-ODataEndpointProxy" $progressBarStatus 60 20 1 1 +} + +######################################################### +# GenerateModuleManifest is a helper function used +# to generate a wrapper module manifest file. The +# generated module manifest is persisted to the disk at +# the specified OutputModule path. When the module +# manifest is imported, the following comands will +# be imported: +# 1. Get, Set, New & Remove proxy cmdlets for entity +# sets and singletons. +# 2. If the server side Odata endpoint exposes complex +# types, enum types, type definitions, then the corresponding +# client side proxy types imported. +# 3. Service Action/Function proxy cmdlets. +######################################################### +function GenerateModuleManifest +{ + param + ( + [System.Collections.ArrayList] $GlobalMetadata, + [String] $ModulePath, + [string[]] $AdditionalModules, + [Hashtable] $resourceNameMappings, + [string] $progressBarStatus + ) + + if($progressBarStatus -eq $null) { throw ($LocalizedData.ArguementNullError -f "progressBarStatus", "GenerateModuleManifest") } + + $NestedModules = @() + + foreach ($Metadata in $GlobalMetadata) + { + foreach ($entitySet in $Metadata.EntitySets) + { + $entitySetName = $entitySet.Name + if(($null -ne $resourceNameMappings) -and + $resourceNameMappings.ContainsKey($entitySetName)) + { + $entitySetName = $resourceNameMappings[$entitySetName] + } + else + { + $entitySetName = $entitySet.Type.Name + } + + $NestedModules += "$OutputModule\$($entitySetName).cdxml" + } + + foreach ($singleton in $Metadata.SingletonTypes) + { + $singletonName = $singleton.Name + $NestedModules += "$OutputModule\$($singletonName)" + "Singleton" + ".cdxml" + } + } + + New-ModuleManifest -Path $ModulePath -NestedModules ($AdditionalModules + $NestedModules) + + Write-Verbose ($LocalizedData.VerboseSavedModuleManifest -f $ModulePath) + + # Update the Progress Bar. + ProgressBarHelper "Export-ODataEndpointProxy" $progressBarStatus 80 20 1 1 +} + +######################################################### +# This is a helper function used to generate comlplex +# type defination from the metadata. +######################################################### +function GenerateComplexTypeDefinition +{ + param + ( + [System.Collections.ArrayList] $GlobalMetadata, + [string] $OutputModule, + [string] $typeDefinationFileName, + $normalizedNamespaces + ) + + $Path = "$OutputModule\$typeDefinationFileName" + $date = Get-Date + + $output = @" +# This module was generated by PSODataUtils on $date. + +`$typeDefinitions = @" +using System; +using System.Management.Automation; +using System.ComponentModel; + +"@ + # We are currently generating classes for EntityType & ComplexType + # defination exposed in the metadata. + + $complexTypeMapping = @{} + + # First, create complex type mappings for all metadata files at once + foreach ($metadata in $GlobalMetadata) + { + $typesToBeGenerated = $metadata.EntityTypes+$metadata.ComplexTypes + $enumTypesToBeGenerated = $metadata.EnumTypes + $typeDefinitionsToBeGenerated = $metadata.TypeDefinitions + + foreach ($entityType in $typesToBeGenerated) + { + if ($entityType -ne $null) + { + $entityTypeFullName = $entityType.Namespace + '.' + $entityType.Name + if(!$complexTypeMapping.ContainsKey($entityTypeFullName)) + { + $complexTypeMapping.Add($entityTypeFullName, $entityType.Name) + } + + # In short name we use Alias instead of Namespace + # We will add short name to $complexTypeMapping to enable Alias based search + if ($entityType.Alias -ne $null -and $entityType.Alias -ne "") + { + $entityTypeShortName = $entityType.Alias + '.' + $entityType.Name + if(!$complexTypeMapping.ContainsKey($entityTypeShortName)) + { + $complexTypeMapping.Add($entityTypeShortName, $entityType.Name) + } + } + } + } + + foreach ($enumType in $enumTypesToBeGenerated) + { + if ($enumType -ne $null) + { + $enumTypeFullName = $enumType.Namespace + '.' + $enumType.Name + if(!$complexTypeMapping.ContainsKey($enumTypeFullName)) + { + $complexTypeMapping.Add($enumTypeFullName, $enumType.Name) + } + + if (($enumType.Alias -ne $null -and $enumType.Alias -ne "") -or ($metadata.Alias -ne $null -and $metadata.Alias -ne "")) + { + if ($enumType.Alias -ne $null -and $enumType.Alias -ne "") + { + $alias = $enumType.Alias + } + else + { + $alias = $metadata.Alias + } + + $enumTypeShortName = $alias + '.' + $enumType.Name + if(!$complexTypeMapping.ContainsKey($enumTypeShortName)) + { + $complexTypeMapping.Add($enumTypeShortName, $enumType.Name) + } + } + } + } + + foreach ($typeDefinition in $typeDefinitionsToBeGenerated) + { + if ($typeDefinition -ne $null) + { + $typeDefinitionFullName = $typeDefinition.Namespace + '.' + $typeDefinition.Name + if(!$complexTypeMapping.ContainsKey($typeDefinitionFullName)) + { + $complexTypeMapping.Add($typeDefinitionFullName, $typeDefinition.Name) + } + + # In short name we use Alias instead of Namespace + # We will add short name to $complexTypeMapping to enable Alias based search + if ($typeDefinition.Alias) + { + $typeDefinitionShortName = $typeDefinition.Alias + '.' + $typeDefinition.Name + if(!$complexTypeMapping.ContainsKey($typeDefinitionShortName)) + { + $complexTypeMapping.Add($typeDefinitionShortName, $typeDefinition.Name) + } + } + } + } + } + + # Now classes definitions will be generated + foreach ($metadata in $GlobalMetadata) + { + $typesToBeGenerated = $metadata.EntityTypes+$metadata.ComplexTypes + $enumTypesToBeGenerated = $metadata.EnumTypes + $typeDefinitionsToBeGenerated = $metadata.TypeDefinitions + + if($typesToBeGenerated.Count -gt 0 -or $enumTypesToBeGenerated.Count -gt 0) + { + if ($metadata.Alias -ne $null -and $metadata.Alias -ne "") + { + # Check if this namespace has to be normalized in the .Net namespace/class definitions file. + $dotNetAlias = GetNamespace $metadata.Alias $normalizedNamespaces + + $output += @" + +namespace $($dotNetAlias) +{ +"@ + } + else + { + # Check if this namespace has to be normalized in the .Net namespace/class definitions file. + $dotNetNamespace = GetNamespace $metadata.Namespace $normalizedNamespaces + + $output += @" + +namespace $($dotNetNamespace) +{ +"@ + } + + foreach ($typeDefinition in $typeDefinitionsToBeGenerated) + { + if ($typeDefinition -ne $null) + { + Write-Verbose ($LocalizedData.VerboseAddingTypeDefinationToGeneratedModule -f $typeDefinitionFullName, "$OutputModule\$typeDefinationFileName") + + $output += "`n public class $($typeDefinition.Name)`n {" + $typeName = Convert-ODataTypeToCLRType $typeDefinition.BaseTypeStr $complexTypeMapping + $dotNetPropertyNamespace = GetNamespace $typeName $normalizedNamespaces $true + $output += "`n public $dotNetPropertyNamespace value;" + $output += @" +`n } +"@ + } + } + + $DotNETKeywords = ("abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "in", "int", "interface", "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while", "add", "alias", "ascending", "async", "await", "descending", "dynamic", "from", "get", "global", "group", "into", "join", "let", "orderby", "partial", "partial", "remove", "select", "set", "value", "var", "where", "yield") + + foreach ($enumType in $enumTypesToBeGenerated) + { + if ($enumType -ne $null) + { + $enumTypeFullName = $enumType.Namespace + '.' + $enumType.Name + + Write-Verbose ($LocalizedData.VerboseAddingTypeDefinationToGeneratedModule -f $enumTypeFullName, "$OutputModule\$typeDefinationFileName") + + $output += "`n public enum $($enumType.Name)`n {" + + $properties = $null + + for($index = 0; $index -lt $enumType.Members.Count; $index++) + { + $memberName = $enumType.Members[$index].Name + $formattedMemberName = [System.Text.RegularExpressions.Regex]::Replace($memberName, "[^0-9a-zA-Z]", "_"); + $memberValue = $enumType.Members[$index].Value + + if ($DotNETKeywords -contains $formattedMemberName) + { + # If member name is a known keyword in .Net, add '@' prefix + $formattedMemberName = '@' + $formattedMemberName + } + + if ($formattedMemberName -match "^[0-9]*$") + { + # If member name is a numeric value, add 'm_' prefix + $formattedMemberName = 'm_' + $formattedMemberName + } + + if ($memberName -ne $formattedMemberName -or $formattedMemberName -like '@*' -or $formattedMemberName -like 'm_*') + { + # Add Description attribute to preserve original value + $properties += "`n [Description(`"$($memberName)`")]$formattedMemberName" + } + else + { + $properties += "`n $memberName" + } + + if ($memberValue) + { + $properties += " = $memberValue," + } + else + { + $properties += "," + } + } + + $output += $properties + $output += @" +`n } +"@ + } + } + + foreach ($entityType in $typesToBeGenerated) + { + if ($entityType -ne $null) + { + $entityTypeFullName = $entityType.Namespace + '.' + $entityType.Name + + Write-Verbose ($LocalizedData.VerboseAddingTypeDefinationToGeneratedModule -f $entityTypeFullName, "$OutputModule\$typeDefinationFileName") + + if ($entityType.BaseTypeStr -ne $null -and $entityType.BaseTypeStr -ne '' -and $entityType.BaseType -eq $null) + { + # This class inherits from another class, but we were not able to find base class during Parsing. + # We'll make another attempt. + foreach ($referencedMetadata in $GlobalMetadata) + { + if (($baseType = $referencedMetadata.EntityTypes | Where { $_.Namespace + "." + $_.Name -eq $entityType.BaseTypeStr -or $_.Alias + "." + $_.Name -eq $entityType.BaseTypeStr }) -ne $null -or + ($baseType = $referencedMetadata.ComplexTypes | Where { $_.Namespace + "." + $_.Name -eq $entityType.BaseTypeStr -or $_.Alias + "." + $_.Name -eq $entityType.BaseTypeStr }) -ne $null) + { + # Found base class + $entityType.BaseType = $baseType + break + } + } + } + + if($null -ne $entityType.BaseType) + { + if ((![string]::IsNullOrEmpty($entityType.BaseType.Alias) -and $entityType.BaseType.Alias -eq $entityType.Alias) -or + (![string]::IsNullOrEmpty($entityType.BaseType.Namespace) -and $entityType.BaseType.Namespace -eq $entityType.Namespace)) + { + $fullBaseTypeName = $entityType.BaseType.Name + } + else + { + # Base type can be defined in different namespace. For that reason we include namespace or alias. + if (![string]::IsNullOrEmpty($entityType.BaseType.Alias)) + { + # Check if derived alias has to be normalized. + $normalizedDotNetAlias = GetNamespace $entityType.BaseType.Alias $normalizedNamespaces + $fullBaseTypeName = $normalizedDotNetAlias + "." + $entityType.BaseType.Name + } + else + { + # Check if derived namespace has to be normalized. + $normalizedDotNetNamespace = GetNamespace $entityType.BaseType.Namespace $normalizedNamespaces + $fullBaseTypeName = $normalizedDotNetNamespace + "." + $entityType.BaseType.Name + } + } + + $output += "`n public class $($entityType.Name) : $($fullBaseTypeName)`n {" + } + else + { + $output += "`n public class $($entityType.Name)`n {" + } + + $properties = $null + + for($index = 0; $index -lt $entityType.EntityProperties.Count; $index++) + { + $property = $entityType.EntityProperties[$index] + $typeName = Convert-ODataTypeToCLRType $property.TypeName $complexTypeMapping + + if ($typeName.StartsWith($metadata.Namespace + ".")) + { + $dotNetPropertyNamespace = $typeName.Replace($metadata.Namespace + ".", "") + } + elseif ($typeName.StartsWith($metadata.Alias + ".")) + { + $dotNetPropertyNamespace = $typeName.Replace($metadata.Alias + ".", "") + } + else + { + $dotNetPropertyNamespace = GetNamespace $typeName $normalizedNamespaces $true + } + + $properties += "`n public $dotNetPropertyNamespace $($property.Name);" + } + + $output += $properties + $output += @" +`n } +"@ + } + } + + $output += "`n}`n" + } + } + $output += """@`n" + $output += "Add-Type -TypeDefinition `$typeDefinitions -IgnoreWarnings`n" + $output | Out-File -FilePath $Path + Write-Verbose ($LocalizedData.VerboseSavedTypeDefinationModule -f $typeDefinationFileName, $OutputModule) + + return $complexTypeMapping +} \ No newline at end of file diff --git a/src/Modules/Microsoft.PowerShell.ODataUtils/en-US/Microsoft.PowerShell.ODataUtilsStrings.psd1 b/src/Modules/Microsoft.PowerShell.ODataUtils/en-US/Microsoft.PowerShell.ODataUtilsStrings.psd1 new file mode 100644 index 0000000000000000000000000000000000000000..6010408f1d1c33fb3844be3c0dc7de214a303190 GIT binary patch literal 12018 zcmdU#+fQ7{5yty@rM&OH9cd$NRthMa>{FzXLNJbyY_DZty~-OfV~hebguym!lz%%U-F@Z^=3yY5wARnLF_^L6UdvouSGX+NE$*-8C$LYKDoAgEg-qh}Cdar%wTJ=;vXX!MpY5#@(KGwUVkLPshFX@}S z>+8f9RGx{>W`4G#Gfwn!omo=x*UDED`EdNb9! zEB%H>r*qN3p?1$Rr##!&v%^fG<)=%(TX6nu#rcs=nuw2yPQDP&@N$y2bOtA*iKjXd zd)QVNdfG|LtVdJW4BpMjrFeq_WGi|K$gx-!*i)kCd<-To4EEwE8Unw8rq-PCBp#$pshsLb74*cO}7D z=HlV`FSPC>LErQ7;^UmB&?S1gklrr!48IwYYMvz~lf9ATL=4_V6u!-RyP2&fA8Fi2 z8sg_i(RZ|MXV128y%B$87FP6S{*+YgEOHIW(|Q^{xGy@+J0MnA_Q7u=J{i0aF{HoUkKJ!(Q7-Tl0LsQ2VbBA9q9 zd9PSvS>r?bzpXn%nYZ?}Pg&*j`O#0(&dDQt&QJ2%XVUH6b5+4YKgwR`if7x)G5$1X zKdR0Bqv6w;IC4YbsZ-q6Ts@qmtFRM(UGrl+7+Pv;&5$3qakh*aPNZQls`1)&S<)CK z@J&>+W#opAO14hMmfmYiPhgPR<~KA zMs01ri41XfFD8GNys{&WQe{r1*BAOm>(~ZlGWiUiY&?x+OD?u&?kO6dNoSy0kVPQD z$lBoFIy0}fBDltIo

-qov?0Ie6aOC1Ko;3ZfJj0r+3=V8xX ztwGoC^_v=7*TiEzkJ<(zj~=FQ2DKU~!WVS$ea><};&{8Og#yLSa~&$)xS45@%^%A? zVV71PXdI1(CJ&?|Ru)apcUhfh?$(#Q$~pk^&Si%eS;ur)`_ij>?s{I(uXMJ|bL|G(&2$D& z(BaF4e$UlC5m9J-y{ejJ%3{ls1E=Y$&NGjC^3dfDd#rQKBepdHCF>BM=kkMT?x(-( z*y-MUqPa{v-?$&2Uv&|mL@Ru@y6a;~?d6cOe?;dD1{*Ko%+p#3e{ZjjWs5dG;<&LeLL$%ai zik3S7bi7QheZNd?T^bmY!c>?9T&m1$1D?3e_L2$8l zwf7h9f-5G^*K_q;ei}37=h7XK%Dl%@p_;2!+aU9Ltr2bOn;SZX8p8~!88=YDYlV%o%0^XSp!xiyv&l}zwxfm-It_yd8WA|53 z4#aXBUg@EH5NIF?UqiCMNSBX>K5xR)wcW&a15e zCs=++=j<#|L3LsEkz&qPWd7K%w&ds`xxo#~tBb$a@4{ZeIS9l(7B>-|AlIDLd(p|M zWbb!RTjD-y-pl-#?=Jc?GHeaD4P7nw_U>^eS#PJgo)FnaNJBCjLA$~dbKDL&M>)o$ zGR_yAw`YVdjFLUKMLxQYxD)AA({4J!@J&|qW~Fy&sgmi8{p-62VvfkIClqi`4B|ug zm9d_4T%YqoD^J9yab3wybv|sfa_j;D$3CMPM?sq(kutPp35zaDp1^P%THo1ljN9PzGT`GCu%#>?sH{`u|4*qjz4%&mQ77A`iXOC6ZHOl7hz-&X#vudD zjIyqgw$;?obk!2Asn;ytRG&GlpPNsjPi3>fH{@mOdD(+&njy!wG-Z#b3p`H$6pu_F z)$*?tj?v=jr_|xorEchWzksj~rmRFKMM&S0g=jjGP4 z&F$27=hNsox?H32FuGkMm-&KbV3DXHk>P4g)lMs-CUO?HCVW}}FQk$}qup6*S6z#i z=gqDoAha5}vM26B;LLTH-ORV_|ImzFXp9XvZ6$Kugx3>sNgULas27~l?rHBwjMxqp zfn%LvbmVxbSpL{vnAgU|81PQ0|=C*orgpTBc)s zB7q%6FRLQrcG~>4L`f@qtI3;XtD9;x{Ist}@=cjD)l()`7Q6h?{@U`@&c9mB)vqF< zk;m}c&!ydm@ZXzj^!C~Qm-AzKJ>LX^$LI3iL)9kGigiymWDen&j Date: Mon, 20 Jun 2016 17:52:09 -0700 Subject: [PATCH 5/5] Update KNOWNISSUES about ControlPanelItemCommand.cs [skip ci] --- docs/KNOWNISSUES.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/KNOWNISSUES.md b/docs/KNOWNISSUES.md index 5b6587183..3454cb611 100644 --- a/docs/KNOWNISSUES.md +++ b/docs/KNOWNISSUES.md @@ -15,10 +15,8 @@ with `PlatformNotSupportedException`. ## `ControlPanelItemCommand.cs` -The file `monad/src/commands/management/ControlPanelItemCommand.cs` has been removed -temporarily from `Microsoft.PowerShell.Commands.Management` because we -cannot resolve `[Shell32.ShellFolderItem]` for FullCLR builds. This must be -fixed ASAP. +The file `ControlPanelItemCommand.cs` is excluded from all frameworks in `Microsoft.PowerShell.Commands.Management` +because it has dependency on `[Shell32.ShellFolderItem]` for FullCLR builds. ## `GetComputerInfoCommand.cs`