/Source/FIMPSClient.cs
C# | 341 lines | 234 code | 39 blank | 68 comment | 11 complexity | fdeb18c361c36223b3494bf38a0ee7d6 MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
-
- using System.ServiceModel;
- using System.Security.Principal;
- using System.Xml.Schema;
- using Microsoft.ResourceManagement.Client;
- using Microsoft.ResourceManagement.ObjectModel;
- using Microsoft.ResourceManagement.ObjectModel.ResourceTypes;
- using Microsoft.ResourceManagement.Client.WsTransfer;
- using Microsoft.ResourceManagement.Client.WsEnumeration;
- using System.ServiceModel.Channels;
- using System.Net;
- using System.Management.Automation;
- using System.Management.Automation.Host;
- using System.Globalization;
-
- namespace Quest.FIMPowerShellSnapin
- {
- public class FIMPSClient
- {
- private const String _defaultResourceManagementPort = "5725";
- private const String _defaultSTSPort = "5726";
-
- private MexClient _mexClient;
- private WsTransferClient _wsTransferClient;
- private WsTransferFactoryClient _wsTransferFactoryClient;
- private WsEnumerationClient _wsEnumerationClient;
- private RmResourceFactory _resourceFactory;
- private RmRequestFactory _requestFactory;
- private PSHost _pSHost;
- private PSCredential _pSCreds;
- private string _fIMServer;
- private string _fIMPort;
- private string[] _defaultAttrNames;
- private bool _schemaCached;
- private SchemaCache _schemaCache;
-
- /// <summary>
- /// This class contains the names of the FIM web service endpoints. They are copied from
- /// Microsoft.ResourceManagement.Client.Constants.Endpoint, which is unfortunately marked internal, which makes
- /// them inaccessible.
- /// </summary>
- internal class EndpointNames
- {
- private EndpointNames() { }
- public const String MEX = "ResourceManagementService/MEX";
- public const String Resource = "ResourceManagementService/Resource";
- public const String ResourceFactory = "ResourceManagementService/ResourceFactory";
- public const String Enumeration = "ResourceManagementService/Enumeration";
- public const String Alternate = "ResourceManagementService/Alternate";
- }
-
- public FIMPSClient(string fIMserverParam, PSCredential creds, PSHost pSHost)
- {
- // Save reference to PS host environment
- _pSHost = pSHost;
- _pSCreds = creds;
-
- // Separate FIM server name and port if any, and save
- int colonPosition = fIMserverParam.IndexOf(':');
- if (colonPosition < 0)
- {
- _fIMServer = fIMserverParam.ToLower();
- _fIMPort = _defaultResourceManagementPort;
- }
- else
- {
- _fIMServer = fIMserverParam.Substring(0, colonPosition);
- _fIMPort = fIMserverParam.Substring(colonPosition + 1);
- /*!!! check _fIMPort for numeric value*/
- }
-
- _mexClient = CreateMexClient();
- _wsTransferClient = CreateTransferClient();
- _wsTransferFactoryClient = CreateTransferFactoryClient();
- _wsEnumerationClient = CreateEnumerationClient();
-
- _resourceFactory = new RmResourceFactory();
- _requestFactory = new RmRequestFactory();
- _schemaCache = new SchemaCache();
- }
-
- /// <summary>
- /// Refreshes the metadata from the service.
- /// </summary>
- public XmlSchemaSet RefreshSchema()
- {
- XmlSchemaSet metadata = _mexClient.Get();
-
- lock (_requestFactory)
- {
- _requestFactory = new RmRequestFactory(metadata);
- }
- lock (_resourceFactory)
- {
- _resourceFactory = new RmResourceFactory(metadata);
- }
- lock (_schemaCache)
- {
- _schemaCache = new SchemaCache(metadata);
- }
-
- _schemaCached = true;
-
- return metadata;
- }
-
- public SchemaCache Schema
- {
- get
- {
- if(!_schemaCached)
- {
- RefreshSchema();
- }
- return _schemaCache;
- }
- }
-
- #region ResourceTransfer
- /// <summary>
- /// Retrieves the object with the given ObjectId
- /// </summary>
- /// <param name="objectId">The ObjectId of the requested object.</param>
- /// <returns>The object or null if not found</returns>
- /// <exception cref="System.ServiceModel.FaultException">System.ServiceModel.FaultException thrown when failures occur.</exception>
- public RmResource Get(RmReference objectId)
- {
- return Get(objectId, null, null);
- }
-
- /// <summary>
- /// Retrieves the representation of an object with the given ObjectId in the given culture.
- /// </summary>
- /// <param name="objectId">The ObjectId of the requested object.</param>
- /// <param name="culture">The requested culture representation of the object.</param>
- /// <returns>The object or null if not found.</returns>
- public RmResource Get(RmReference objectId, CultureInfo culture)
- {
- return Get(objectId, culture, null);
- }
-
- /// <summary>
- /// Retrieves the object and the specified attributes with the given ObjectId.
- /// </summary>
- /// <param name="objectId">The ObjectId of the requested object.</param>
- /// <param name="attributes">The list of attributes on the object to return.</param>
- /// <returns></returns>
- public RmResource Get(RmReference objectId, String[] attributes)
- {
- return Get(objectId, null, attributes);
- }
-
- /// <summary>
- /// Retrieves the object and the specified attributes with the given ObjectId and in the specified culture.
- /// </summary>
- /// <param name="objectId">The ObjectId of the requested object.</param>
- /// <param name="culture">The requested culture representation of the object.</param>
- /// <param name="attributes">The list of attributes on the object to return.</param>
- /// <returns>The requested object, or null if it is not found.</returns>
- public RmResource Get(RmReference objectId, CultureInfo culture, String[] attributes)
- {
- GetRequest request = _requestFactory.CreateGetRequest(objectId, culture, attributes);
- GetResponse response = _wsTransferClient.Get(request);
- return _resourceFactory.CreateResource(response);
- }
-
- #endregion
-
- #region Enumeration
- /// <summary>
- /// Returns an enumerator that can traverse all objects matching the given filter.
- /// </summary>
- /// <param name="filter">The XPath filter of which objects to select.</param>
- /// <returns>An enumerator object which can be consumed in foreach statements.</returns>
- public IEnumerable<RmResource> Enumerate(String filter)
- {
- return this.Enumerate(filter, new string[] { });
- }
-
- /// <summary>
- /// Returns an enumerator that can traverse all objects matching the given filter.
- ///
- /// Each object only contains the specified attributes.
- /// </summary>
- /// <param name="filter">The XPath filter of which objects to select.</param>
- /// <param name="attributes">A list of attribute names to include in returned objects.</param>
- /// <returns>An enumerator object which can be consumed in foreach statements.</returns>
- public IEnumerable<RmResource> Enumerate(String filter, String[] attributes)
- {
- if (String.IsNullOrEmpty(filter))
- {
- throw new ArgumentNullException("filter");
- }
-
- return _requestFactory.CreateEnumeration(_wsEnumerationClient, _resourceFactory, filter, attributes);
- }
- #endregion
-
- #region Create
- /// <summary>
- /// Creates the given resource and returns its ObjectId.
- /// This method does not set the ObjectId of newResource.
- /// </summary>
- /// <param name="newResource">The resource to create.</param>
- /// <returns>The ObjectId of the resource.</returns>
- public RmReference Create(RmResource newResource)
- {
- if (newResource == null)
- throw new ArgumentNullException("newResource");
- CreateRequest request = _requestFactory.CreateCreateRequest(newResource);
- CreateResponse response = _wsTransferFactoryClient.Create(request);
- try
- {
- RmReference reference = new RmReference(response.ResourceCreated.EndpointReference.ReferenceProperties.ResourceReferenceProperty.Value);
- newResource.ObjectID = reference;
- return reference;
- }
- catch (NullReferenceException)
- {
- return new RmReference();
- }
- catch (FormatException)
- {
- return new RmReference();
- }
- }
- #endregion
-
- #region Put
- /// <summary>
- /// Saves changes made to an object recorded by the transaction to the service.
- /// </summary>
- /// <param name="transaction">The transaction object which recorded changes made to a Resource object.</param>
- /// <returns>True upon successful operation.</returns>
- public bool Put(RmResourceChanges transaction)
- {
- if (transaction == null)
- {
- throw new ArgumentNullException("transaction");
- }
-
- PutRequest request = _requestFactory.CreatePutRequest(transaction);
- PutResponse response = _wsTransferClient.Put(request);
- if (response == null)
- return false;
- else
- return true;
- }
- #endregion
-
- #region Delete
- /// <summary>
- /// Deletes the object with the given ObjectId.
- /// </summary>
- /// <param name="objectId">The ObjectId of the object to delete.</param>
- /// <returns>True upon successful deletion.</returns>
- public bool Delete(RmReference objectId)
- {
- DeleteRequest request = _requestFactory.CreateDeleteRequest(objectId);
- DeleteResponse response = _wsTransferClient.Delete(request);
- if (response == null)
- return false;
- else
- return true;
- }
- #endregion
-
- /// <summary>
- /// Returns true if the schema has been cached for this client.
- /// </summary>
- public bool SchemaCached
- {
- get
- {
- return _schemaCached;
- }
- }
-
- private MexClient CreateMexClient()
- {
- EndpointAddress remoteAddress = new EndpointAddress(CreateServiceEndpointURI(EndpointNames.MEX), CreateFIMSPNIdentity());
- WSHttpBinding binding = new WSHttpBinding(SecurityMode.None);
- binding.MaxReceivedMessageSize = Int32.MaxValue;
-
- return new MexClient(binding, remoteAddress);
- }
-
- private WsTransferClient CreateTransferClient()
- {
- EndpointAddress remoteAddress = new EndpointAddress(CreateServiceEndpointURI(EndpointNames.Resource), CreateFIMSPNIdentity());
-
- System.ServiceModel.WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message);
- binding.Security.Message.EstablishSecurityContext = false;
- binding.MaxReceivedMessageSize = Int32.MaxValue;
-
- WsTransferClient client = new WsTransferClient(binding, remoteAddress);
- client.ClientCredentials.Windows.ClientCredential = _pSCreds.GetNetworkCredential();
- return client;
- }
-
- private WsTransferFactoryClient CreateTransferFactoryClient()
- {
- EndpointAddress remoteAddress = new EndpointAddress(CreateServiceEndpointURI(EndpointNames.ResourceFactory), CreateFIMSPNIdentity());
-
- System.ServiceModel.WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message);
- binding.Security.Message.EstablishSecurityContext = false;
- binding.MaxReceivedMessageSize = Int32.MaxValue;
-
- WsTransferFactoryClient client = new WsTransferFactoryClient(binding, remoteAddress);
- client.ClientCredentials.Windows.ClientCredential = _pSCreds.GetNetworkCredential();
- return client;
- }
-
- private WsEnumerationClient CreateEnumerationClient()
- {
- EndpointAddress remoteAddress = new EndpointAddress(CreateServiceEndpointURI(EndpointNames.Enumeration), CreateFIMSPNIdentity());
-
- System.ServiceModel.WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message);
- binding.Security.Message.EstablishSecurityContext = false;
- binding.MaxReceivedMessageSize = Int32.MaxValue;
-
- WsEnumerationClient client = new WsEnumerationClient(binding, remoteAddress);
- client.ClientCredentials.Windows.ClientCredential = _pSCreds.GetNetworkCredential();
- return client;
- }
-
- private Uri CreateServiceEndpointURI(string serviceEndpointName)
- {
- return new Uri(String.Format("http://{0}:{1}/{2}", _fIMServer, _fIMPort, serviceEndpointName));
- }
-
- EndpointIdentity CreateFIMSPNIdentity()
- {
- return EndpointIdentity.CreateSpnIdentity("IdentityManagementService/" + _fIMServer);
- }
- }
- }