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