using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; using System.Management.Automation; using System.Management.Automation.Provider; using System.Management.Automation.Runspaces; namespace Intel.Management.Module { /// /// This sample implements a Windows PowerShell provider class /// that acts upon AMT Hardware. /// /// /// Get-PSDrive /// $DebugPreference = "Continue" /// $DebugPreference = "SilentlyContinue" /// [CmdletProvider("AmtSystem", ProviderCapabilities.None)] public class AmtDriveProvider : NavigationCmdletProvider, IPropertyCmdletProvider, IContentCmdletProvider { public class NewDriveParameters { [Parameter(Mandatory = false)] public string ComputerName { get { return _computerName; } set { _computerName = value; } } [Parameter(Mandatory = false)] public int Port { get { return _port; } set { _port = value; } } string _computerName; int _port; } //In this context, an "item" is an element of data within a data store. /* MSH> MSH>$a = "foobar" MSH>$a = $a | AddNote CreatedBy Me MSH>$a.CreatedBy Me*/ //[convert]::ToBase64String /* Dynamic properties public class SendGreetingCommandDynamicParameters { [Parameter(Mandatory = true)] [Parameter] [ValidateSet ("Marketing", "Sales", "Development")] public string Department { get { return department; } set { department = value; } } private string department; } */ NewDriveParameters _driveParams; public AmtDriveProvider() : base() { //WriteDebug("New AmtDriverProvider"); //_heci = new HECIClass(); //this.get } /// /// The Windows PowerShell engine calls this method when the /// New-PSDrive cmdlet is run and the path to this provider is /// specified. This method creates a connection to the database /// file and sets the Connection property of the PSDriveInfo object. /// /// /// Information describing the drive to create. /// /// An AmtDriveInfo object that represents /// the new drive. protected override PSDriveInfo NewDrive(PSDriveInfo drive) { WriteDebug("AMT NewDrive"); PSDriveInfo result = null; result = new AmtDriveInfo(drive); //check root for valid store return result; } protected override object NewDriveDynamicParameters() { return _driveParams = new NewDriveParameters(); } private Collection _drives; /// /// When the provider engine starts a provider, the InitializeDefaultDrives method /// is called. This is an opportunity for the provider to mount drives that are /// important to it. /// /// A collection of PSDriveInfo objects for each drive the provider /// wants to mount. protected override Collection InitializeDefaultDrives() { if (_drives == null) { WriteDebug("Initializing amt drive"); _drives = new Collection(); _drives.Add( new PSDriveInfo("AMT",ProviderInfo,string.Empty, "Intel(r) AMT Subsystem",Credential)); } return _drives; } /// /// The Windows PowerShell engine calls this method when the /// Remove-PSDrive cmdlet is run and the path to this provider is /// specified. This method closes a hardware connection /// /// The drive to remove. /// An AMTDrive object that represents /// the removed drive. protected override PSDriveInfo RemoveDrive(PSDriveInfo drive) { // WriteDebug("Removing AMT Drive"); //if (string.Compare(AmtRootItem.DriveName, drive.Name, true) == 0) // { // //((AmtDriveInfo)drive).r //} //_paths.Clear(); return drive; } // End RemoveDrive. /// /// Test to see if the specified path is syntactically valid. /// /// The path to validate. /// True if the specified path is valid. protected override bool IsValidPath(string path) { WriteDebug("Is Path value for " +path); AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; object item = info.GetItemFromPath(path); return item != null; } /// /// Sets or Changes the value of an item /// parameter. /// /// Specifies the path to the item /// Comma separated string of values protected override void SetItem(string path, object values) { AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; object item = info.GetItemFromPath(path); } /// /// Create a new Item /// parameter. /// /// Specifies the path to the item /// The Type of the new Item /// The value of the new Item protected override void NewItem(string path,string itemTypeName, object newItemValue) { AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; DriveItem item = null; //split the path char[] pathChar = { '\\', '/' }; string[] paths = path.Split(pathChar, StringSplitOptions.RemoveEmptyEntries); int index = paths.Length; string searchPath = path; item = info.GetItemFromPath(searchPath); while (item == null) { index--; searchPath = GetParentPath(searchPath, info.Root); if (searchPath == null) break; item = info.GetItemFromPath(searchPath); } if (((path.Length - index) > 1) && !Force.IsPresent) throw new InvalidOperationException(); for (int i = index; i < paths.Length && item != null; i++) { item = item.NewItem(paths[i], itemTypeName, newItemValue, null,Force.IsPresent); } if (item!=null) WriteItemObject(item, path, false); } protected override object NewItemDynamicParameters(string path, string itemTypeName, object newItemValue) { AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; DriveItem item = null; string searchPath = path; item = info.GetItemFromPath(searchPath); while (item == null) { searchPath = GetParentPath(searchPath, info.Root); if (searchPath == null) break; item = info.GetItemFromPath(searchPath); } if (item != null) return item.NewItemDynamicParameters(itemTypeName, newItemValue); return base.NewItemDynamicParameters(path, itemTypeName, newItemValue); } /// /// Removes an Item /// protected override void RemoveItem(string path, bool recurse) { AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; DriveItem item = info.GetItemFromPath(path); item.RemoveItem(Force.IsPresent); } protected override void InvokeDefaultAction(string path) { AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; DriveItem item = info.GetItemFromPath(path); item.Invoke(Force.IsPresent); //this.NewDriveDynamicParameters( //this. } protected override object InvokeDefaultActionDynamicParameters(string path) { AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; DriveItem item = info.GetItemFromPath(path); return item.InvokeDefaultActionDynamicParameters(); throw new InvalidOperationException(path); } /// /// Retrieves an item using the specified path. /// /// The path to the item to return. protected override void GetItem(string path) { WriteDebug("GetItem " + path); AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; DriveItem item = info.GetItemFromPath(path); WriteItemObject(item, path, item is DriveContainer); } /// /// Test to see if the specified item exists. /// /// The path to the item to verify. /// True if the item is found. protected override bool ItemExists(string path) { WriteDebug("Path Exists for " + path); AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; DriveItem item = info.GetItemFromPath(path); return item != null; } /// /// Returns Children of a container /// protected override void GetChildItems(string path, bool recurse) { WriteDebug("Geting path information for " + path); AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; //IsContainer already passed DriveContainer parent = (DriveContainer)info.GetItemFromPath(path); foreach (DriveItem item in parent.GetChildItems(Force.IsPresent)) { WriteItemObject(item, path + "\\" + item.Name, item is DriveContainer); if (recurse && (item is DriveContainer)) GetChildItems(path + "\\" + item.Name, item is DriveContainer); } } /// /// Return the names of all child items. /// /// The root path. /// Not used. protected override void GetChildNames(string path, ReturnContainers returnContainers) { WriteDebug("Geting path information for " + path); AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; DriveContainer parent = (DriveContainer)info.GetItemFromPath(path); foreach (DriveItem item in parent.GetChildItems(Force.IsPresent)) { WriteItemObject(item.Name, path + "\\" + item.Name, item is DriveContainer); } } /// /// Determines if the specified path has child items. /// /// The path to examine. /// /// True if the specified path has child items. /// protected override bool HasChildItems(string path) { AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; DriveItem item = info.GetItemFromPath(path); return item is DriveContainer; } /// /// Determine if the path specified is that of a container. /// /// The path to check. /// True if the path specifies a container. protected override bool IsItemContainer(string path) { WriteDebug("IsItemContainer: " + path); AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; DriveItem item = info.GetItemFromPath(path); return item is DriveContainer; } /// /// Throws an argument exception stating that the specified path does /// not represent either a table or a row /// /// path which is invalid private void ThrowTerminatingInvalidPathException(string path) { StringBuilder message = new StringBuilder("Invalid AmtSystem path:"); message.Append(path); throw new ArgumentException(message.ToString()); } /// /// Get the name of the leaf element in the specified path /// /// /// /// The full or partial provider specific path /// /// /// /// The leaf element in the path /// protected override string GetChildName(string path) { return base.GetChildName(path); /*if (PathIsDrive(path)) { return path; } int pos = path.LastIndexOf("\\", StringComparison.OrdinalIgnoreCase)+1; if (pos < 0) pos = path.LastIndexOf("/", StringComparison.OrdinalIgnoreCase)+1; //if (pos < 0) // ThrowTerminatingInvalidPathException(path); return path.Substring(pos);*/ } /// /// Removes the child segment of the path and returns the remaining /// parent portion /// /// /// /// A full or partial provider specific path. The path may be to an /// item that may or may not exist. /// /// /// /// The fully qualified path to the root of a drive. This parameter /// may be null or empty if a mounted drive is not in use for this /// operation. If this parameter is not null or empty the result /// of the method should not be a path to a container that is a /// parent or in a different tree than the root. /// /// /// protected override string GetParentPath(string path, string root) { return base.GetParentPath(path, root); // return parentpath } public void ClearProperty(string path, Collection propertyToClear) { } public object ClearPropertyDynamicParameters(string path, Collection propertyToClear) { return null; } public void GetProperty (string path, Collection providerSpecificPickList) { AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; DriveItem item = info.GetItemFromPath(path); WritePropertyObject(item.GetProperty(providerSpecificPickList,Force.IsPresent),path); //The implementation of this method returns a PSObject object by calling the WritePropertyObject methods // add note } public void SetProperty(string path, PSObject propertyValue) { AmtDriveInfo info = (AmtDriveInfo)PSDriveInfo; DriveItem item = info.GetItemFromPath(path); item.SetProperty(propertyValue, Force.IsPresent); WritePropertyObject(propertyValue, path); } public object GetPropertyDynamicParameters(string path, Collection providerSpecificPickList) { return null; } public object SetPropertyDynamicParameters(string path,PSObject propertyValue) { return null; } public object ClearContentDynamicParameters(string path) { return null; } public void ClearContent(string path) { } public object GetContentWriterDynamicParameters(string path) { return null; } public IContentWriter GetContentWriter(string path) { return null; } public object GetContentReaderDynamicParameters(string path) { return null; } public IContentReader GetContentReader(string path) { return null; } private void WriteErrors(Exception exp) { //WriteErrors(exp, // ErrorCategory. // if (exp is HECIClass.UnauthorizedException) { // WriteError(new ErrorRecord( // exp, // exp.GetType().Name, // ErrorCategory.PermissionDenied, /// PSDriveInfo)); } // else { WriteError(new ErrorRecord( exp, exp.GetType().Name, ErrorCategory.NotSpecified, PSDriveInfo)); } } /// /// Checks if a given path is actually a drive name. /// /// The path to check. /// /// True if the path given represents a drive, false otherwise. /// private bool PathIsDrive(string path) { // check for root path (with or without separators) if (string.IsNullOrEmpty(path) || string.Compare(path,PSDriveInfo.Name,true)==0 || string.Compare(path,PSDriveInfo.Name+"\\",true)==0) { return true; } else { return false; } } // PathIsDrive /* /// /// Definition of an AmtDriveInfo object /// internal class AmtDriveInfo : PSDriveInfo { AmtDriveItem _root; HECIClass _heci; string _cashedPath; AmtDriveItem _cashedItem; bool _bDriverLoaded; bool _bDriverLocked; public AmtDriveInfo(PSDriveInfo info) : base(info) { _heci = new HECIClass(); _cashedItem = null; _cashedPath = string.Empty; //_root = new ContainerItem("LocalDriver", _root = new AmtRootItem(_heci); _bDriverLoaded = false; } public void LockDriver() { _bDriverLocked=true; } public void UnlockDriver() { _bDriverLocked = false; UnLoadDriver(); } public void LoadDriver() { if (!_bDriverLoaded) { _heci.Init(); _bDriverLoaded = true; } } public void UnLoadDriver() { if (_bDriverLoaded && !_bDriverLocked) { _heci.DeInit(); _bDriverLoaded = false; } } public AmtDriveItem GetItemFromPath(string path) { //check root if (string.IsNullOrEmpty(path) || string.Compare(this.Name,path,true)==0 || string.Compare(this.Name+"\\", path, true)==0) { return _root; } // Get path components char[] splits = {'\\'}; string[] paths = path.Split(splits, StringSplitOptions.RemoveEmptyEntries); //find item in path AmtDriveItem parent = _root; AmtDriveItem foundItem = null; //load heci if its in the path foreach (string pathItem in paths) { if (string.Compare(pathItem, AmtHeciRootItem.HostDriveName, true) == 0) LoadDriver(); } //check and see if the item is cached if (string.Compare(path, _cashedPath, true) == 0) { return _cashedItem; } else { //check if parent is cached int pos = path.ToLower().IndexOf(_cashedPath.ToLower() + "\\"); if (pos == 0) { paths = path.Substring(_cashedPath.Length).Split(splits, StringSplitOptions.RemoveEmptyEntries); parent = _cashedItem; } } try { for (int i = 0; i < paths.Length; i++) { foundItem = null; foreach (AmtDriveItem childItem in parent.GetChildItems()) { if (string.Compare(childItem.Name, paths[i], true) == 0) { foundItem = childItem; parent = foundItem; break; } } if (foundItem == null) { break; } else { _cashedItem = foundItem; _cashedPath = path; } } } finally { UnLoadDriver(); } return foundItem; } } // End defintion of AMTDriveInfo internal class AmtRootContainerValue : ContainerItemValue { AmtDriveItem[] _items; public AmtRootContainerValue(HECIClass heci) { //build the array _items = new AmtDriveItem[1]; _items[0]= new AmtHeciRootItem(heci); } public override AmtDriveItem[] GetChildItems() { return _items; } } /// /// Definition of the Root Container /// internal class AmtRootItem : AmtDriveItem { AmtRootContainerValue _value; public AmtRootItem(HECIClass heci) { _value = new AmtRootContainerValue(heci); } public override string Name { get { return DriveName; } } public override object Value { get { return _value; } } public override bool HasChildren { get { return true; } } public static string DriveName { get { return "AMT"; } } } //End Definition of the Root Container internal class AmtSetupContainerValue : ContainerItemValue { HECIClass _heci; public AmtSetupContainerValue(HECIClass heci) { _heci = heci; } public override AmtDriveItem[] GetChildItems() { List list = new List(); HECIClass.ProvisioningMode mode; bool bOk = _heci.GetProvisioningMode(out mode); if (bOk) list.Add(new AmtPropertyItem("ProvisioningMode", mode)); bool ztcEnabled; bOk = _heci.GetZeroTouchEnabled(out ztcEnabled); if (bOk) list.Add(new AmtPropertyItem("ZeroTouch", ztcEnabled)); HECIClass.TlsMode tlsMode; bOk = _heci.GetTlsMode(out tlsMode); if (bOk) list.Add(new AmtPropertyItem("SetupMode", tlsMode)); HECIClass.RngSeedStatus rngStatus; bOk = _heci.GetRngSeedStatus(out rngStatus); if (bOk) list.Add(new AmtPropertyItem("RngStatus", rngStatus)); return list.ToArray(); } } /// /// Definition of the setup container /// internal class AmtSetupItem : AmtDriveItem { AmtSetupContainerValue _value; public AmtSetupItem(HECIClass heci) { _value = new AmtSetupContainerValue(heci); } public override bool HasChildren { get { return true; } } public override string Name { get { return "LegacySetup"; } } public override object Value { get { return _value; } } } /// /// Definition of an individual hash item /// internal class AmtHashEntryItem : AmtDriveItem { AmtHashContainerValue _value; public AmtHashEntryItem(HECIClass.HashEntry entry) { _value = new AmtHashContainerValue(entry); } public override bool HasChildren { get { return true; } } public override string Name { get { return _value.Name; } } public override object Value { get { return _value; } } } // Definition of an Hash Entry Item /// /// Container value for a Hash Entry /// internal class AmtHashContainerValue : ContainerItemValue { HECIClass.HashEntry _entry; public AmtHashContainerValue(HECIClass.HashEntry entry) { _entry = entry; } public string Name { get { return _entry.Name; } } public override AmtDriveItem[] GetChildItems() { List list = new List(); list.Add(new AmtPropertyItem("Name", _entry.Name)); list.Add(new AmtPropertyItem("IsDefault", _entry.IsDefault)); list.Add(new AmtPropertyItem("IsActive", _entry.IsActive)); list.Add(new AmtPropertyItem("Thumbprint", _entry.Thumbprint)); list.Add(new AmtPropertyItem("HashString", _entry.HashString)); return list.ToArray(); } public override string ToString() { return _entry.Thumbprint; } } /// /// Container value for Hashes /// internal class AmtHashesContainerValue : ContainerItemValue { HECIClass _heci; public AmtHashesContainerValue(HECIClass heci) { _heci = heci; } public override AmtDriveItem[] GetChildItems() { HECIClass.HashEntry[] hashes; AmtDriveItem[] result = { }; if (_heci.GetCertHashes(out hashes)) { result = new AmtDriveItem[hashes.Length]; for (int i = 0; i < hashes.Length; i++) { result[i] = new AmtHashEntryItem(hashes[i]); } } return result; } } /// /// Definition of a collection of hashes /// internal class AmtHashesItem : AmtDriveItem { AmtHashesContainerValue _value; bool _hasChildren; public AmtHashesItem(HECIClass heci) : base() { _value = new AmtHashesContainerValue(heci); _hasChildren = false; } public override bool IsContainer { get { return true; } } public override bool HasChildren { get { return _hasChildren; } } public override AmtDriveItem[] GetChildItems() { AmtDriveItem[] result = _value.GetChildItems(); _hasChildren = result.Length > 0; return result; } public override string Name { get { return "Hashes"; } } public override object Value { get { return _value; } } } /// /// Container value for Root Heci Items /// internal class AmtHeciContainerValue : ContainerItemValue { HECIClass _heci; public AmtHeciContainerValue(HECIClass heci) { _heci = heci; } public override AmtDriveItem[] GetChildItems() { List list = new List(); bool bOk; string boisString; HECIClass.ProvisioningState state; bOk = _heci.GetProvisioningState(out state); if (bOk) list.Add(new AmtPropertyItem("ProvisioningState", state)); HECIClass.AMT_VERSION_TYPE[] verTypes; bOk = _heci.GetCodeVersions(out boisString, out verTypes); if (bOk) { list.Add(new AmtPropertyItem("BIOSVersion", boisString)); foreach (HECIClass.AMT_VERSION_TYPE verType in verTypes) { list.Add(new AmtPropertyItem(verType.Description.Text, verType.Version.Text)); } } string userName, password; bOk = _heci.GetLocalAdminCredentials(out userName, out password); if (bOk) { list.Add(new AmtPropertyItem("LocalUser", userName)); list.Add(new AmtPropertyItem("LocalPassword", password)); } list.Add(new AmtPropertyItem("LocalAddress", "http://localhost:16992/wsman")); list.Add(new AmtSetupItem(_heci)); list.Add(new AmtHashesItem(_heci)); return list.ToArray(); } } //Container value for Root Heci Items /// /// Definition of the Heci Root Item /// internal class AmtHeciRootItem : AmtDriveItem { AmtHeciContainerValue _value; public AmtHeciRootItem(HECIClass heci) { _value = new AmtHeciContainerValue(heci); } public override bool HasChildren { get { return true; } } public override string Name { get { return HostDriveName; } } public override object Value { get { return _value; } } public static string HostDriveName { get { return "HostDriver"; } } } /// /// Definition a property item /// internal class AmtPropertyItem : AmtDriveItem { string _name; object _value; public AmtPropertyItem(string name, object value) : base() { _name = name; _value = value; } public override string Name { get { return _name; } } public override object Value { get { return _value; } } }*/ } //End AMTDriveProvider } // end Namepsace