Leverage the Mobile Device Extension for AD RMS

Introduction

Every day, information workers use email messages to exchange sensitive information such as financial reports and data, legal contracts, confidential product information, sales reports and projections, competitive analysis, research and patent information, customer records, employee information, etc.

With time, the type, volume and sensitivity of information that is exchanged has changed significantly. Mailboxes have transformed into repositories containing large amounts of potentially sensitive information.

Ever more powerful and more affordable devices (smartphones, slates, tablets, and laptops), converging technologies, and the widespread use of the Internet have replaced what were only (controlled and managed) laptops in past years.

Today, information workers are highly interconnected interacting with each other in new ways using social networks (Facebook, Google+, Yammer, etc.), and expect "always on" connectivity, and more of them are using the device of their choice to access emails and work-related documents from just about anywhere: at home, at work and everywhere in between… up to the point where personal and work communication can become indistinguishable.

CoIT is the current phenomenon whereby consumer technologies and consumer behavior are in various ways driving innovation for information technology within the organization. As people become more comfortable with technology innovation in their personal lives, they expect it in their professional lives.

While CoIT has remarkable potential for improving collaboration and productivity, this raises new challenges for security, privacy, and industry and regulatory compliance.

Note    To help figure out how to face security, compliance and compatibility issues you might deal with and to give users access to corporate intellectual property from ubiquitous devices, both managed and unmanaged, you can refer to a series of documents on CoIT, i.e. Test Lab Guides (TLGs) available on the Microsoft Download Center. The TLGs illustrate key CoIT scenarios with current Microsoft technologies and allow you to get hands-on experience using a pre-defined and tested methodology that results in working configurations.

Where information workers are more mobile, share information, and collaborate more than ever before, information leakage can be thus a serious threat to organizations. Leaks of confidential information can result in lost revenue, compromised ability to compete, unfairness in purchasing and hiring decisions, diminished customer confidence, and more.

The proliferation of consumer devices and ubiquitous information access is driving the organization to define a new model in which information workers use their (own) devices to access sensitive corporate data. The model must be flexible enough to meet their users' needs while at the same time guarantee that sensitive corporate data are protected from unauthorized access regardless of whether the user's device is completely managed and individually secured. To increase productivity, users also ask for a secure and consistent way to access and share sensitive information from their devices.

To tackle the issues described above, Microsoft has delivered a cloud-based digital information rights management solution on all important devices through the Azure Rights Management service (Azure RMS) offerings. This service enables users on all important devices to access and use sensitive information. As a transport and storage agnostic solution, it operates on all types of files. Dispersed enterprise data can be protected in a consistent way dictated by the policy no matter where it goes.

Note    For an overview of Azure RMS, see the whitepaper Azure Rights Management services, and the online documentation.

However, such a support for all important devices was not available in the on-premises counterpart to Azure RMS, Microsoft Active Directory Right Management Services (AD RMS). First shipped for Windows Server 2003 and later evolved into a component of Windows Server 2008/2012, AD RMS is designed for organizations that need to protect sensitive and proprietary information and that are not ready to or cannot subscribe for any specific requirement or reason to a cloud service.

The Mobile Device Extension for AD RMS now enables Windows Server 2012 and Windows Server 2012 R2-based AD RMS clusters to support important mobile devices with mobile RMS-enlightened applications in the same way as Azure RMS does.

Note    You don't need the Mobile Device Extension for AD RMS to consume or author protected email on devices if they use mobile mail apps that support Exchange ActiveSync (EAS) Information Rights Management (IRM). This native support for AD RMS and mobile devices was introduced with Exchange 2010 Service Pack 1 (SP1).

Note    The Microsoft Exchange ActiveSync (EAS) protocol provides synchronization of mailbox data between mobile devices and Exchange Online, so users can access their email, calendar, contacts, and tasks on the go. EAS is licensed by Microsoft to mobile device manufacturers, original equipment manufacturers (OEMs), and mail client applications, and is thus supported by a wide range of mobile devices, including Windows Phone devices, Palm devices, Apple iPhone and iPad, and many Android phones. Implementation of specific EAS features may vary by device and manufacturer. A community-maintained comparison of how Exchange ActiveSync features are implemented by various mobile clients is available at this Comparison of Exchange ActiveSync Clients page on Wikipedia.

Note    Devices supporting version 14.1 and above of the protocol can leverage the above EAS IRM capability. The mobile mail app on a device must support the RightsManagementInformation tag defined in this protocol version and above.

To learn more about EAS IRM for protecting mail messages and attachments and how to deploy it in Exchange 2010 SP1 and above, see the Microsoft TechNet article Understanding Information Rights Management in Exchange ActiveSync.

The Mobile Device Extension for AD RMS is particularly intended for any mobile RMS-enlightened applications based on the latest Microsoft Rights Management (RMS) SDK, i.e. the RMS SDK 4.0, such as the RMS Sharing app. These applications generally need to be installed through the corresponding app stores for the device.

Note    For more information on the RMS Sharing app, see the RMS sharing app guides (administration guide and user guide) and the FAQ for mobile platforms on Microsoft TechNet.

Objectives of this paper

This document provides information about the Mobile Device Extension for AD RMS, and how it can be deployed on top of existing Windows Server 2012 and Windows Server 2012 R2-based AD RMS clusters to support devices with mobile RMS-enlightened applications.

By following the steps outlined in this document you should be able to successfully prepare your environment to deploy the Mobile Device Extension, and start using it within your organization to create and consume protected content on your devices.

Please note that the detailed step by step guidance in this paper covers not only the deployment of the Mobile Device Extension, but also the installation and configuration of AD RMS, the domain controllers that support the environment, Active Directory Federation Services (AD FS) servers, the virtual machines to host those components and other required components. If this guide is used to support the deployment of MDE in an existing environment, only specific sections of the detailed procedures will apply, while others will have to be modified.

Non-objectives of this paper

This document doesn't provide a full description of AD RMS. It rather focuses on key aspects that aims at providing the readers an understanding on how to leverage and deploy the Mobile Device Extension on their existing on-premises corporate AD RMS infrastructure.

Note    For additional information on AD RMS, see the Microsoft TechNet article Active Directory Rights Management Services Overview, as well as the several posts of the AD RMS Team Blog.

It doesn't provide neither guidance for setting up and configuring AD RMS in a production environment nor a complete technical reference for AD RMS.

Organization of this paper

To cover the aforementioned objectives, this document is organized in the following four sections:

  • Overview of the Mobile Device Extension.
  • Building a test lab environment.
  • Setting up the Windows Server 2012 R2 Base Configuration test lab.
  • Testing and evaluating the Mobile Device Extension for AD RMS.

These sections provide the information details necessary to (hopefully) successfully build a working environment with the Mobile Device Extension for AD RMS. They must be followed in order.

About the audience

This document is intended for system architects and IT professionals who are interested in understanding how to enable and configure the Mobile Device Extension for AD RMS on their existing on-premises AD RMS infrastructure.

Overview of the Mobile Device Extension for AD RMS

As introduced before, the Mobile Device Extension for AD RMS lets users who have mobile devices protect and consume sensitive data when their device supports the latest RMS client (also known as the mobile client) and uses RMS-enlightened apps. For example, users on these devices can do the following:

  • Use the RMS sharing app to consume protected text files in different formats (including .txt, .csv, and .xml).
  • Use the RMS sharing app to consume protected image files (including .jpg, .gif, and .tif).
  • Use the RMS sharing app to open any file that have been generically protected (.pfile format).
  • Use the RMS sharing app to open an Office or PDF file encoded in PPDF format (to learn more about the PPDF format see the relevant section in the RMS Sharing app documentation).
  • Use the RMS sharing app to protect image files on the device.
  • Use an RMS-enlightened PDF viewer for mobile devices to open PDF files that were protected with the RMS sharing app for Windows, or another RMS-enlightened application.
  • Use other apps from software vendors who provide RMS-enlightened apps that support file types that natively support RMS.
  • Use your internally developed RMS-enlightened apps that were written by using the lightweight Microsoft Rights Management SDK (RMS SDK) 4.0.

The first mobile client that was based on the RMS SDK 3.0 was initially intended to work only in conjunction with Azure RMS. More specifically, it was designed to interact with the highly abstracted and simplified REST APIs exposed by Azure RMS through rights management service endpoints - along with a service discovery process - for authoring of new content and for consumption of protected content on mobile devices.

To enable the above usage scenario, the Mobile Device Extension for AD RMS enables an on-premises AD RMS clusters to expose similar service endpoints as the ones exposed by Azure RMS.

Such an approach leverages a common logic to locate via a service discovery process the REST service endpoints of the RMS service, whether it is an on-premises AD RMS cluster with the Mobile Device Extension or Azure RMS.

The newly introduced RMS SDK 4.0 for creating rights-enabled applications integrates this common logic and abstracts all access to service endpoints in a platform agnostic manner for the REST APIs. This version of the RMS SDK thus enables to develop RMS-enlightened apps on mobile devices with the new AD RMS server's Mobile Device Extension.

Important note     The RMS SDK 4.0 supersedes the RMS SDK 3.0, which is now deprecated.

Note    The RMS SDK 4.0 is a simplified, next-generation API that enables a lightweight development experience in building or upgrading device apps with information protection via the RMS service, whether it is an on-premises AD RMS cluster with the Mobile Device Extension or Azure RMS.

Its APIs support standard programming languages and models for each operating system so, they are easy and familiar to work with. The RMS SDK 4.0 provides support in mobile devices (Android, iOS, Mac OS X, Windows Phone, and Windows RT).

For additional information on the RMS SDK 4.0, see the eponym MSDN page Microsoft Rights Management SDK 4.0.

Prerequisites for the Mobile Device Extension

The Mobile Device Extension supports the following RMS clients:

  • Android phones and tablets. Minimum version of Android 4.0.3
  • iPhone and iPad. Minimum version of iOS 7.0
  • Mac OS X. Versions 10.8 and 10.9
  • Windows Phone. Minimum version of Windows Phone 8.1
  • Windows RT tablets. Windows 8 RT, Windows 8.1 RT

Note    The availability of the RMS client and SDK on an operating system does not necessarily imply the availability of the RMS Sharing app on that platform. In particular, the RMS Sharing app has not yet been released for Windows RT devices at the time of this writing.

These clients must use the latest version of the RMS sharing app for the devices as available for download at the Microsoft Rights Management page.

Beyond an existing on-premises AD RMS deployment on Windows Server 2012 or Windows Server 2012 R2, the following dependencies must be in place before using the Mobile Device Extension for AD RMS:

  • DNS SRV records to help locate the service endpoints provided by the Mobile Device Extension.
  • Both AD RMS internal (e.g., intranet) and external (e.g., extranet) FQDN URLs populated. (In a split brain DNS configuration, only the Intranet URLs are populated.)
  • Use of SSL/TLS with a trusted X.509 certificate for the AD RMS internal and external URLs.
  • AD FS deployed on Windows Server 2012 R2 to sustain the authentication required by the service endpoints.

Note    For information on AD FS in Windows Server 2012 R2, see the Microsoft TechNet article Windows Server 2012 R2 AD FS Deployment Guide.

  • Some secure publishing mechanism such as the Web Application Proxy (WAP) deployed on Windows Server 2012 R2 to publish the service endpoints on the Internet.
  • If the AD RMS server is deployed behind a firewall or published by using a reverse proxy, in addition to publishing the service endpoints on the Internet, you must also publish the /my folder, for example https://adrms.litware369.com/my.

The next sections provide additional information on the service endpoints and depict how the above dependencies are being used by the Mobile Device Extension for AD RMS.

How mobile apps use the new service endpoints

Note    This section discusses how the Mobile Device Extension works under the hood to support mobile apps based on the RMS SDK 4.x. This section is included here for a deeper understanding of the technology, but this level of knowledge is not essential to be able to deploy the AD RMS Mobile Device Extension. If you are not interested in the details of how this technology works, you can skip directly to the section Building a test lab environment below.

The Mobile Device Extension exposes the following endpoints in the form of REST APIs:

In addition to the above REST service endpoints, the Mobile Device Extension provides a DNS-based service discovery mechanism in order to enable mobile devices to discover these endpoints based on the identity of the user or the source of the protected content. This will be further discussed below.

Publishing License request

When a mobile client has to protect content it calls the service to obtain the Publishing License to use for the document. This differs from Windows clients, where protection can be performed offline by the client by using keys contained in the Client Licensor certificate and other artifacts obtained during activation. In mobile devices such activation process does not exist, and all calls performed to the service are handled independently.

The Publishing License request takes either a template ID or a custom policy and returns a serialized Publishing License (PL) that is generated from the template or policy.

HTTP Method

Request URL

HTTP Version

POST

https://<ClusterURL>/my/v1/publishinglicenses

HTTP 1.1

Where <ClusterURL> is the FQDN of an AD RMS cluster on top of which the Mobile Device Extension has been installed. This value will be obtained by calling the service discovery so that mobile devices can discover the endpoints based on the identity of the user.

The request body includes a JSON-encoded template ID that corresponds to one of the templates that are configured for the tenant or custom (ad-hoc) policy. A successful request returns HTTP 200 OK with a body that contains the Publishing License (in base64 encoded form) in a JSON object.

End User License request

The End User License request takes the publishing license of the protected content as a parameter and returns the end user license (EUL) for the calling user.

HTTP Method

Request URL

HTTP Version

POST

https://<ClusterURL>/my/v1/enduserlicenses

HTTP 1.1

Where <ClusterURL> is the FQDN of an AD RMS cluster on top of which the Mobile Device Extension has been installed. This value will be obtained by calling the service discovery so that mobile devices can discover the endpoints based on the identity of the user and the URL of the server that was used to protect the content.

The request body is a JSON object that contains the serialized publishing license (PL) (in base64 encoded form) that applies to the protected content. A successful request returns HTTP 200 OK with a body that contains the end user license (EUL).

Templates request

The Templates request returns the list of templates that are available for the user in the server.

HTTP Method

Request URL

HTTP Version

GET

https://<ClusterURL>/my/v1/templates

HTTP 1.1

Where <ClusterURL> is the FQDN of an AD RMS cluster on top of which the Mobile Device Extension has been installed.

There is no body for this request. A successful request returns HTTP 200 OK with a body that contains the list of templates that are available.

REST API errors

This section describes the errors that can be returned by the aforementioned REST APIs and their format.

The following table shows the HTTP error codes that the REST APIs can return.

HTTP Error Code

Description

200 OK

Standard response for successful HTTP requests.

400 Bad Request

The request cannot be fulfilled because of bad syntax or set of parameters.

401 Unauthorized

Returned when authentication is required and has failed or has not yet been provided.

500 Internal Server Error

Returned when something happened on the server and the client is not at fault.

When the REST API explicitly returns HTTP 400 and 500 errors (but not HTTP 401 errors), it also returns a message body that contains information about the error. The response body contains the following fields:

  • code. The fully qualified name of the exception that caused the error.
  • message. A descriptive message that explains the error.

Understanding how the service endpoints are located

Unlike with the cloud RMS service (Azure RMS) there is no universal location a client must go to deal with an AD RMS server deployed on-premises, so a service discovery mechanism is required. Windows clients can use the Service Connection Point (SCP) in Active Directory or, alternatively, registry-based overrides, to locate the RMS server in their environment. Mobile devices typically do not support being members of an Active Directory domain, nor can support registry-based configurations, so a different mechanism is used.

As mentioned before, the Mobile Device Extension provides a service discovery mechanism based on DNS SRV records in order to enable mobile devices to locate the necessary service endpoints. Such mechanism works in two steps:

  1. The RMS client performs a DNS lookup for a SRV record corresponding to the user's email domain (for authoring or template acquisition operations) or the content source server's FDQN (for consumption operations), and processes the response from the DNS service to build the service discovery URL to call.
  2. The client then contacts the URL obtained in the previous step and obtains the final REST APIs endpoints to call.

This two-step process allows mobile clients to identify the organization's infrastructure in the first step and then locate the exact server desired for the user in the second step. This allows for very flexible configurations in which different users are directed to different servers, or in which clients are directed to servers that replace the ones used in the past to protect the content. Similar capabilities are provided in Windows clients through the use of registry values.

The second operation is implemented as an HTTP GET call to the REST APIs in MDE as follows:

HTTP Method

Request URL

HTTP Version

GET

https://<ClusterURL>/my/v1/servicediscovery

HTTP 1.1

Where <ClusterURL> is the FQDN of an AD RMS cluster built by the RMS client based on the DNS SRV lookup response.

The response body will then contain the list of the aforementioned service endpoints and corresponding URLs in JSON format in the context of the request. The following JSON example illustrates a sample response body:

[{
"Name": "enduserlicenses",
"Uri": "https://adrms.contoso.com/my/v1/enduserlicenses"
},
{
"Name": "templates",
"Uri": "https://adrms.contoso.com/my/v1/templates"
},
{
"Name": "publishinglicenses",
"Uri": "https://adrms.contoso.com/my/v1/publishinglicenses"
}]

Since the first step of the endpoint discovery uses DNS and relies for that purposes on specific SRV service discovery records, the Service Connection Point (SCP) declared in the Active Directory is not used by the Mobile Device Extension.

Note    The SCP is an object in the Active Directory configuration partition that holds the Web address of the AD RMS cluster. RMS-enlightened applications built with RMS SDKs whose version is prior to 3.0 use the SCP to discover the AD RMS service; it is the first connection point for users to discover the AD RMS SOAP-based web service endpoints. Only one SCP can exist in your Active Directory forest.

A SCP can be viewed using ADSI Edit for instance. To view the SCP, connect to the configuration container in ADSI Edit and navigate the following nodes: CN=Configuration [server name], CN=Services, CN=RightsManagementServices, CN=SCP.

From a practical standpoint, the RMS client uses DNS SRV records to find the right location for the services used for:

  1. Authoring, i.e. protecting a file.
  2. The consumption of a protected file.

Different DNS SRV records must be consequently created in the authoritative DNS for the organization's domain(s) to support these processes. The next sections cover the DNS SRV records required for a fully functional RMS service discovery mechanism for mobile devices.

Understanding the DNS SRV service discovery records to create

To operate and enable the aforementioned scenarios, the Mobile Device Extension requires the creation in the DNS service one or more DNS SRV service discovery records in the organization's domain(s) as per RFC 6763 DNS-Based Service Discovery:

  • One record for each email domain suffix that users will use.
  • One record for every FQDN used by the AD RMS clusters in place to protect content.
Service discovery record for the email domain suffix

During first use of the mobile applications to protect content, users will be asked for their email address. The domain part of this address will be used to locate the right RMS infrastructure to handle the user's operations.

The service discovery record that relates to the email domain suffix for the user has the following format:

_rmsdisco._http._tcp.<email suffix><port number><AD RMS cluster FQDN>

Where:

  • <email suffix> is the email domain suffix that users will use,
  • <port number>is the port number used by an on-premises AD RMS cluster,
  • <AD RMS cluster FQDN> is the FQDN used by an on-premises AD RMS cluster.

When users supply their email address from their mobile device, the domain suffix is used to identify whether they should use an on-premises AD RMS cluster or Azure RMS. When the SRV record is found, the RMS client redirects to the RMS service that responds to this record (see below).

Important note     If all the users of the organization use child domains from a single parent domain, and all users from this contiguous namespace use the same AD RMS cluster, only one SRV record in the parent domain is needed, and the RMS client will find the appropriate DNS records (see below).

For example, if an organization has users with the following email addresses:

  • <user alias>@contoso.com
  • <user alias>@europe.contoso.com
  • <user alias>@fabrikam.com

And if there are no other child domain(s) for contoso.com and no other parent domain(s) that use a different AD RMS cluster than the one named adrms.contoso.com, the following two DNS SRV records must be created in DNS:

_rmsdisco._http._tcp.contoso.com 443 adrms.contoso.com

_rmsdisco._http._tcp.fabrikam.com 443 adrms.contoso.com

Service discovery record for the FQDN used by the AD RMS clusters in place

When consuming protected content, the mobile apps will use the URL in the Publishing License in the content to identify the right server to reach out to. Since it is possible that the original server has been replaced by another server with a different URL, a DNS-based service discovery call is performed based on the URL in the PL. The service discovery record that relates to the FQDN used by an AD RMS cluster in place to protect content has the following format:

_rmsdisco._http._tcp.< AD RMS cluster FQDN><port number><AD RMS cluster FQDN>

Where:

  • <AD RMS cluster FQDN> is the FQDN used by an on-premises AD RMS cluster,
  • <port number>is the port number used by an on-premises AD RMS cluster.

For example, if an AD RMS cluster deployed on-premises is adrms.contoso.com and it is desired that the same cluster, which has MDE installed, is used to consume content with mobile devices, a DNS SRV record that has the following value must be created in DNS:

_rmsdisco._http._tcp.adrms.contoso.com 443 adrms.contoso.com

Note that since this organization also has users using the same domain in their email addresses, this DNS entry is already included in those used for email domain-based service discovery. Thus, the organization used in this example would only need two DNS SRV records for RMS service discovery.

The next sections depict how these SRV records are queried by mobile devices to dynamically discover the endpoints for authoring and consuming content thanks to the above service discovery mechanism.

Understanding the basic flow for authoring content

The process for a mobile RMS-enlightened app to author content is as follows. The app uses the RMS SDK 4.0 and thus the related RMS client:

  1. For the initial domain resolution, the user specifies their email address in the app. The RMS client calls the DNS service and queries for the service discovery record which corresponds to the user's email domain suffix.

    If not found, the RMS client repeats the call for the user's email address domain's parent and iterates the process until a match is found or it reaches the second level domain.

    As previously noted, this allows to use only one DNS SRV record in the parent domain if all of all the users of the organization use child domains from a single parent domain, and all users from this contiguous namespace use the same AD RMS cluster.

  2. This record points to the on-premises AD RMS cluster.

    The response from the DNS service is processed by the RMS client to build the service discovery URL to call.

  3. The RMS client then makes a service discovery call to the endpoint URL discovered previously.
  4. On initial access the call to this endpoint will return a 401 error code and will redirect the client to the environment's federation server where the authentication process will be performed as described in section § Understanding how authentication works with the service endpoints below in this document. Steps 5-8 of the authentication process are explained in that section.
  5. Once the client has obtained an access token, it passes the token to the service discovery URL to which it tried to authenticate
  6. Upon acceptance of the token received from the service the URL of the RMS cluster is used by this user. The service discovery endpoint returns a list of rights management services (publish license, end user license, and templates) and corresponding endpoint URLs. These endpoints may be in the same RMS cluster (i.e. under the same FQDN) or in a different cluster if RMS is configured to direct the calling user to a different server. This may be done in the case where Licensing-Only clusters are deployed in the environment to handle different groups of users.

    Note that in this example, this is the same RMS cluster.

  7. The client contacts the URLs obtained in the previous step in order to obtain from the service the templates, and then the publishing license (PL).
  8. The app can finally protect the content.

As illustrated above, the publishing licenses (PL) are built by the AD RMS server and embedded by the RMS client, and all the transactions are atomic:

  • The client trusts the service endpoint URLs, and SSL/TLS is mandatory. There is no Server Licensor Certificate (SLC). The SLC is issued to licensing servers and grants them the right to issue PL, end use licenses (UL), client licensor certificates (CLC), and rights policy templates.
  • The client authenticates and acquires PL in one operation. There is no Rights Account Certificate (RAC). The RAC identifies a user in the context of a specific computer or device.) Consequently, there is no machine certificate either.
  • The client builds the policy and gets the PL from the server. There is no CLC. The CLC grants a user the right to publish (offline) AD RMS-protected content.

Note    For introduction on the AD RMS certificates and licenses, see the post Licenses and Certificates, and how AD RMS protects and consumes documents on the AD RMS Team Blog.

The Mobile Device Extensions do not support offline publishing from mobile devices at the time of publishing of this document.

Understanding the basic flow for consuming content

When a user consumes protected content with a mobile device, the process for the mobile RMS-enlightened app to activate is as follows. The app uses the RMS SDK 4.0 and thus the related RMS client:

  1. For the initial domain resolution, the RMS client looks in DNS for a service discovery record that matches the FQDN in the URL of the RMS service that protected the content. This URL is specified in the publishing license.
  2. The response from the DNS service is processed by the RMS client to build the discovery service URL to call.
  1. The RMS client then makes a call to the service discovery endpoint in the URL discovered previously.
    1. On initial access the call to this endpoint will return a 401 error code and will redirect the client to the environment's federation server where the authentication process will be performed as described in section § Understanding how authentication works with the service endpoints below in this document. Steps 4-7 in this authentication process are explained in that section. Once the client has obtained an access token it passes the token to the service discovery URL to which it tried to authenticate.
    2. Upon acceptance of the token received from the service the URL of the RMS cluster is used by this user.
    3. The service discovery endpoint returns the list of rights management services (publish license, end use license, and templates) and corresponding endpoint URLs is provided to the client in the response (as described before). These endpoints may be in the same RMS cluster (i.e. under the same FQDN) or in a different cluster if RMS is configured to direct the calling user to a different server. This may be done in the case where Trusted Publishing Domains are exchanged between RMS clusters to have one cluster handle the load for some or all users for content protected in another cluster.
    4. The RMS client then makes a call to the endpoint discovered previously passing the access token in order to acquire an end use license (EUL) to open the content.
    5. Once a EUL has been issued the mobile RMS-enlightened app finally renders the content.

As illustrated above, the EULs are delivered by the AD RMS server to the RMS client every time and, likewise the previous flow, all the transactions are atomic. As previously outlined:

  • The client trusts the service endpoint URLs, and SSL/TLS is mandatory. There is no SLC.
  • The client authenticates and acquires EUL in one operation. There is neither RAC nor machine certificate.

Understanding how authentication works with the service endpoints

As discussed above, the Mobile Device Extension for AD RMS enables to expose rights management service endpoints on top of the RMS service for consumption of protected content and for authoring of new content. Most mobile devices do not support the NTLM or Kerberos protocols for authentication and thus need to use a different mechanism to authenticate to the different interfaces in the RMS server, including connecting to the service discovery endpoint.

For that purpose, the Mobile Device Extension for AD RMS leverages the OAuth 2.0 open standard protocol for authentication and authorization.

The above step 3 more specifically uses the OAuth 2.0 authorization code grant flow: a public client (e.g. the RMS-enlightened app) receives consent (in the form of an authorization code) from a resource owner (e.g. the user) to access a protected resource (e.g. the RMS service) on their behalf. The client then redeems the authorization code for an access token and a refresh token, to access the protected resource.

ADFS in Windows Server 2012 R2 exposes the following two endpoints in order to sustain the above OAuth 2.0 grant flow:

  1. Authorization endpoint: https://<ServerURL>/adfs/oauth2/authorize

    The authorization endpoint is used to interact with the RMS client and obtain an authorization code which will be issued to the app. AD FS authenticates the user before granting the authorization code. This authorization code will be exchanged by the app for an access token.

  2. Token endpoint: https://<ServerURL>/adfs/oauth2/token

    The token endpoint is used by the app to obtain an access token by presenting its authorization code.

Where <ServerURL> is the FQDN of the ADFS server/farm specified during the installation of the Mobile Device Extension for AD RMS.

The overall flow to obtain an access token is as follows:

  1. The RMS client makes a call to a service endpoint to perform an operation on the RMS service by making a call to the URL obtained thanks to one of the created DNS SRV records.
  2. The RMS service finds out that the authentication has not happened yet. It returns back an OAuth 2.0 challenge. More specifically, it returns back a HTTP 401 with two fields in the HTTP body. One is the resource name that identifies the service endpoint, and the other is the URL to the local AD FS server/farm to interact with to obtain an access token. This URL is set during the installation of the Mobile Device Extension for AD RMS.
  3. The RMS client takes this response and goes to the URL identified in the response from the RMS service.
    1. In accordance to the OAuth 2.0 authorization code grant flow, it makes an authorization request to AD FS for the resource (again in the response from the RMS service) to get an authorization code. This call comprises the service endpoint the app wants to access, an app client identifier, and an app redirection URI in accordance with RFC 6749.

Note    In order to allow access from OAuth 2.0 clients to REST resources secured by AD FS, the app has to be registered beforehand with AD FS by using the cmdlet Add-AdfsClient. AD FS will not allow access to a REST resource to clients that specify a client identifier or redirection URI that is not registered with AD FS. For additional information, see Microsoft MDSN article Developing Modern Applications using OAuth and Active Directory Federation Services. 

  1. AD FS authenticates the user and issues an authorization code.
  2. The app gets the authorization code, and then does a post to the AD FS token endpoint to get an access token, passing the app client identifier, the redirection URI (this just has to match up with what was sent previously and isn't used as a redirect), and the authorization code received in the previous step.
  1. AD FS issues an access token for the user.
  2. The RMS client gets the access token and makes the request again but this time with the access token it got from AD FS. The RMS service validates the access token and if authorized responds to the request appropriately.

The follow diagram synthetizes the OAuth 2.0 authorization code grant flow in the above step 3:

Note    The Active
Directory
Authentication Library (ADAL)
library offers a simple programming model in client applications for AD FS in Windows Server 2012 R2 and for Azure Active Directory (AAD). Its main purpose is to help developers easily obtain access tokens from AD FS in Windows Server 2012 R2 or from AAD, which can then be used for requesting access to protected resources like the Mobile Device Extension for AD RMS REST APIs in the context of this document.

ADAL provides supports in mobile devices (Android, iOS, Windows Phone, and Windows RT), and Mac OS X. ADAL is available as Open Source code on GitHub so that you can participate in the development process. A full suite of sample applications and documentation is provided on GitHub to help you get started. This includes tutorials for the above mobile devices and full walkthroughs for authentication flows such as OAuth2 in the context of this paper.

The RMS service expects that ADFS provides the following claims in the access token:

  • Primary email address of the user,
  • User principal name (UPN) of the user,
  • Proxy email addresses of the user if present.

The format used for the access token is JSON Web Token (JWT), a compact JSON-encoded security token bearing claims. As such, JWT is especially apt for REST-based development. JWT use is growing, and products supporting the format are increasingly common in the industry.

Reviewing the supported topologies for the Mobile Device Extension

Whilst IT professionals can deploy AD RMS in a myriad of possible topologies - combining multiple clusters of different types with different trusts – to accommodate requirements that vary significantly from one organization to another, the Mobile Device Extension is designed to operate in the most common topologies used by organizations. While it may be possible for AD RMS to work in other topologies it is not the scope of this paper, and the Mobile Device Extension may not support some specific configurations.

These supported topologies for the Mobile Device Extension can be grouped and listed as follows:

  • Single forest with a single cluster.
  • Multiple forests with multiple certification clusters and a single licensing point.
  • Multiple forests with multiple certification clusters used for licensing.
  • Single or multiple forest with licensing-only clusters.
  • Cross-organization with federated trusts.
    • Trusted Publishing Domain (TPD) key imported from existing or deprecated AD RMS server.

While other topologies may be possible with AD RMS, they are NOT supported with the Mobile Device Extension for AD RMS at the time of publishing.

The next sections provide a short depiction of the considered topologies along with the considerations that apply to each.

Single forest with as single cluster

In this topology, an organization has only a single forest in which AD RMS can be used. All users and servers that interact with RMS are hosted in that forest. This topology is the most commonly one deployed. Consequently, the deployment of the Mobile Device Extension for AD RMS will be illustrated later in this document using this topology.

One AD RMS cluster is installed in that forest and typically the aforementioned service connection point (SCP) is configured in Active Directory. Since all licensing and certification URLs point to the same cluster, and all users in the organization, regardless of their email domain or sub-domain, use the same cluster, the DNS SRV records for the discovery service mechanism point to that cluster's URL as follows:

  • Service discovery record for email domain suffix ð RMS service FQDN
  • Service discovery record for AD RMS cluster licensing URL ð RMS service FQDN

No additional redirection is needed at the AD RMS cluster.

Multiple forests with multiple certification clusters, all using the same cluster for licensing

In multi-forest organizations where users are scattered around domains in multiple forests, AD RMS architectural design requires that one AD RMS cluster is deployed in each forest to enable certification of the different users.

To simplify logging, troubleshooting, configuration and deployment most organizations configure the licensing ULRs in all the different certification clusters to point to the licensing location of one of the clusters, in essence making this cluster the only cluster that will be utilized to protect content. (This cluster may be either the certification cluster in one of the forests or a licensing-only cluster installed in one of the forests in addition to that forest's certification cluster). This so-called "centralized licensing" cluster is populated with trusted user domains (TUD) from all other clusters, and domain or forest trusts between the different forests are usually configured to enable cross-forest authentication and group expansion.

Note    For information on Trusted User Domains (TUD), see the eponym Microsoft TechNet article Trusted User Domain.

As a consequence, while Rights Account Certificates containing different certification URLS and signed by different clusters are issued to rich clients in different forests, all clients receive a Client Licensor Certificate from the same cluster, and all Publishing Licenses will be encrypted with the same key pair and will be stamped with the same URL.

Important Note    Since in mobile devices working with the Mobile Device Extension for AD RMS all transactions are atomic and there's no use for Rights Account Certificates, clients only interact with the RMS cluster used for licensing. The existence of an RMS cluster in a forest that is only used for certification is of no consequence to the mobile clients, and as a results Trusted User Domains are not used for mobile devices. This, in turn, means that only cluster actively used for licensing need to have the Mobile Device Extension installed, and clusters only used for certification in their respective forests don't need to be configured for mobile devices directly.

In this environment, users may have email addresses under the same or different domains. All publishing licenses contain the same URL.

Protecting content in this topology

When a user tries to protect content with a mobile device, the service discovery records for the user's email address domain or, recursively, a parent domain of that domain will point the user to the single licensing cluster. Authentication will be triggered when trying to acquire a Publishing License to protect content and the federation flow will involve authentication in the user's source forest as needed.

Authentication for users in a forest different from the one used for licensing may be achieved through a federated trust between AD FS servers in the different forests, or via a single AD FS server in the forest where licensing is being performed by using AD trusts established between the forests to authenticate users in their respective forests.

Aside from the underlying requirements of setting up such a federation topology, the details of the authentication flow between the different forests are abstracted by the federation server platform, and all that matters to the Mobile Device Extension is that, once authenticated in its own forest, the user will be granted a valid access token with the necessary claims to connect to the service endpoints in the RMS cluster. One that happens, the user trying to protect content will be issued a Publishing License as required.

When the RMS client tries to protect content, the service discovery mechanism has to return to the client the licensing URL in the organization which is the same for all users. Once the user has entered their email the licensing URL of the organization is returned and the user starts the authentication process against that URL which will be performed using AD FS and the multiple directories involved, but ultimately will lead to the user being connected to the Publishing URL in MDE in the cluster used for licensing.

Consuming content in this topology

Likewise, when a user tries to consume protected content with a mobile device, the service discovery records for the URL in the Publishing License in the document will point the client to the URL of the cluster used to protect the content. Authentication will be triggered when trying to acquire a EUL and there the federation flow will proceed just as for the authoring scenario and involve authentication in the user's source forest as needed. Once authenticated, the user is able to acquire a EUL from the cluster that protected the content.

If the PL indicates groups as recipients of rights that are defined in any other forest, AD RMS will perform remote group expansion by utilizing the remote clusters group expansion services, but this will be completely transparent to the mobile device client and the REST related implementation.

Multiples forests with multiple licensing and certification clusters

Sometimes, organizations deploy multiple certification clusters with different licensing URLs in their multi-forest environment. In this case, MDE needs to be installed in each cluster utilized for licensing, and each of them needs to be configured to use AD FS in a way that supports authenticating all users that will be using that cluster to protect or consume content.

Protecting content in this topology

When a user tries to protect content with a mobile device, the email domain of the user will be used to find the corresponding server and the service discovery mechanism will direct the user to the right cluster. As in the previous topology authentication might involve Federation across the different forests depending on the forest to which the user belongs.

If all users in the organization use email domains specific to the forest to which each user belongs, then different records for each domain will point the user directly to the RMS cluster in the right forest. In this case the user will be authenticated via AD FS locally in the same forest.

If all users and organization share the same email domain or there isn't a one to one mapping between email domains and forests, the user will be directed to the RMS cluster in one of the forests by the service discovery record corresponding to the email domain, and the post-authentication service discovery process will be used to direct the user to the RMS cluster that the user should use to protect content. This process uses information in a table associating Active Directory groups to the corresponding RMS FQDN to direct the user to the right cluster. As in the previous topology, authentication might involve federation across the different forests depending on the forest to which the user belongs. A properly configured federation environment will be then required to authenticate the user against their source forest.

Consuming content in this topology

In this configuration there will be content protected with different URLs depending on where the author was located.

This means that the service discovery records for consumption will include entries for each of the clusters in the organization that are used for licensing as indicated before.

When content is consumed by a mobile device user, the RMS client will use the service discovery record for the URL indicated in the PL in the protected document which typically will lead the user to the cluster that was used by the author to protect the content. The client authentication will be triggered by access to the URLs in the authors cluster. As in the previous topology authentication might involve federation across the different forests depending on the forest to which the user belongs.

A properly configured federation environment will be then required to authenticate the user against their source forest. If the federation setup can identify the user's source forest and authenticate it accordingly (which is possible at least if there are forest trusts in place) the user should be authenticated properly and the necessary claims extracted. Once the necessary tokens are obtained including the claims for the user's email address the user may be redirected to a different RMS cluster for obtaining an End User License. This is done in cases in which it is desired that the user consume content using a different cluster with an Imported Trusted Publishing domain from the source cluster. In most cases, the cluster used to consume content is the same used to protect it.

After the user reaches the licensing URL in the right cluster, an End Use License will be issued by the cluster in the document author's forest.

Single or multiple forest with a licensing-only cluster

Sometimes, organizations deploy multiple licensing-only clusters in their environment. A Licensing-Only cluster is a cluster deployed in the same forest as a certification cluster. The Licensing-Only cluster is subordinated to the certification cluster, which will handle all certification requirements in the forest.

In these organizations some individual users need to be pointed to different service URL to protect content than other users with the same or different email domain. For example a group of high-level executives might need to use a special AD RMS cluster, which is different from the one used by all the other users at the company. In most environments where this is the case, different licensing clusters are thus assigned to different users via registry overrides. This will not be possible with the mobile RMS clients since mobile devices do not support registry overrides or any other kind of manageable persistent application configuration.

Protecting content in this topology

When content is protected in this topology, the DNS-based service discovery will point the user to the default cluster for the user's email domain. If the users assigned to a licensing only cluster share the same email domain with users assigned to different cluster then after authentication group membership-based redirection based on a table in the RMS configuration database associating Active Directory groups with RMS clusters will point the user to the licensing only cluster that corresponds to them.

Consuming content in this topology

Conversely, when content is consumed in this topology, the DNS-based service discovery will point the user to the cluster that was used to protect the content. Authentication at this cluster might involve federation between forests or it might be performed within a single forest.

Once the user is authenticated a EUL will be issued by the licensing only cluster just as in the single cluster case.

Cross-organization with federated trust

Some organizations collaborate with other organizations via federated trusts. In these cases, rich clients are activated, obtain CLC's, and consume content with the same AD RMS cluster.

Since authentication is performed on the mobile device clients through a federation flow, the fact that these partners are external users should be opaque to the clients and to the service, and this topology looks exactly like the single cluster, single forest scenario topology for implementation purposes.

As long as the federation platform is correctly configured and is able to authenticate the external users they will receive the right artifacts and be able to acquire licenses from the organization's AD RMS cluster. If an organization wants their federated partners to be able to protect content against their cluster, the organization will need to configure the DNS-based service discovery for their email domains to point to the controlling organization's AD RMS cluster.

TPD Imported from existing or deprecated AD RMS server

In some organizations with special requirements, multiple clusters are deployed (possibly at different times) and trusted publishing domains (TPD) are exchanged between them. Clients are then configured to consume content from one cluster even though it has been protected with another cluster. The typical reasons for such environments are related to network topologies, isolated environments, and decommissioned clusters in migrations or merger scenarios.

Note    For information on trusted publishing domains (TPD), see the eponym Microsoft TechNet article Trusted Publishing Domain.

This redirection is typically implemented via registry overrides on rich clients. As already noticed, the mobile device clients do not support registry overrides.

Protecting content in this topology

A user is directed to whatever URL is registered for the user's email domain name in DNS in accordance to the service discovery record(s). The user may or may not be redirected to a different cluster for acquiring a PL based on the group-cluster mapping table in the configuration database, just as in the regular multi-forest environment.

Consuming content in this topology

For consumption, the RMS client would look up in DNS the service discovery record for the domain in the PL. This may point the user to the same cluster that was used to protect the content (the default single-forest behavior) if that cluster is still available, or to a cluster with an imported TPD if that cluster is not available or not intended to be used by this user.

In either case, the user may be redirected based on group membership to a different cluster (the original one or another one with a TPD) for a variety of reasons (e.g. geographical affinity). Once the client reaches the right cluster successfully, the server can use the imported Trusted Publishing Domain to issue an End User License for the content.

Building an evaluation environment

This section guides you through a set of instructions required to build a representative lab environment to evaluate the Mobile Device Extension.

For the sake of simplicity and in order to focus on the key aspects that relate to the Mobile Device Extension deployment, the chosen test topology is a single cluster in a single forest.

The guidance in this lab can also be utilized to deploy the Mobile Device Extension in a production environment, but adjustments to the process will be necessary depending on the target environment's topology, configuration and state.

It must be noted that this guide not only covers the deployment of the Mobile Device Extension, but also that of AD RMS and its databases, the Active Directory domain, AD FS and other pre-requisite software. When applying this guide to a preexisting environment most of the detailed steps have to be adapted or omitted accordingly.

Beyond the AD RMS cluster with its SQL Server database, the environment includes:

  • A single AD FS server integrated with Active Directory for authentication,
  • A single WAP proxy to publish on the Internet the Mobile Device Extension service endpoints,
  • A single Active Directory Certificate Services (AD CS) based certification authority to issue the required certificates,

The following diagram provides an overview of the overall test lab environment with the software and service components that need to be deployed / configured.

In this environment we have simplified as much as possible the environment to reduce the number of actions needed.

Building an Azure-based lab environment

A challenge in creating a useful lab environment is to enable its reusability and extensibility. Because creating a test lab can represent a significant investment of time and resources, your ability to reuse and extend the work required to create the test lab is important. An ideal test lab environment would enable you to create a basic lab configuration, save that configuration, and then build out multiple test lab scenarios in the future by starting with the base configuration.

For that reason and considering the above objectives, this guide will use for the corporate on-premises infrastructure the Microsoft Test Lab Guides (TLGs) available on Microsoft TechNet to build the lab environment.

The Microsoft Test Lab Guides (TLGs) allow you to get valuable hands-on experience with new products and technologies using a pre-defined and tested methodology that results in a working configuration.

Microsoft Test Lab Guides (TLGs) are a set of documents that step you through the configuration and demonstration of a Microsoft technology or product in a standardized test lab environment, which starts with a common base configuration that mimics a simplified intranet and the Internet. TLGs are designed to be modular, extensible, and stackable to configure complex, multi-product solutions. TLGs make learning about products, technologies, and solutions easier by providing that crucial hands-on, "I built it out myself" experience.

Note    For more information, see Test Lab Guides on Microsoft TechNet.

Moreover, another potential challenge relates to the hardware needed to run such a base configuration that involves several (virtual) machines.

For these reasons and considering the above objectives, this guide will leverage Microsoft Azure environment with Azure-based virtual machines (VM).
Consequently, the setup of the on-premises environment for this evaluation of the Mobile Device Extension will be based on the Test Lab Guide: Base Configuration in Azure. It will also leverage the Test Lab Guide: Deploying an AD RMS Cluster.

Finally, to streamline as much as possible the setup of this Azure-based test lab environment, and to test and evaluate the Mobile Device Extension for AD RMS, this guide will also leverage the Microsoft Azure PowerShell and Windows PowerShell cmdlets to configure the required services.

Introducing virtual machines in Azure

Azure Virtual Machines provides support for virtual machines (VMs) provisioned from the cloud. At a glance, a VM consists of a piece of infrastructure available to deploy an operating system and an application. Specifically, this includes a persistent operating system (OS) disk, possibly some persistent data disks, and internal/external networking "glue"/connectivity to hold it all together. With these infrastructure ingredients, it enables the creation of a platform where you can take advantage of the reduced cost and ease of deployment offered by Azure.

To mimic an on-premises deployment with a multi-VM workload as needed here, virtual networks are also required. This is where Azure Virtual Networks come into play. Azure Virtual Network let you provision and manage virtual networks (VNET) in Azure. A VNET provides the ability to create a logical boundary and place VMs inside it. VNET also provides the capability of connecting Azure Cloud Services (VMs, web roles, and worker roles) that are in the same affinity group directly with them.

Note    An affinity group is a container where you choose the location (Azure region) where you place your Azure resources. An affinity group represents also a convenient way to designate an Azure data center region with the name of your choice. (As of this writing, Azure Cloud Services can be added to an affinity group only at the time of creation of the service.).

Azure Virtual Network provides control over network topology, including configuration of IP addresses, routing tables and security policies. A VNET has its own private address space. The address space is IPv4 only (but could be extended to IPv6 in a future release).

Note    Azure Virtual Network also allows to securely extend on-premises networks into the cloud. With the ability to assign a private address range for its VNET, you can indeed treat it as an extension of your own corporate private network address space by establishing appropriate gates (VPN gateway) between your on-premises corporate private network and virtual network(s) in Microsoft Azure. For that purpose, Azure Virtual Network enables to set up secure site-to-site connectivity between the organization's corporate VPN gateway and Azure, and then to connect the organization's on-premises corporate network to the organization's Azure tenant by using a VPN gateway along with the industry-standard IPsec protocol.

With such a capability, IT administrators can easily create a logically isolated private environment in Azure, and connect it to the organization's on-premises IT infrastructure by using a secure VPN tunnel. Once set up, the isolated Azure environment can be viewed as a natural extension of the on-premises corporate network.

To synthetize, Azure Virtual Network allows you to create private network(s) of VMs in your Azure tenant environment that you can assign IP addresses to (and then optionally connect to your data center through a VPN gateway). Using this method, you can seamlessly connect on-premises (virtual) machines to VMs running in your Azure tenant.

The fundamental requirements for deploying AD DS on VM(s) in Azure differ very little from deploying it in VMs (and, to some extent, physical machines) on-premises. For example, if the domain controller that you deploy on VMs are replicas in an existing on-premises corporate domain/forest, then the Azure deployment can largely be treated in the same way as you might treat any other additional AD DS site. That is, subnets must be defined in AD DS, a site created, the subnets linked to that site, and connected to other sites using appropriate site-links. There are, however, a number of differences that are common to all Azure deployments and some that vary according to the specific deployment scenario.

Note     For more information, see the Microsoft TechNet articles Install a new Active Directory forest in Windows Azure and Guidelines for Deploying Windows Server Active Directory on Windows Azure Virtual Machines that cover the fundamental differences and explain in great detail how successfully deploy and operate AD DS in Azure. The former deals with a standalone configuration in the cloud as we will deploy later in this document whereas the latter highlights the requirements for deploying AD in a hybrid scenario in which AD DS is partly deployed on-premises and partly deployed on VMs in Azure.

Understanding the ongoing costs of virtual machines in Azure

Virtual machines in Azure incur an ongoing monetary cost when they are running. This cost is billed against your free trial, MSDN subscription, or paid subscription.

Note    For more information about the costs of running Azure virtual machines, see Virtual Machines Pricing Details and Azure Pricing Calculator on the Azure Web site.

To minimize the cost of running the test lab virtual machines, you can do one of the following:

  • Create the test lab environment and perform your needed testing and demonstration as quickly as possible. When complete, delete the test lab virtual machines from the VIRTUAL MACHINES page of the Azure management portal.
  • Shut
    down your test lab virtual machines into a de-allocated state from the VIRTUAL MACHINES page of the Azure management portal as covered later in this document. However, you should start your virtual machines in a specific order.

Signing up for an Azure trial

If you do not already have an Azure account, you can sign up for a free one month trial. If you have an MSDN Subscription, see Azure benefit for MSDN subscribers on the Azure Web site.

Note    Once you have completed your trial tenant signup, you will be redirected to the Azure account portal
and can proceed to the Azure management portal by clicking Portal at the top right corner of your screen.

At this stage, you should have an Azure trial subscription to proceed with the steps in this guide.

Preparing the local environment for Azure

Microsoft Azure PowerShell is the module for Windows PowerShell that you can use to control and automate the deployment and management of the workloads in Azure.

Installing and configuring Azure PowerShell

The configuration of Azure PowerShell on a local computer consists of:

  • Installing Azure PowerShell,
  • Verifying that Azure PowerShell can run scripts, and enabling scripts to run in Windows PowerShell,
  • Verifying that WinRM allows Windows PowerShell to connect, and configuring WinRM to support basic authentication.

Note that this local computer must have Internet connectivity.

Installing Azure PowerShell

To install the Azure PowerShell module, proceed with the following steps:

  • Open a browsing session and navigate to the Azure Downloads page.
  • Scroll down to Command line tools.

  • Under Windows downloads, click Windows Azure PowerShell.

  • When prompted to run or save the .exe installation file (WindowsAzurePowerShell.3f.3.3fnew.exe), choose the Run button.
  • A User Account Control dialog brings up. Click Yes. This launches the Web Installer Platform 5.0 as of this writing.

  • Click Install and follow the online instructions to complete the installation.

  • Click I Accept. The package is downloaded and installed.

  • Click Finish.
  • Click Exit.

You can run then the cmdlets from the Azure PowerShell console.

To connect to your Azure subscription with the Azure PowerShell console, proceed with the following steps:

  • Open an Azure PowerShell command prompt.

  • Run the following command.

PS C:\> Add-AzureAccount

  • A Sign in to Azure dialog brings up.

  • Type the email address and click Continue. You're redirected to a Sign In page
  • Type the password associated with your account and click Sign in.
  • Azure authenticates you, saves the credential information, and then closes the dialog. A message states that your subscription is now selected has the default subscription.

PS C:\> VERBOSE: Account "your email address" has been added.
PS C:\> VERBOSE: Subscription "xxx" is selected as the default subscription.
PS C:\> VERBOSE: To view all the subscriptions, please use Get-AzureSubscription.
PS C:\> VERBOSE: To switch to a different subscription, please use Select-AzureSubscription.help azure
PS C:\>

  • Once connected to your default subscription, you can use the built-in Help system to list and get help about the cmdlets in the Azure PowerShell module. To list the available cmdlets, run the following command:

PS C:\> help azure

You can then display help about a specific cmdlet by typing help followed by the name of the cmdlet, for example "help New-AzureVM".

Note    For instructions, see the Microsoft TechNet articles How to install and configure Windows Azure PowerShell and Get Started with Windows Azure Cmdlets.

Note    For more information about the cmdlets in the Azure PowerShell module, see the Microsoft MSDN article Windows Azure Management Cmdlets.

Enabling Windows PowerShell scripts

To verify that Azure PowerShell can run scripts, proceed with the following steps;

  1. Open an elevated Azure PowerShell command prompt, and run the following command:

PS C:\> Get-ExecutionPolicy

  1. If the value returned is anything other than RemoteSigned, you need to change the value to RemoteSigned.

Note     A digital signature is required from a trusted publisher on scripts and configuration files that are downloaded from the Internet (including email and instant messaging programs) so that they can run. However, a digital signature isn't required on scripts that you have written on the local computer (not downloaded from the Internet). Finally, you can run scripts that are downloaded from the Internet and not signed, if the scripts are unblocked, such as by using the Unblock-File cmdlet. For more information, see the Microsoft TechNet article
about_Execution_Policies..

Run the following command if needed:

PS C:\> Set-ExecutionPolicy RemoteSigned

When asked, press "Y" to confirm the operation.

Enabling WinRM for remote PowerShell shell

To verify that WinRM allows Windows PowerShell to connect, proceeds as follows:

  1. In the above elevated Azure PowerShell session, run the following command to check the status of the WinRM service:

PS C:\> sc query winrm

  1. If the WinRM service isn't running, start it with the following command:

PS C:\> net start winrm

  1. Run the following command:

PS C:\> winrm get winrm/config/client/auth

  1. In the results, look for the value "Basic =". If the value is "Basic = false", you must change the value to "Basic = true".

If the value has to be changed, run the following command:

PS C:\> winrm set winrm/config/client/auth @{Basic="true"}

The value between the braces { } is case-sensitive. In the command output, verify the value "Basic = true".

  1. If you started the WinRM service in step 2, run the following command to stop it:

PS C:\> net stop winrm

You are now ready to setup the Windows Server 2012 R2 Base Configuration needed for the test lab.

This is the purpose of the next section.

Setting up the Windows Server 2012 R2 Base Configuration test lab

By following the instructions outlined hereafter, you should be able to successfully prepare your test lab environment based on virtual machines (VMs) running in Azure to later deploy and configure the mobile Device Extension environment, install and configure it with AD RMS along with Active Directory Federation Services (AD FS) in Windows Server 2012 R2 that is a prerequisite, etc. and start evaluating/using it.

Important note    Individual virtual machines (VMs) are needed to separate the services provided on the network and to clearly show the desired functionality. This being said, the suggested configuration to later evaluate the Mobile Device Extension for AD RMS is neither designed to reflect best practices nor does it reflect a desired or recommended configuration for a production network. The configuration, including IP addresses and all other configuration parameters, is designed only to work on a separate test lab networking environment.

Any modifications that you make to the configuration details provided in the rest of this document may affect or limit your chances of successfully setting up the on-premises test lab environment. We recommend following this guide as-is first to familiarize yourself with the steps involved, before attempting a deployment on an environment with a different configuration.

In order to complete the document's walkthrough, you need an environment that consists of the following components for the Azure-based test lab infrastructure:

  • One Azure virtual machine running Windows Server 2012 R2 (named DC1) that is configured as a domain controller with a test user and group accounts, and Domain Name System (DNS) server.
  • One Azure virtual machine running Windows Server 2012 R2 (named ADFS1) that is configured as an enterprise root certification authority and as an AD FS federation server.
  • One Azure virtual machine running Windows Server 2012 R2 (named ADRMS1) that is configured as an AD RMS cluster.

Note    For more information about the system requirements for installing AD RMS, see the Microsoft TechNet article Pre-installation Information for Active Directory Rights Management Services.

  • One Azure virtual machine running Windows Server 2012 R2 (named SQL1) that is configured as a SQL Server 2012 computer, which will be used to support the AD RMS configuration and logging databases.

Important note    The Mobile Device Extension for AD RMS requires that the AD RMS deployment uses a full Microsoft SQL Server-based database on a separate server and not the Windows Internal Database that is often used for testing on the same server.

  • One Azure virtual machine running Windows Server 2012 R2 (named EDGE1) that is configured as a Web server.

Important note    The configuration of the Azure virtual machines and the related Azure virtual network (see below) in this guide is designed to give you hands-on practice in creating an AD RMS test environment suitable for testing and evaluating the Mobile Device Extension for AD RMS. The design decisions made in this guide were geared toward increasing your hands-on experience and to some degree reflect AD RMS best practices configuration. For full best practices and design and planning information related to AD RMS, see the Microsoft TechNet articles AD RMS Prerequisites, AD RMS Performance and Logging Best Practices, and AD RMS Architecture Design and Secure Collaboration Scenarios.

Note     Windows Server 2012 R2 offers businesses and hosting providers a scalable, dynamic, and multitenant-aware infrastructure that is optimized for the cloud. For more information, see the Microsoft TechNet Windows Server 2012 R2 homepage.

These Azure VMs will enable you to:

  • Connect to the Internet to install updates, and access Internet resources in real time.
  • Remotely managed those using Remote Desktop connections by your computer that is connected to the Internet or your organization network.

Note    You must be logged on as a member of the Domain Admins group or a member of the Administrators group on each computer to complete the tasks described in this guide. If you cannot complete a task while you are logged on with an account that is a member of the Administrators group, try performing the task while you are logged on with an account that is a member of the Domain Admins group.

  • Create snapshots so that you can easily return to a desired configuration for further learning and experimentation.

For that purpose, these VMs notably expose one public endpoint for Remote Desktop Protocol (RDP) and another one for remote Windows PowerShell (WinRMHTTPS) as illustrated hereafter.

The EDGE1 VM exposes in addition a public endpoint for HTTPS (HttpsIn).

The integrated test lab consists of:

  • A first subnet (10.0.1.0/24) that will expose the test lab resources that require Internet connectivity/endpoint(s). It is separated from a second subnet that hosts the corporate intranet resources. The computer on this subnet is EDGE1.
  • A second subnet (10.0.2.0/24) that simulates a private intranet. Computers on the Subnet2 subnet are DC1, ADRMS1, ADFS1, and SQL1.

Important Note    Azure assigns IP addresses dynamically, which may seem inconvenient when you have the habit to set static IP addresses, especially for domain controllers. More specifically, static IP addresses are NOT supported. For more information, see section IP Addressing and DNS
of the MSDN article Guidelines for Deploying Windows Server Active Directory on Windows Azure Virtual Machines.

Within
a
subnet,
the first 3
addresses are reserved
and, in the case of
Subnet2 above,
the first
address that is assigned
by the Azure DHCP
will be
10.0.2.4. However, it is guaranteed
that the first
address
will remain constant, which is not
the case
for the addresses that belong to the rest of the range.
Such a behavior must be taken into account if you want that a specific VM
will have the same
IP
address allocated over the time, which
will
be
the case of our
domain controller DC1 that will also host the DNS server for the test lab environment.

For illustration purposes, we have opted to configure the domain litware369.com (LITWARE369). Since the lab depends on you using a unique name for your domain, you will have to choose a domain name of your own. For checking purposes, you can use the domain search capability provided by popular domain name registrars. Alternatively, you can use a subdomain of a domain you already control in lieu of Litware369.com.

Whenever a reference to litware369.com is made in a procedure, it has to be replaced by the DNS domain name of your choice to reflect accordingly the change in naming. Likewise, any reference to LITWARE369 should be substituted by the NETBIOS domain name of your choice.

Furthermore, for the sake of simplicity, the same password "pass@word1" is used throughout the procedures of the above TLGs as well as the ones detailed in this document. This is neither mandatory nor recommended in a real world scenario.

To perform all the tasks in this guide, we will use the LITWARE369 domain Administrator account AzureAdmin for each Windows Server 2012 R2 Azure VM, unless instructed otherwise.

Note    When you configure Windows Server 2012 R2, you are required to click Continue or Yes in the User Account Control (UAC) dialog box for some tasks. Several of the configuration tasks require UAC approval. When you are prompted, always click Continue or Yes to authorize these changes. Alternatively, see the Appendix of this guide for instructions about how to set the UAC behavior of the elevation prompt for administrators.

The following five steps must be followed in order to set up the on-premises core infrastructure of our test lab:

  1. Deploying the base workloads in Azure.
  2. Configuring the domain controller.
  3. Configuring the root Enterprise CA.
  4. Deploying the database server.
  5. Deploying the federation server.
  6. Preparing the Internet-facing computer.
  7. Deploying the rights management server.

Deploying the base workloads in Azure

To deploy the base workloads in your Azure subscription, proceed with the following steps:

  1. Download the script New-TestLabEnvironment.ps1 and unblock it so that it can comply with the above execution policy and executed in your environment.

Note     The script New-TestLabEnvironment.ps1 is largely inspired by the sample script Deploy a domain controller and member using Windows Azure Virtual Machines available on the Microsoft TechNet Script Center.

Note     The script Remove-TestLabEnvironment.ps1 enables you to later seamlessly remove the test lab environment from your Azure subscription. Its usage is not covered in this paper since its arguments are almost the same as the ones used by the above script.

  1. Open an Azure PowerShell command prompt and navigate to the folder where the above script is located, for example C:\Scripts in our illustration.
  2. Run the following command to connect to your subscription:

PS C:\Scripts> Add-AzureAccount

A Sign in to Windows Azure dialog brings up.

  1. Enter your email address and click Continue. You're redirected to a Sign In page.
  2. Type the password associated with your account for your Azure (trial) subscription and click Sign in. You should now be connected to your default subscription.
  3. Run the following command to deploy the base workloads in your subscription:

PS C:\Scripts> .\New-TestLabEnvironment.ps1 -ServiceName "mfalab" -Location "North Europe"

  1. The script New-TestLabEnvironment.ps1 proceeds with the setup and will prompt you to gather the administrator credentials to use when provisioning the aforementioned VMs. A Windows PowerShell credential required dialog brings up.

  1. Provide the administrator credentials you want to use. We will use throughout this walkthrough "AzureAdmin" for the username and "pass@word1" for the password.

The script New-TestLabEnvironment.ps1 continues with the setup. It executes the following tasks for you:

  • Create an affinity group to associate all the workloads to be deployed with.

    The name of the affinity group is based on the provided service name in the command line, for example "mfalab" in our configuration, with the added suffix "aff", resulting for example in "mfalabaff" in our configuration.

  • Create a cloud service for these workloads.

    Like with the affinity group name, the name of the cloud service is based on the provided service name in the command line with the added suffix "svc", for example "mfalabsvc" in our configuration.

  • Create an account storage to store the VHDs of the workloads as blobs.

    The name of the account storage is based on the provided service name in the command line with the added suffix "stor", for example "mfalabstor" in our configuration.

  • Create a VNET for the workloads.

    The name of the VNET is based on the provided service name in the command line with the added suffix "vnet", for example "mfalabvnet" in our configuration. The address space is 10.0.0.0/8.

    By default, the name of the above Subnet1 is "-subnet1" prefixed by the name of the VNET, for example "mfalabvnet-subnet1" in our configuration. The address space is 10.0.1.0/24 by default.

    Likewise, the name of the above Subnet2 is "-subnet2" prefixed by the name of the VNET, for example "mfalabvnet-subnet2" in our configuration. The address space is 10.0.2.0/24 by default.

  • Create a DC1 virtual machine of small size based on the latest available Windows Server 2012 R2 image, add a second disk for the AD DS role service, install the AD DS role service, and finally install Active Directory Domain Services (AD DS) to make the DC1 computer a domain controller in Windows Server 2012 R2. This action upgrades the AD DS schema as part of the domain controller creation.
  • Create a SQL1 virtual machine of medium size based on the latest available Windows Server 2012 R2 image. SQL Server 2012 will be installed later on this machine. This machine will host an SQL Server instance that will be used for the AD RMS deployment on the ADRMS1 machine (see below).
  • Create a domain-joined ADFS1 virtual machine of small size based on the latest available Windows Server 2012 R2 image, and install the Active Directory Certificates Services (AD CS) role service and install an Enterprise Certification Authority (CA) along with Internet Information Services (IIS). The Active Directory Federation Services (AD FS) role service will be installed later on this machine and referred as to adfs.litware369.com.
  • Create a domain-joined ADRMS1 virtual machine of small size based on the latest available Windows Server 2012 R2 image, and install Internet Information Services (IIS). The Active Directory Rights Management Services (AD RMS) role service will be installed later on this machine and referred as to adrms.litware369.com.
  • Create an Internet-facing domain-joined EDGE1 virtual machine of small size based on the latest available Windows Server 2012 R2 image, and install Internet Information Services (IIS). The default web site on this machine will be later referred as to www.litware369.com. As already mentioned, a public endpoint for HTTPS (HttpsIn) is defined for that purpose as part of the script configuration.

The script leverages the remote Windows PowerShell capabilities along with the Windows Server automation with Windows PowerShell to setup the above virtual machines.

Note     To learn about the Windows PowerShell command line and scripting environment, see the TechNet Script Center.

Note     For information about installing, learning, using, and customizing Windows PowerShell, see the Microsoft TechNet article Scripting with Windows PowerShell.

Note     For information about what scripts are and how to run them in Windows PowerShell, see the Microsoft TechNet article Running Scripts. This article includes basic information about creating scripts and configuring your computer to run scripts.

Note     For information on Windows Server Automation with Windows PowerShell, see the eponym Microsoft TechNet article. This article provides references to install and configure the various role services.

If needed to accommodate your own configuration, the script New-TestLabEnvironment.ps1 enables you to customize the VNET and VM details:

PS C:\Scripts> .\New-TestLabEnvironment.ps1 -ServiceName "mfalab" -Location "North Europe" `
-DC1Name "dc1" -DCVMSize "Small" -FQDNDomainName "litware369.com" -NetBIOSDomainName "LITWARE369" `
-ADFS1Name "adfs1" –ADFS1VMSize "Small" `
-ADRMS1Name "adrms1" –ADRMS1VMSize "Small" `
-SQL1Name "sql1" –SQL1VMSize "Small" `
-EDGE1Name "edge1" EDGE1VMSize "ExtraSmall" `
-VNetAddressPrefix "10.0.0.0/8" -Subnet1AddressPrefix "10.0.1.0/24" -Subnet2AddressPrefix "10.0.2.0/24"

At the end of the script, you should have an up and running base configuration that we will leverage in the next steps.
The next sections imply that you have in place such an environment.

Furthermore, to externally resolve the adrms.litware369.com, adfs.litware369.com, and www.litware369.com FQDN names and point to the above cloud service in Azure, you will need to create the following CNAME records in your DNS zone (e.g. litware369.com in our configuration) of your domain registrar. The exact method depends on the chosen domain registrar.

You will need to externally resolve these FQDN names for the Web Application Proxy (WAP).

Name

Type

Value

TTL

adrms

CNAME

mfalabsvc.cloudapp.net

3 hours

adfs

CNAME

mfalabsvc.cloudapp.net

3 hours

www

CNAME

mfalabsvc.cloudapp.net

3 hours

Configuring the domain controller

To configure the domain controller, proceed with the following steps:

  1. Opening a remote desktop connection on the domain controller.
  2. Configuring public DNS forwarders.
  3. Creating DNS records.
  4. Creating a group Managed Service Account (gSMA).
  5. Creating additional user accounts and groups.
  6. Allowing user accounts to log on locally.

The following subsections describe in the context of our test lab environment each of these steps.

Opening a remote desktop connection on the domain controller

To open a remote desktop connection on the DC1 computer, proceed with the following steps:

  1. Open a browsing session and navigate to the Azure management portal at https://manage.windowsazure.com.
  2. Sign in with your administrative credentials to your Azure subscription.
  3. On the left pane of the Azure management portal, click VIRTUAL MACHINES.

  1. On the virtual machine page, at the top, ensure VIRTUAL MACHINE INSTANCES is selected.
  2. Select the dc1 machine and click CONNECT at the tray of the bottom.

  1. Click Open. A Remote Desktop Connection dialog brings up.

  1. Check Don't ask me again for connections to this computer and click Connect.
  2. A Windows Security dialog brings up.
  3. Log on as LITWARE369\AzureAdmin with "pass@word1" as password.

  1. Another Remote Desktop Connection dialog brings up.

  1. Check Don't ask me again for connections to this computer and click Yes.

The connection is then established to the remote desktop.

Configuring public DNS forwarders

The Windows PowerShell script used to setup our test lab environment configures the DNS server on the DC1 computer for name resolution instead of the Azure-provided name resolution.

We must ensure that our DNS server is configured to use the root hints if no forwarders are available so that we can correctly resolve name over the Internet in our test lab environment.

Note     For more information on the root hints, see the eponym page Root Servers.

To configure the DNS server to use the root hints, proceed with the following steps:

  1. Open a Windows PowerShell command prompt, and run the following command to start the DNS Manager console:

PS C:\Users\AzureAdmin> dnsmgmt.msc
PS C:\Users\AzureAdmin>

The DNS Manager console brings up.

  1. In the console tree, select DC1.
  2. On the Action menu, click Properties. The DC1 Properties dialog brings up.
  3. Select the Forwarders tab.

  1. Ensure that Use rot hints if no forwarders are available is checked.
  2. Click OK and close the DNS Manager console.
  3. From the above Windows PowerShell command prompt, type the following command to validate the resolution with the root hints:

PS C:\Users\AzureAdmin> dnscmd /ipvalidate /roothints 192.5.5.241

. completed successfully.
Raw Flags ResultCode NoTcp RTT IP Address
---------------------------------------------------------------------------
00001000 0 Success 0 10 192.5.5.241
Command completed successfully.

PS C:\Users\AzureAdmin>

You should see Success as the result code.

Creating DNS records

To create a DNS record for adfs, adrms, and www, proceed with the following steps:

  • Open a remote desktop session as per previous section.
  • Open an elevated Windows PowerShell command prompt and run the following command to add an A record for adfs:

PS C:\users\AzureAdmin> Add-DnsServerResourceRecord -ZoneName "litware369.com" -A -Name "adfs" -IPv4Address "10.0.2.5"
PS C:\users\AzureAdmin>

Important note    If the DNS resolution of the AD FS service endpoint is performed through CNAME record lookup instead of through an A record lookup, you will be repeatedly prompted for credentials later in this lab during sing-in.

Note    For more information on the DNS cmdlets, see the Microsoft TechNet article Domain Name System (DNS) Server Cmdlets in Windows PowerShell.

  • Run the following command to add a CNAME record for adrms:

PS C:\users\AzureAdmin> Add-DnsServerResourceRecord -CName -Name "adrms" -HostNameAlias "adrms1.litware369.com" -ZoneName "litware369.com"
PS C:\users\AzureAdmin>

  • Run the following command to add a CNAME record for www:

PS C:\users\AzureAdmin> Add-DnsServerResourceRecord -CName -Name "www" -HostNameAlias "edge1.litware369.com" -ZoneName "litware369.com"
PS C:\users\AzureAdmin>

Creating a group Managed Service Account (gSMA)

A group Managed Service Account (gMSA) account will be required during the AD FS installation and configuration. The benefit of using a gMSA is its auto-negotiated password update feature.

Note    For more information, see the blog post New features in Active Directory Domain Services in Windows Server 2012, Part 8: Group MSAs (gMSAs). 

To create the gMSA account, proceed with the following steps:

  • From the above elevated Windows PowerShell command prompt, run the following command to verify whether the KDS Root Key has been created in your domain to enable gMSA in your domain:

PS C:\users\AzureAdmin> Get-KdsRootKey
PS C:\users\AzureAdmin>

  • If it has not been created (the output displays no information), run the following command to create the key:

PS C:\users\AzureAdmin> Add-KdsRootKey –EffectiveTime (Get-Date).AddHours(-10)

Guid
----
7d5decb2-6c35-2b0c-6286-8055e413f2a5

PS C:\users\AzureAdmin>

Note    For more information, see the Microsoft TechNet article Key Distribution Service (KDS) in Windows PowerShell. 

  • Run the following command:

PS C:\users\AzureAdmin> New-ADServiceAccount FsGmsa -DNSHostName adfs.litware369.com -ServicePrincipalNames http/adfs.litware369.com
PS C:\users\AzureAdmin>

Creating additional user accounts and groups

We will now create the following additional user accounts and groups in our domain litware369.com. The following table lists the user accounts that we need to create at this time:

Account Name

User Logon Name

Email Address

Group

ADRMSSVC

ADRMSSVC

   

Robert Hatley

RobertH

roberth@litware369.com

Employees, Finance

Janet Schorr

JanetS

janets@litware369.com

Employees, Marketing

Stuart Railson

StuartR

stuartr@litware369.com

Employees, Engineering

These user accounts and groups are used to complete the walkthroughs later in this document.

To create the above user accounts, open an elevated Windows PowerShell command prompt, and run the following command. All the user accounts will use the password: "pass@word1":

PS C:\users\AzureAdmin> Import-Module -Name ActiveDirectory
PS C:\users\AzureAdmin> New-ADUser -Name ADRMSSVC -GivenName ADRMSSVC -UserPrincipalName "ADRMSSVC@litware369.com" -AccountPassword (ConvertTo-SecureString -AsPlainText "pass@word1" -Force) -ChangePasswordAtLogon $false -PasswordNeverExpires $true -Enabled $true
PS C:\users\AzureAdmin> New-ADUser –Name "Robert Hatley" -SamAccountName "roberth" -DisplayName "Robert Hatley" -AccountPassword (ConvertTo-SecureString "pass@word1" -AsPlainText –Force) -ChangePasswordAtLogon $false -PasswordNeverExpires $true -Enabled $true -UserPrincipalName "roberth@litware369.com" -EmailAddress "roberth@litware369.com" -GivenName "Hatley" -Surname "Robert"
PS C:\users\AzureAdmin> New-ADUser –Name "Janet Schorr" -SamAccountName "janets" -DisplayName "Janet Schorr" -AccountPassword (ConvertTo-SecureString "pass@word1" -AsPlainText –Force) -ChangePasswordAtLogon $false -PasswordNeverExpires $true -Enabled $true -UserPrincipalName "janets@litware369.com" -EmailAddress "janets@litware369.com" -GivenName "Schorr" -Surname "Janet"
PS C:\users\AzureAdmin> New-ADUser –Name "Stuart Schorr" -SamAccountName "stuartr" -DisplayName "Stuart Railson" -AccountPassword (ConvertTo-SecureString "pass@word1" -AsPlainText –Force) -ChangePasswordAtLogon $false -PasswordNeverExpires $true -Enabled $true -UserPrincipalName "stuart@litware369.com" -EmailAddress "stuart@litware369.com" -GivenName "Railson" -Surname "Stuart"
PS C:\users\AzureAdmin>

We now need to create some additional AD groups to assign users. The following table lists the groups that we need to create at this time.

Group Name

Email Address

Finance

finance@litware369.com

Marketing

marketing@litware369.com

Engineering

engineering@litware369.com

Employees

employees@litware369.com

To create the above user groups, proceed with the following steps:

  1. From the previous elevated Windows PowerShell command prompt, run the following command to create the various groups.

PS C:\users\AzureAdmin> New-ADGroup -Name Finance -SamAccountName Finance -GroupCategory Security -GroupScope Universal
PS C:\users\AzureAdmin> New-ADGroup -Name Marketing -SamAccountName Marketing -GroupCategory Security -GroupScope Universal
PS C:\users\AzureAdmin> New-ADGroup -Name Engineering -SamAccountName Engineering -GroupCategory Security -GroupScope Universal
PS C:\users\AzureAdmin> New-ADGroup -Name Employees -SamAccountName Employees -GroupCategory Security -GroupScope Universal
PS C:\users\AzureAdmin>

  1. Run the following command to add email addresses to group objects:

PS C:\users\AzureAdmin> Set-ADGroup Finance -Add @{mail='finance@litware369.com'}
PS C:\users\AzureAdmin> Set-ADGroup Marketing -Add @{mail='marketing@litware369.com'}
PS C:\users\AzureAdmin> Set-ADGroup Engineering -Add @{mail='engineering@litware369.com'}
PS C:\users\AzureAdmin> Set-ADGroup Employees -Add @{mail='employees@litware369.com'}
PS C:\users\AzureAdmin>

  1. Run the following command to add the user accounts to their appropriate groups:

PS C:\users\AzureAdmin> Add-ADGroupMember -Identity Employees -Members roberth,janets,stuartr
PS C:\users\AzureAdmin> Add-ADGroupMember -Identity Finance -Members roberth
PS C:\users\AzureAdmin> Add-ADGroupMember -Identity Marketing -Members janets
PS C:\users\AzureAdmin> Add-ADGroupMember -Identity Engineering -Members stuartr
PS C:\users\AzureAdmin>

Allowing users accounts to log on locally

By default, a domain user is not allowed to log on locally on a member server like the EDGE1 computer. A configuration of group policy can be modified so that a domain user account can log on locally on a member sever. Though this is NOT at all recommended in production environment but for testing purpose or in lab setup like this one this configuration can be quite handy. This configuration helps where there are only few computers.

To modify group policy settings to allow a domain user to log on locally a member server, proceed with following steps:

  1. Open an elevated command prompt if none, and run the following command:

PS C:\users\AzureAdmin> gpmc.msc
PS C:\users\AzureAdmin>

A Group Policy Management windows brings up.

  1. Double-click the name of the forest, double-click Domains, and double-click the name of the domain.

  1. Right-click Default Domain Policy, and then click Edit. A Group Policy Management Editor window pops up.

  1. In the console tree, expand Computer Configuration, Policies, Windows Settings, Security Settings, and Local Policies, and then click User Rights Assignment.
  2. In the details pane, double-click Allow Logon Locally.

  1. Check Define these policy settings, and then click Add User or Group. An Add User or Group dialog brings up.

  1. Click Browse to locate the account with the Select Users, Computers, or Groups dialog.

  1. Under Enter the object names to select, type "janets; roberth; administrators", click Check Names, and then click OK.
  2. Click OK in the Add User or Group dialog, and then click OK in the Allow log on locally Properties dialog box.
  3. Close the Group Policy Management Editor window.
  4. Close the Group Policy Management window.

Configuring the root Enterprise CA

To configure the root Enterprise CA, proceed with the following steps:

  1. Opening a remote desktop connection on the target computer.
  2. Configuring an appropriate certificate template for SSL certificate (optional).

Opening a remote desktop connection on the target computer

To open a remote desktop connection on the ADFS1 computer, proceed as illustrated before with the DC1 computer but with the ADFS1 computer instead. As previously illustrated, log on as LITWARE369\AzureAdmin with "pass@word1" as password since ADFS1 is a domain-joined computer.

Configuring an appropriate certificate template for SSL certificate (optional)

Services on both the ADFS1, ADRMS1, and EDGE1 computers will require secure sockets layer (SSL) / transport layer security (TLS) protection and corresponding certificates.

The Web Server certificate template is the one usually used to request such a SSL certificate for a domain-joined computer. Its settings are perfectly appropriated when the certificate must be installed on the server that requests it. However, for a test lab environment, it could be convenient to be able to export both the certificate and private key. In such situation, these default settings are not suitable because they do not allow to export the private key.

Consequently, we will configure a new certificate template that will duplicate this template, and thus present the same characteristics as the original template but with the possibility to export the private key.

To configure a certificate template for SSL certificate, proceed with the following steps:

  • Open a remote desktop session as per previous section.
  • From the Server Manager, click Tools and then Certification Authority. The Certification Authority console brings up.

  • Expand the certification authority litware369-ADFS1-CA so that you can see Certificate Templates. The name of the certification authority may differ if you have chosen another NetBIOS domain name and another name for the ADFS1 computer.
  • Right-click Certificate Templates and then click Manage. The Certificate Templates Console brings up.

  • In the details pane of the Certificate Templates console, right-click the Web Server template and then click Duplicate Template. A Properties of New Template dialog brings up.

  • Select the Request Handling tab.

  • Leave unchecked Allow private key to be exported.
  • Select the Security tab.

  • We must ensure the domain computer accounts will have the ability to enroll for the template. To do so, click Add. A Select Users, Computers, Services Accounts, or Groups dialog brings up.

  1. In Select Users, Computers, Service Accounts, or Groups, type "Domain computers". Click Check Names, and then click OK.
  2. Ensure that the group is selected and then select the Allow checkbox that corresponds to the Enroll permission.
  • Select the General tab.

  • Under Template display name, type a name that you want to use for the template, for example, "SSL Certificates" in our configuration.
  • Click OK.
  • Close the Certificate Templates console and return to the Certificate Authority console.
  • In the console tree of the Certification Authority console, right-click Certificate Templates, click New, and then click Certificate Template to Issue. An Enable Certificate Templates dialog brings up.

  • In the Enable Certificate Templates dialog, select the new certificate template that you just configured (SSL Certificates) and then click OK.

Deploying the federation server

This section walks you through the deployment of the federation server on the ADFS1 computer with the following steps:

  1. Issuing a SSL/TLS certificate.
  2. Installing and configuring the AD FS role service.

Note     For more information, see the Microsoft TechNet article Windows Server 2012 R2 AD FS Deployment Guide.

Important note     You must have domain administrator permissions to deploy the AD FS role.

Issuing a SSL/TLS certificate

The AD FS role service will require a Secure Socket Layer (SSL) server certificate. The certificate should have the following attributes:

  • Subject Name (CN): adfs.litware369.com
  • Subject Alternative Name (DNS): adfs.litware369.com

Note     For more information about setting up SSL/TLS certificates, see the Microsoft TechNet Wiki article Configure SSL/TLS on a Web site in the domain with an Enterprise CA.

To issue the SSL certificate, proceed with the following steps:

  1. Open a remote desktop session if needed as LITWARE369\AzureAdmin.
  2. Open an elevated Windows PowerShell command prompt, and run the following command:

PS C:\users\AzureAdmin.LITWARE369> Get-Certificate -Template SSLCertificates -SubjectName CN=adfs.litware369.comDnsName adfs.litware369.com -CertStoreLocation cert:\LocalMachine\My
Status Certificate Request
------ ----------- -------
Issued [Subject]…

PS C:\users\AzureAdmin.LITWARE369>

Note     If you have not configured a new certificate template (e.g. the SSLCertificates in our configuration), you can use the WebServer certificate template in lieu of in the above command.

Note    For more information, see the Microsoft TechNet article AD CS Administration Cmdlets in Windows PowerShell.

  1. The SSL certificate should now be imported into the Local Computer\My Store on the ADFS1 computer. Verify whether the SSL certificate has been imported by running the following command:

PS C:\users\AzureAdmin.LITWARE369> dir Cert:\LocalMachine\My

Thumbprint Subject
---------- -------
F1DF749C3D84DFF8BE9DED211145C53F2F06D83D CN=mfalabsvc.cloudapp.net
DD6F97EAF0CE4FDB039036199136752F62C8E027 CN=litware369-ADFS1-CA, DC=litware369, DC=com
59D4CFDD539CB616B5608A555E115824BAF14E77 CN=WMSvc-ADFS1
044F380EE49583536012D77D940ACEBBCAC05B86 CN=adfs.litware369.com

PS C:\users\AzureAdmin.LITWARE369>

The certificates are listed by their thumbprint in the Local Computer\My Store. We will be later interested in the thumbprint of the newly issued certificate, i.e. the one whose CN equals adfs.litware369.com, for example in our configuration: 044F380EE49583536012D77D940ACEBBCAC05B86.

Installing and configuring the AD FS role service

To install and configure the AD FS role service, proceed with the following steps:

  • Open an elevated Windows PowerShell command prompt if none, and run the following command:

PS C:\users\AzureAdmin.litware369> Install-windowsfeature adfs-federation –IncludeManagementTools

Success Restart Needed Exit Code Feature Result
------- -------------- --------- --------------
True No Success {Active Directory Federation Services}
WARNING: To finish configuring this server for the federation server role using Windows PowerShell, see
http://go.microsoft.com/fwlink/?LinkId=224868.

PS C:\Users\AzureAdmin.LITWARE369>

  • Run the following commands to create a Windows Internal Database (WID) along with the required gMSA account:

PS C:\users\AzureAdmin.litware369> Import-Module ADFS
PS C:\users\AzureAdmin.litware369> $certificateThumbprint = (Get-ChildItem cert:\LocalMachine\MY -DnsName "*adfs*" | Select-Object -First 1).Thumbprint
PS C:\users\AzureAdmin.litware369> Install-AdfsFarm –CertificateThumbprint $certificateThumbprint -FederationServiceDisplayName "Litware369" -FederationServiceName "adfs.litware369.com" –GroupServiceAccountIdentifier "LITWARE369\FsGmsa$"

Message Context Status
------- ------- ------
The configuration completed successf... DeploymentSucceeded Success

PS C:\Users\AzureAdmin.LITWARE369>

Important note    The '$' at the end of the gMSA account is required.

Note    If this is NOT the first time you run this command, add OverwriteConfiguration.

Preparing the Internet-facing computer

To prepare the Internet facing computer, proceed with the following steps in order:

  1. Opening a remote desktop connection on the target computer.
  2. Allowing the domain users to open a remote session.
  3. Testing the federation server configuration.
  4. Issuing a SSL/TLS certificate.
  5. Configuring HTTPS on the default web site.
  6. Deploying the Web Application Proxy (WAP).

The following subsections describe each of these steps in the context of our test lab environment.

Opening a remote desktop connection on the target computer

To open a remote desktop connection on the EDGE1 computer, proceed as illustrated before with the DC1 computer but with the EDGE1 computer instead. As previously illustrated, log on as LITWARE369\AzureAdmin with "pass@word1" as password since EDGE1 is a domain-joined computer.

Allowing the domain users to open a remote session

We have previously modified group policy settings so that our test user accounts can log on locally on member servers. We now need to apply the modified group policies.

To update the group policies, proceed with the following steps:

  1. Open a remote desktop session as per previous section.
  2. Open an elevated Windows PowerShell command prompt.
  3. Run the following command:

PS C:\users\AzureAdmin.LITWARE369> gpupdate /force
Updating policy...

Computer Policy update has completed successfully.
User Policy update has completed successfully.

PS C:\Users\AzureAdmin.LITWARE369>

In addition, we need to add our test user accounts to the local group Remote Desktop Users so that they can open a remote desktop session on the virtual machine in Azure.

To add the test user accounts to the local group Remote Desktop Users, proceed with the following steps:

  1. Open an elevated Windows PowerShell command prompt, and run the following command to add Janet Schorr to the local group:

PS C:\users\AzureAdmin.LITWARE369> net localgroup "Remote Desktop Users" /add "LITWARE369\janets"
The command completed successfully.

PS C:\users\AzureAdmin.LITWARE369>

  1. Run the following command to add Robert Hatley to the local group:

PS C:\users\AzureAdmin.LITWARE369> net localgroup "Remote Desktop Users" /add "LITWARE369\Roberth"
The command completed successfully.

PS C:\users\AzureAdmin.LITWARE369>

Testing the federation server configuration

Before testing the configuration, you need to configure your browser settings to trust the federation server role by adding your federation service name (for example in our configuration, https://adfs.liteware369.com) to the browser's local intranet zone.

To configure the browser settings accordingly on the EDGE1 computer, proceed with the following steps:

  1. Close the current remote desktop connection and open a new one on the EDGE1 computer as LITWARE369\JanetS with "pass@word1" as password.
  2. Start Internet Explorer and select Internet Options on the Tools menu. An Internet Options dialog pops up.
  3. Click the Security tab, select the Local intranet zone, and then click Sites. A Local intranet dialog appears.

  1. Click Advanced. A Trusted sites dialog appears.

  1. In Add this website to the zone, type "https://adfs.litware369.com", and then click Add. You should replace litware369.com by your own domain as already mentioned.
  2. Click Close, and then click OK.

  1. Verify that the security level for the zone is set to the default setting of Medium-low which enables Windows integrated authentication for Intranet zones.
  2. Click OK to close the Internet Options dialog.

To verify that a federation server on ADFS1 is operational, proceed with the following steps:

  • Open a browsing session on ADFS1 and navigate to the federation service metadata endpoint, for example, in our configuration:

https://adfs.litware369.com/federationmetadata/2007-06/federationmetadata.xml

If in your browser window you can see the federation server metadata without any SSL errors or warnings, your federation server is operational.

  • You can alternatively navigate to the metadata exchange endpoint, which offers an XML service description:

https://adfs.litware369.com/adfs/services/trust/mex

  • You can alternatively navigate to the AD FS sign-in page, for example in our configuration:

https://adfs.litware369.com/adfs/ls/idpinitiatedsignon.htm

This displays the AD FS sign-in page where you can sign in with the domain credentials.

Click Sign in to verify that the user is successfully and seamlessly authenticated thanks to the Windows Integrated Authentication. You shouldn't see any Windows Security dialog if AD FS has been properly configured.

Issuing a SSL/TLS certificate

The default web site will require a SSL server certificate. The certificate MUST have the following attributes:

  • Subject Name (CN): www.litware369.com
  • Subject Alternative Name (DNS): adfs.litware369.com
  • Subject Alternative Name (DNS): adrms.litware369.com
  • Subject Alternative Name (DNS): www.litware369.com

For demonstration purpose, you can issue such a SSL certificate with the test lab certification authority litware369-ADFS1-CA as illustrated hereafter.

You can instead use a SSL certificate issued from a public certification authority is required. The exact method depends on the chosen public certification authority. Please refer to their instructions.

With the exception of the SSL certificate import into the Local Computer\My Store on the EDGE1 computer, the rest of the suggested configuration doesn't differ from the one illustrated in this document.

To issue the SSL certificate with the test lab certification authority, proceed with the following steps:

  1. Close the current remote desktop connection and open a new one on the EDGE1 computer as LITWARE369\AzureAdmin with "pass@word1" as password.
  2. Open an elevated Windows PowerShell command prompt, and run the following command:

PS C:\users\AzureAdmin.LITWARE369> Get-Certificate -Template SSLCertificates -SubjectName CN=www.litware369.comDnsName adfs.litware369.com, adrms.litware369.com, www.litware369.com -CertStoreLocation cert:\LocalMachine\My

Status Certificate Request
------ ----------- -------
Issued [Subject]…

PS C:\users\AzureAdmin.LITWARE369>

Note     If you haven't previously configured a new certificate template (e.g. the SSL certificates in our configuration), you can use the WebServer certificate template in lieu of in the above command.

Configuring HTTPS on the default web site

To configure HTTPS on the default web site, proceed with the following steps:

  • Open an elevated Windows PowerShell command prompt if none, and run the following command to add a SSL binding to the default web Site:

PS C:\users\AzureAdmin.LITWARE369> New-WebBinding -Name "Default Web Site" -IP "*" -Port 443 -Protocol https
PS C:\users\AzureAdmin.LITWARE369>

  • Run the following commands to associate the imported SSL certificate to the newly created SSL binding:

PS C:\users\AzureAdmin.LITWARE369> Get-ChildItem cert:\LocalMachine\MY | where { $_.Subject -match "CN\=www.litware369.com" } | select -First 1 | New-Item IIS:\SslBindings\0.0.0.0!443

IP Address Port Host Name Store Sites
---------- ---- --------- ----- -----
0.0.0.0 443 MY Default Web Site

PS C:\Users\AzureAdmin.LITWARE369>

Deploying the Web Application Proxy (WAP)

The Web Application Proxy (WAP) is the new proxy for AD FS in Windows Server 2012 R2.

Note    For more information, see the Microsoft TechNet article Web Application Proxy Overview as well as the section Deploying Federation Server Proxies of the Windows Server 2012 R2 AD FS Deployment Guide also available on Microsoft TechNet.

To install and configure the Web Application Proxy role service, proceed with the following steps:

  • Open an elevated Windows PowerShell command prompt if none, and run the following command:

PS C:\Users\AzureAdmin.LITWARE369> Install-WindowsFeature Web-Application-Proxy –IncludeManagementTools

Success Restart Needed Exit Code Feature Result
------- -------------- --------- --------------
True No Success {RAS Connection Manager Administration Kit...
WARNING: To finish configuring this server for the Web Application Proxy role service using Windows PowerShell, see
http://go.microsoft.com/fwlink/?LinkId=294322.

PS C:\Users\AzureAdmin.LITWARE369>

  • Run the following command to collect the credential of the LITWARE369\AzureAdmin user:

PS C:\Users\AzureAdmin.LITWARE369> $credentials = Get-Credential

cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential
PS C:\Users\AzureAdmin.LITWARE369>

When prompted, enter the following credential in the dialog below and click OK:

Username: LITWARE369\AzureAdmin

Password: pass@word1

  • Run the following commands to install and configure the Web Application Proxy (WAP):

PS C:\users\AzureAdmin.litware369> $certificateThumbprint = (Get-ChildItem cert:\LocalMachine\MY -DnsName "*adfs*" | Select-Object -First 1).Thumbprint
PS C:\users\AzureAdmin.litware369> Install-WebApplicationProxy -FederationServiceTrustCredential $credentials -CertificateThumbprint $certificateThumbprint -FederationServiceName "adfs.litware369.com"

Message Context Status
------- ------- ------
The configuration completed successf... DeploymentSucceeded Success

PS C:\Users\AzureAdmin.LITWARE369>

Note    For more information, see the Microsoft TechNet article Web Application Proxy Cmdlets in Windows PowerShell.

To verify that you can successfully authenticate against the federation server on the Internet, proceed with the following steps:

  • Open a browsing session on your local computer and navigate to the AD FS sign-in page, for example in our configuration:

https://adfs.litware369.com/adfs/ls/idpinitiatedsignon.htm

Note    If the SSL certificate used in the configuration has not been issued by a public certification authority, you will need to add the test lab certification authority Litware369-ADFS1-CA root certificate to the trusted root certification authorities of your user's store.

As before, this displays the AD FS sign-in page where you can sign in with the domain credentials.

  • Click Sign in to verify that you can successfully be authenticated.

  • Enter the following credential and the click Sign in:

    Username: LITWARE369\JanetS

    Password: pass@word1

Deploying the database server

The SQL1 computer provides a SQL Server installation on a member server within litware369.com domain that will later host the AD RMS configuration and logging databases.

This section walks you through the deployment of SQL Server 2012 on the SQL1 computer with the following steps:

  1. Opening a remote desktop connection on the target computer.
  2. Adding the LITWARE369\AzureAdmin user as a SQL login and assign it sysadmin rights.
  3. Starting the SQL Server Browser service.
  4. Adding Windows Firewall exceptions for SQL Server ports.

The following subsections describe each of these steps in the context of our test lab environment.

Opening a remote desktop connection on the target computer

To open a remote desktop connection on the SQL1 computer, proceed as illustrated before with the DC1 computer but with the SQL1 computer instead. However, log on this time as SQL1\AzureAdmin with "pass@word1" as password. The local account SQL1\AzureAdmin sysadmin rights on the SQL Server instance.

Next, we will continue working on SQL1 using SQL Server Management Studio and other administrative tools to make some configuration changes to support SQL Server access before we install AD RMS later in this document. First, the LITWARE369\AzureAdmin account needs to be given sysadmin rights on the SQL Server instance in order to be able to create the AD RMS databases during AD RMS setup.

Adding the LITWARE369\AzureAdmin user as a SQL login and assign it sysadmin rights

To add the LITWARE369\AzureAdmin user as a SQL login and assign it sysadmin rights, proceed with the following steps:

  • Open a remote desktop session as per previous section.
  • Right-click the taskbar and select Task Manager.
  • In Task Manager, from the File menu, select Run new task.

  • Type in the following command to open SQL Server Management Studio and then click OK:

"C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\Ssms.exe"

  • SQL Server Management Studio launches. A Connect to Server dialog pops up.

  • Click Connect to connect to the SQL Server instance on SQL1.
    • In the console tree, expand SQL1, then expand Security, and then click Logins.
    • Right-click and select New Login. A Login – New dialog pops up.

  • For Login Name, click Search. A Select User or Group dialog pops up.

  • In Enter the object name to select, type "LITWARE369\AzureAdmin" and then click Check Names. A Windows Security dialog pops up.

  • Type "AzureAdmin" for the name of the account with "pass@word1" as password and click OK.

  • Click OK.
  • Back in Login - New, in the navigation pane, select Server Roles.

  • In Server roles, check sysadmin.
  • Click OK.
  • Close SQL Server Management Studio.

Starting the SQL Server Browser service

To start the SQL Server Browser service, proceed with the following steps:

  • While still being logged on to the SQL1 computer with the previous remote desktop session, in Task Manager, from the File menu, select Run new task, type in the following to open the Services console and then click OK:

Services.msc

  • Scroll in the list of services and select SQL Server Browser.
    • Right-click and select Properties. A SQL Server Browser Properties dialog pops up.

  • In SQL Server Browser Properties, for Startup type, select Automatic and then click Apply.
  • Click Start to start the SQL Server Browser service.
  • Click OK and then close the Services console.

Adding Windows Firewall exceptions for SQL Server ports

To add Windows Firewall exceptions for SQL Server ports, while still being logged on to the SQL1 computer with the previous remote desktop session, open an elevated Windows PowerShell command prompt if none, and run the following command:

PS C:\Users\AzureAdmin.LITWARE369> New-NetFirewallRule -DisplayName "SQL Server" -Direction Inbound –Protocol TCP –LocalPort 1433-1434,5022 -Action allow

Name : {82a6cf85-72ef-4322-aa0d-50481e278878}
DisplayName : SQL Server
Description :
DisplayGroup :
Group :
Enabled : True
Profile : Any
Platform : {}
Direction : Inbound
Action : Allow
EdgeTraversalPolicy : Block
LooseSourceMapping : False
LocalOnlyMapping : False
Owner :
PrimaryStatus : OK
Status : The rule was parsed successfully from the store. (65536)
EnforcementStatus : NotApplicable
PolicyStoreSource : PersistentStore
PolicyStoreSourceType : Local

PS C:\Users\AzureAdmin.LITWARE369>

The forthcoming configuration of the AD RMS cluster can use Microsoft SQL Server 2012.

Deploying the rights management server

To deploy the AD RMS server, proceed with the following steps in order:

  1. Opening a remote desktop connection on the target computer.
  2. Issuing a SSL/TLS certificate.
  3. Configuring HTTPS on the default web site.
  4. Configuring a new AD RMS root cluster.

Important note     You must have domain administrator permissions to deploy the AD RMS role.

  1. Testing the rights management server.

The following subsections describe each of these steps in the context of our test lab environment. Unless noticed otherwise, all these steps are executed on the ADRMS1 computer.

Opening a remote desktop connection on the target computer

To open a remote desktop connection on the ADRMS1 computer, proceed as illustrated before with the DC1 computer but with the ADRMS1 computer instead. As previously illustrated, log on as LITWARE369\AzureAdmin with "pass@word1" as password since ADRMS1 is a domain-joined computer.

Issuing a SSL/TLS certificate

The AD RMS role service will require a Secure Socket Layer (SSL) server certificate. The certificate MUST have the following attributes:

  • Subject Name (CN): adrms.litware369.com
  • Subject Alternative Name (DNS): adrms.litware369.com

To issue the SSL certificate, proceed with the following steps:

  1. Open a remote desktop session if needed as LITWARE369\AzureAdmin.
  2. Open an elevated Windows PowerShell command prompt, and run the following command:

PS C:\users\AzureAdmin.LITWARE369> Get-Certificate -Template SSLCertificates -SubjectName CN=adrms.litware369.comDnsName adrms.litware369.com -CertStoreLocation cert:\LocalMachine\My

Status Certificate Request
------ ----------- -------
Issued [Subject]…
PS C:\users\AzureAdmin.LITWARE369>

Note     If you have not configured a new certificate template (e.g. the SSLCertificates in our configuration), you can use the WebServer certificate template in lieu of in the above command.

Configuring HTTPS on the default web site

To configure HTTPS on the default web site, proceed with the following steps:

  • Open an elevated Windows PowerShell command prompt if none, and run the following command to add a SSL binding to the default web Site:

PS C:\users\AzureAdmin.LITWARE369> New-WebBinding -Name "Default Web Site" -IP "*" -Port 443 -Protocol https
PS C:\users\AzureAdmin.LITWARE369>

  • Run the following commands to associate the imported SSL certificate to the newly created SSL binding:

PS C:\users\AzureAdmin.LITWARE369> Get-ChildItem cert:\LocalMachine\MY | where { $_.Subject -match "CN\=adrms.litware369.com" } | select -First 1 | New-Item IIS:\SslBindings\0.0.0.0!443

IP Address Port Host Name Store Sites
---------- ---- --------- ----- -----
0.0.0.0 443 MY Default Web Site

PS C:\Users\AzureAdmin.LITWARE369>

Configuring a new AD RMS root cluster

In Windows Server 2012 R2, adding the AD RMS role and deploying of a new AD RMS cluster are two separate processes. The role was added as part of the base configuration:

Install-WindowsFeature ADRMS -IncludeManagementTools
Install-WindowsFeature NET-Framework-Core

Additional configuration is now required to deploy the AD RMS server role. The AD RMS server role in Windows Server 2012 R2 is manageable by two sets of Windows PowerShell cmdlets. One set (AdRmsInstall) assists in deploying and configuring AD RMS, and the second set (AdRmsAdmin) can be later used to administer an AD RMS cluster.

To run these two set of cmdlets, you need to import these modules:

PS C:\Windows\system32> Import-Module AdRms
PS C:\Windows\system32> Import-Module AdRmsAdmin

After the modules are imported, you can manage and administer AD RMS installations and components through Windows PowerShell.

Note    For additional information, you can refer to the Microsoft TechNet articles AD RMS Cmdlets in Windows PowerShell and Using Windows PowerShell to Deploy AD RMS.

Deploying a new AD RMS root cluster

To deploy a new AD RMS root cluster, proceed with the following steps:

Note    Additional details can be found in the Microsoft TechNet article Installing an AD RMS Cluster. To provide high availability for the cluster, you must install additional cluster members. For information on this installation, see the Microsoft TechNet article Joining an Existing Cluster.

  • Open an elevated Windows PowerShell command prompt if none, and run the following command to import the AdRmsInstall set of Windows PowerShell cmdlets:

PS C:\Users\AzureAdmin.LITWARE369> Import-Module AdRms
PS C:\Users\AzureAdmin.LITWARE369>

  • Run the following command to create a Windows PowerShell drive to represent the server we are provisioning:

PS C:\Users\AzureAdmin.LITWARE369> New-PSDrive -Name RC -PSProvider ADRMSInstall -Root RootCluster

Name Used (GB) Free (GB) Provider Root CurrentLocation
---- --------- --------- -------- ---- ---------------
RC ADRmsInstall RootCluster

PS C:\Users\AzureAdmin.LITWARE369>

At this stage, we can now set properties on objects in the drive namespace RC:\ that represent required configuration settings. Setting properties on objects in the drive namespace is similar to using a wizard to specify configuration settings when installing a server role.

  • Run the following command to configure the AD RMS server to use the SQL1 server and the default instance:

PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty –Path RC:\ClusterDatabase -Name UseWindowsInternalDatabase -Value $false
PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty –Path RC:\ClusterDatabase -Name ServerName -Value "SQL1"
WARNING: Verifying the specified database information. This may take a few minutes.
PS C:\Users\AzureAdmin.LITWARE369>

  • Run the following command to set the AD RMS service account:

PS C:\Users\AzureAdmin.LITWARE369> $svcacct = Get-Credential

cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential
PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty –Path RC:\ -Name ServiceAccount -Value $svcacct
PS C:\Users\AzureAdmin.LITWARE369>

When prompted, enter the following credential in the dialog below and click OK:

Username: LITWARE369\ADRMSSVC

Password: pass@word1

  • Run the following command to securely store the cluster key password string in a variable and assign it to the AD RMS installation:

PS C:\Users\AzureAdmin.LITWARE369> $password = Read-Host -AsSecureString -Prompt "ClusterPassword:"
ClusterPassword:: **********
PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty -Path RC:\ClusterKey -Name UseCentrallyManaged -Value $true
PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty -Path RC:\ClusterKey -Name CentrallyManagedPassword -Value $password
PS C:\Users\AzureAdmin.LITWARE369>

When prompted, enter the following password: pass@word1

Note    We choose to protect the AD RMS cluster key by using this option because it simplifies the configuration and does not require additional components. However, you should normally provide the best protection for this key through hardware Cryptographic Security Provider (CSP) for a HSM.

  • Run the following command to set the AD RMS cluster address:

PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty -Path RC:\ -Name ClusterURL -Value https://adrms.litware369.com:443
PS C:\Users\AzureAdmin.LITWARE369>

Note    As a security best practice, the AD RMS cluster should be provisioned by using an SSL/TLS-encrypted connection. You should be using a certificate provided by a third-party public certification authority (CA) so that it can be automatically trusted by all parties. This certificate should already be installed on the server so that you can select it as you proceed through the installation.

  • Run the following command to set the SLC name for the AD RMS installation:

PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty -Path RC:\ -Name SLCName -Value "ADRMS"
PS C:\Users\AzureAdmin.LITWARE369>

  • Run the following command to register the SCP connection point:

PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty -Path RC:\ -Name RegisterSCP -Value $true
PS C:\Users\AzureAdmin.LITWARE369>

Note    As noticed before, the service connection point (SCP) is an object in the Active Directory configuration partition that holds the Web address of the AD RMS cluster. As depicted at the beginning of this document, this object is not used by the Mobile Device Extension. The Mobile Device Extension rather relies on a DNS-based service discovery mechanism. However, since such an object is typically registered in AD RMS deployment, we will do the same here.

Only one SCP can exist in your Active Directory forest. If you try to install an AD RMS cluster and an SCP already exists in your forest from a previous AD RMS installation (attempt) that was not properly de-provisioned, the new SCP will not install properly. It must be removed before you can establish the new SCP. You can remove an SCP by using the ADScpRegister.exe tool included in the Rights Management Services Administration Toolkit with SP2 available for download on the Microsoft Download Center.

  • Run the following command to install the AD RMS root cluster using the settings provided in the Windows PowerShell drive:

PS C:\Users\AzureAdmin.LITWARE369> Install-ADRMS –Path RC:\
This will install and configure AD RMS on this computer. Do you want to continue?
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): Y
WARNING: Before you can administer AD RMS on this server, you must log off and log on again.
WARNING: Please configure SSL certificates on IIS before using AD RMS Server.
PS C:\Users\AzureAdmin.LITWARE369>

When prompted to confirm the installation and the configuration of AD RMS on the computer, type "Y" and press ENTER.

In addition to installing the AD RMS server role and provisioning the server, this cmdlet also installs if necessary any other features required by AD RMS like Message Queuing to end the logs to the database server.

  • Restart the ADRMS1 computer.
Finalizing the configuration of the new AD RMS root cluster

To finalize the configuration of the newly installed AD RMS root cluster and fulfill the prerequisites of the Mobile Device Extension, proceed with the following steps:

Note    Additional details can be found in the Microsoft TechNet articles Using Windows PowerShell to Administer AD RMS and Configuring AD RMS Cluster Properties.

  • Open a remote desktop session if needed as LITWARE369\AzureAdmin.
  • Open an elevated Windows PowerShell command prompt, and run the following command to import this time the AdRmsAdmin set of Windows PowerShell cmdlets:

PS C:\Users\AzureAdmin.LITWARE369> Import-Module AdRmsAdmin
PS C:\Users\AzureAdmin.LITWARE369>

  • Run the following command to create a Windows PowerShell drive that represents the newly installed cluster hosted by the local computer ADRMS1:


PS C:\Users\AzureAdmin.LITWARE369> New-PSDrive -Name AdrmsCluster -PsProvider AdRmsAdmin -Root https://localhost

Security Alert
Information you exchange with this site cannot be viewed or changed by others. However, there are the following
problems with the site's security certificate:
The name of the security certificate is not valid or does not match the name of the site.
Do you want to continue?
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): Y

Name Used (GB) Free (GB) Provider Root CurrentLocation
---- --------- --------- -------- ---- ---------------
AdrmsCl... AdRmsAdmin AdrmsCluster:\

PS C:\Users\AzureAdmin.LITWARE369>

When prompted to confirm, type "Y" and press ENTER.

At this stage, we can now set properties on objects in the drive namespace AdrmsCluster:\ that represent the configuration settings.

  • Run the following command to add an Extranet Cluster URL:

PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty -Path AdrmsCluster:\ -Name ExtranetLicensingURL -Value https://adrms.litware369.com:443/_wmcs/licensing
PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty -Path AdrmsCluster:\ -Name ExtranetCertificationURL -Value https://adrms.litware369.com:443/_wmcs/certification
PS C:\Users\AzureAdmin.LITWARE369>

  • Close the Windows PowerShell command prompt.

The AD RMS root cluster is now installed and configured.

Once having completed logging in again, we can further manage AD RMS using the Active Directory Rights Management Services console.

To open the Active Directory Rights Management Services console, in Server Manager, click Local Server in the console tree, then click Tools, and then click Active Directory Rights Management Services. The console opens up.

From the console, you can configure trust policies, configure exclusion policies, and create rights policy templates.

The base configuration is now complete with all the dependencies in place for the Mobile Device Extension.

To avoid spending your credit when you don't work on the test lab, you can shut down the 5 VMs (DC1, ADFS1, SQL1, ADRMS1, and EDGE1) when you don't work on the test lab.

To shut down the VMs of the test lab environment, proceed with the following steps:

  1. From within the Azure management portal, select VIRTUAL MACHINES on the left pane.
  2. Under VIRTUAL MACHINE INSTANCES, select edge1 and then click SHUTDOWN at the tray of the bottom.
  3. Repeat step 2 with adrms1, adfs1, sql1, and then dc1.

  1. Click YES. Once all the allocated resources will be deallocated, the status of the VMs will then change to Stopped (Deallocated).

To resume working on the test lab, you will then need to start in order the DC1 computer, then the ADFS1 computer, the SQL1 computer, the ADRMS1 computer, and finally EDGE1.

To start the VMs of the test lab environment, proceed with the following steps:

  1. From within the Azure management portal, select VIRTUAL MACHINES on the left pane.
  2. Under VIRTUAL MACHINE INSTANCES, select dc1 and then click START at the tray of the bottom.
  3. Click dc1, and then select DASHBOARD.

  1. Verify under quick glance that the INTERNAL IP ADDRESS is set to 10.0.2.4 in our configuration.
  2. Select adfs1 on the left and then click START at the tray of the bottom.
  3. Repeat step 5 in order with sql1, adrms1, and edge1.

You are now in a position to install and configure the Mobile Device Extension for AD RMS on your "on-premises" test lab environment.

Testing and evaluating the Mobile Device Extension for AD RMS

This walkthrough provides instructions for configuring the Mobile Device Extension for AD RMS in a Windows Server 2012 (R2) based environment. It is based on the "on-premises" test lab environment deployed in Azure as per previous sections. This environment satisfies all the prerequisites for the Mobile Device Extension.

Note    For the purpose of this document, it leverages the Microsoft TechNet article Active Directory Rights Management Services Mobile Device Extension.

It consists in the following three steps that must be followed in order:

  1. Configuring AD FS for the Mobile Device Extension for AD RMS.
  2. Specifying the DNS SRV records for the Mobile Device Extension for AD RMS.
  3. Deploying the Mobile Device Extension for AD RMS.

The following subsections describe in the context of our test lab environment each of these steps.

Configuring AD FS for the Mobile Device Extension for AD RMS

Automatically configuring AD FS for the Mobile Device Extension

The configuration of AD FS for the Mobile Device Extension for AD RMS consists in creating a relying party trust for the Mobile Device Extension along with:

  • An issuance transform rule that sources from AD DS and passes through the following claims for the authenticated user:
    • Primary email address (http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress)
    • User principal name (UPN) (http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn)
    • Proxy email addresses if present (http://schemas.xmlsoap.org/claims/ProxyAddresses)
  • An authorization rule that permits the issuance of the above claims for all users.

To automatically configure AD FS in accordance, proceed with the following steps:

  • Open a remote desktop connection on the ADFS1 computer as LITWARE369\AzureAdmin with "pass@word1" as password.
  • Download on the Desktop the script Add-AdfsRelyingPartyTrust4TestLabEnvironment.ps1 and unblock it so that it can comply with the above execution policy and be executed in your environment.

Note     The content of the script Add-AdfsRelyingPartyTrust4TestLabEnvironment.ps1 is the copy of the content provided in the Microsoft TechNet article Active Directory Rights Management Services Mobile Device Extension.

# This Script Configures the Microsoft Rights Management Mobile Device Extension and Claims used in the ADFS Server

# Check if Microsoft Rights Management Mobile Device Extension is configured on the Server
$CheckifConfigured = Get-AdfsRelyingPartyTrust -Identifier "api.rms.rest.com"
if ($CheckifConfigured)
{
Write-Host "api.rms.rest.com Identifer used for Microsoft Rights Management Mobile Device Extension is already configured on this Server"
Write-Host $CheckifConfigured
}
Else
{
Write-Host "Configuring Microsoft Rights Management Mobile Device Extension "

# TransformaRules used by Microsoft Rights Management Mobile Device Extension
# Claims: Email, UPN and ProxyAddresses
$TransformRules = @"
@RuleTemplate = "LdapClaims"
@RuleName = "Jwt Token"
c:[Type ==
"http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname",
Issuer == "AD AUTHORITY"]
=> issue(store = "Active Directory", types =
("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn",
"http://schemas.xmlsoap.org/claims/ProxyAddresses"), query =
";mail,userPrincipalName,proxyAddresses;{0}", param = c.Value);

@RuleTemplate = "PassThroughClaims"
@RuleName = "JWT pass through"
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]
=> issue(claim = c);

@RuleTemplate = "PassThroughClaims"
@RuleName = "JWT pass through"
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"]
=> issue(claim = c);

@RuleTemplate = "PassThroughClaims"
@RuleName = "JWT pass through Proxy addresses"
c:[Type == "http://schemas.xmlsoap.org/claims/ProxyAddresses"]
=> issue(claim = c);
"@

# AuthorizationRules used by Microsoft Rights Management Mobile Device Extension
# Allow All users
$AuthorizationRules = @"
@RuleTemplate = "AllowAllAuthzRule"
=> issue(Type = "http://schemas.microsoft.com/authorization/claims/permit",
Value = "true");
"@

# Add a Relying Part Truest with Name -"Microsoft Rights Management Mobile Device Extension" Identifier "api.rms.rest.com"
Add-ADFSRelyingPartyTrust -Name "Microsoft Rights Management Mobile Device Extension" -Identifier "api.rms.rest.com" -IssuanceTransformRules $TransformRules -IssuanceAuthorizationRules $AuthorizationRules

Write-Host "Microsoft Rights Management Mobile Device Extension Configured"
}

  • Open a Windows PowerShell command prompt and run the following command to create the relying party trust named api.rms.rest.com:

PS C:\Users\AzureAdmin.LITWARE369> cd .\Desktop
PS C:\Users\AzureAdmin.LITWARE369\Desktop> .\Add-AdfsRelyingPartyTrust4TestLabEnvironment.ps1
Configuring Microsoft Rights Management Mobile Device Extension
Microsoft Rights Management Mobile Device Extension Configured
PS C:\Users\AzureAdmin.LITWARE369

Authorizing the RMS sharing app for your devices

To authorizing the RMS sharing app for your devices, proceed with the following steps:

  • Open a remote desktop session if needed as LITWARE369\AzureAdmin.
  • From the previous Windows PowerShell command prompt, run the following command(s):

    For Android devices:

PS C:\users\AzureAdmin.litware369\Desktop> Add-AdfsClient -Name "RMS Sharing App for Android" -ClientId "ECAD3080-3AE9-4782-B763-2DF1B1373B3A" -RedirectUri @("com.microsoft.rms-sharing-for-android://authorize")
PS C:\users\AzureAdmin.litware369\Desktop>

For iPhone and iPad devices:

PS C:\users\AzureAdmin.litware369\Desktop> Add-AdfsClient -Name "RMS Sharing App for iOS" -ClientId "9D7590FB-9536-4D87-B5AA-FAA863DCC3AB" -RedirectUri @("com.microsoft.rms-sharing-for-ios://authorize")
PS C:\users\AzureAdmin.litware369\Desktop>

For Mac devices:

PS C:\users\AzureAdmin.litware369\Desktop> Add-AdfsClient -Name "RMS Sharing App for OSX" -ClientId "96731E97-2204-4D74-BEA5-75DCA53566C3" -RedirectUri @("com.microsoft.rms-sharing-for-osx://authorize")
PS C:\users\AzureAdmin.litware369\Desktop>

For Windows Phone devices:

PS C:\users\AzureAdmin.litware369\Desktop> Add-AdfsClient -Name "RMS Sharing App for WindowsPhone" -ClientId "6507DFAF-F19E-47C6-82C3-08AFEE79D74E" -RedirectUri @("com.microsoft.rms-sharing-for-wp://authorize")
PS C:\users\AzureAdmin.litware369\Desktop>

For Windows RT devices:

PS C:\users\AzureAdmin.litware369\Desktop> Add-AdfsClient -Name "RMS Sharing App for Windows RT" -ClientId "D27EA168-C4FE-41E7-8876-B47FF6376003" -RedirectUri @("com.microsoft.rms-sharing-for-WinRT://authorize")
PS C:\users\AzureAdmin.litware369\Desktop>

Note    In order to allow access from OAuth 2.0 clients to REST resources secured by AD FS, the app have to be pre-registered with AD FS by using the cmdlet Add-AdfsClient. AD FS will not allow access to a REST resource to clients that specify a client identifier or redirection URI that are not registered with AD FS. For additional information, see the Microsoft MDSN article Developing Modern Applications using OAuth and Active Directory Federation Services. 

Specifying the service discovery records for the Mobile Device Extension for AD RMS

As covered at the beginning of this document, we must create one or more DNS SRV records in the organization's domain or domains:

  • One record for each email domain suffix that users will use, for example litware369.com in our configuration the test lab environment.
  • One record for every FQDN used by the AD RMS clusters in place to protect content.

As far as the former is concerned, since our fictitious organization litware369.com has only users with the email addresses <user alias>@litware369.com, for example janets@litware369.com and roberth@litware369.com) for the two users created before, only one DNS SRV record with the following value is required:

_rmsdisco._http._tcp.adrms.litware369.com 443 adrms.litware369.com

The following table can be used as a guide for the SRV record properties:

Field

Value

Domain

_tcp.litware369.com

Service

_rmsdisco

Protocol

_http

Priority

0

Weight

0

Port number

443

Host offering this service

adrms.litware369.com

As far as the latter is concerned, in the chosen test topology for our test lab, i.e. a single cluster in a single forest, only one DNS SRV record must be created for the AD RMS cluster adrms.litware369.com, pointing to the same cluster. This record has the following value:

_rmsdisco._http._tcp.adrms.litware369.com 443 adrms.litware369.com

The following table can be used as a guide for the SRV record properties:

Field

Value

Domain

_tcp.adrms.litware369.com

Service

_rmsdisco

Protocol

_http

Priority

0

Weight

0

Port number

443

Host offering this service

adrms.litware369.com

Creating the service discovery records in the public registrar

For illustration purposes, we use the Go Daddy registrar in our Azure-based test lab environment.

To add the above service discovery records, proceed with the following steps:

  1. Open a browsing session with the browser of your choice from your local machine and navigate to http://www.godaddy.com/ and click Sign In. in the upper right corner. A Sign in dialog appears.

  1. Enter your credentials and click Sign In. Once authenticated, The My Account page (https://mya.goddady.com) opens up.

  1. On the Products tab, at the end of the DOMAINS row, click Launch.
  2. On the Domains page, find the domain name in which the service discovery records should be added, in our case litware369.com.
  3. Click the domain name, in our case LITWARE369.COM. The Domain Details page opens in a new tab in your browser.

  1. Click DNS Zone File in the toolbar.

  1. Click Add Record. An Add Zone Record dialog opens up.

  1. Click the down arrow for the Record type: box and select SRV (Services). The Add DNS Record dialog displays the related fields.

  1. To add the first service discovery record _rmsdisco._http._tcp.litware369.com 443 adrms.litware369.com:
  • For Name, type "_tcp.litware369.com" for the domain for which the record is valid.
  • For Target, type "adrms.litware369.com" for the host offering this service.
  • For Protocol, type "_http".
  • For Service, type "_rmsdisco".
  • For Priority, type "0".
  • For Weight, type "0".
  • For Port, type "443".
  • For TTL:, leave the value set to 1 Hour.
  1. Click Add Another.
  2. Repeat step 9 for the second discovery record _rmsdisco._http._tcp.adrms.litware369.com 443 adrms.litware369.com.
  3. Click Finish.

  1. Click Save Changes to save your two new SRV records
  2. Scroll down to the SRV (Service). You should see the two newly added SRV records.

  1. Click OK.

To check the above DNS for SRV entries for our domain, open a Windows PowerShell command prompt and run the following command:

PS C:\Users\AzureAdmin.LITWARE369> nslookup -type=SRV litware369.com 209.244.0.3
Server: resolver1.level3.net
Address: 209.244.0.3

litware369.com
primary name server = ns09.domaincontrol.com
responsible mail addr = dns.jomax.net
serial = 2014073101
refresh = 28800 (8 hours)
retry = 7200 (2 hours)
expire = 604800 (7 days)
default TTL = 600 (10 mins)
PS C:\Users\AzureAdmin.LITWARE369>

Note    You can specify one of the name server of your DNS zone instead of the external DNS server used above (209.244.0.3). In our illustration with GoDaddy.com, see the article Finding Your Hosting Account's Name servers to determine the name servers. For our litware369.com zone, the name servers are ns09.domaincontrol.com (216.69.185.5) and ns10.domaincontrol.com (208.109.255.5).

If you see the SRV entry, you can continue with the deployment of the Mobile Device Extension. The Azure-based test lab environment uses a split brain DNS configuration. Thus, the above records enables a correct resolution whatever network the device is connected to.

For organization that do not use such a DNS configuration, the optional next section illustrates how to locally declare these records.

Creating the service discovery records in the local DNS

To create the discovery record on the local DNS on the DC1 computer, proceed with the following steps:

  1. Open a remote desktop session as LITWARE369\AzureAdmin on the DC1 computer if needed.
  2. Open an elevated Windows PowerShell command prompt if none, and run the following command to add the first service discovery record _rmsdisco._http._tcp.litware369.com 443 adrms.litware369.com:

PS C:\users\AzureAdmin> Add-DnsServerResourceRecord -ZoneName "litware369.com" -Srv -Name "_rmsdisco._http._tcp" -DomainName "adrms.litware369.com" -Port 443 -Priority 0 -Weight 0
PS C:\users\AzureAdmin>

  1. Run the following command to add the second service discovery record _rmsdisco._http._tcp.adrms.litware369.com 443 adrms.litware369.com:

PS C:\users\AzureAdmin> Add-DnsServerResourceRecord -ZoneName "litware369.com" -Srv -Name "_rmsdisco._http._tcp.adrms" -DomainName "adrms.litware369.com" -Port 443 -Priority 0 -Weight 0
PS C:\users\AzureAdmin>

Deploying the Mobile Device Extension for AD RMS

The Mobile Device Extension for AD RMS have to be installed on all the nodes in an AD RMS cluster. In our test lab environment's configuration, all the instructions below should be done on the ADRMS1 computer.

Disabling the IE Enhanced Security Configuration (ESC)

The installation of the Mobile Device Extension implies to download a file from the Internet and should consequently be authorized.

Since the ADRMS1 computer is intended to run on a test lab environment, the IE Enhanced Security Configuration could be disabled for the course of the installation operations.

To disable the IE Enhanced Security Configuration (ESC), proceed with the following steps:

  1. Open a remote desktop connection as LITWARE369\AzureAdmin on the ADRMS1 computer if needed.
  2. Open an elevated Windows PowerShell command prompt if none, and run the following commands:

PS C:\Users\AzureAdmin.LITWARE369> $adminKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty -Path $adminKey -Name "IsInstalled" -Value 0
PS C:\Users\AzureAdmin.LITWARE369> $userKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty -Path $userKey -Name "IsInstalled" -Value 0
PS C:\Users\AzureAdmin.LITWARE369> Stop-Process -Name Explorer
PS C:\Users\AzureAdmin.LITWARE369>

Downloading the Mobile Device Extension for AD RMS

To download the Mobile Device Extension for AD RMS, proceed with the following steps:

  1. From the previous remote desktop connection, open a browsing session and navigate to http://www.microsoft.com/en-us/download/details.aspx?id=43738.
  2. Click Download.

  1. Click Save.
  2. Close the browsing session.

Installing the Mobile Device Extension for AD RMS

To install the Mobile Device Extension for AD RMS, proceed with the following steps:

  1. From the previous remote desktop connection, open a command prompt, navigate to the location of the .exe file, and run the following command to start the setup:

PS C:\Users\AzureAdmin.LITWARE369> cd Downloads
PS C:\Users\AzureAdmin.LITWARE369\Downloads> .\ADRMS.MobileDeviceExtension.exe

The Active Directory Rights Management Services Mobile Device Extension Setup Wizard pops up.

  1. Click Next.

  1. Check I accept the terms in the License Agreement and click Next.

  1. Type the URL of the AD FS server that you configured previously, for example "https://adfs.litware369.com" in our illustration, and then click Next.

  1. Click Install.

  1. Click Finish to complete the wizard.

Publishing the Mobile Device Extension endpoints over the Internet

To publish the Mobile Device Extension endpoints over the Internet, proceed with the following steps:

  1. Open a remote desktop connection as LITWARE369\AzureAdmin on the EDGE1 computer if needed.
  2. Open an elevated Windows PowerShell command prompt if none, and run the following commands:

PS C:\Users\AzureAdmin.LITWARE369> $certificateThumbprint = (Get-ChildItem cert:\LocalMachine\MY -DnsName "*adrms*" | Select-Object -First 1).Thumbprint

PS C:\Users\AzureAdmin.LITWARE369> Add-WebApplicationProxyApplication -Name "Microsoft Rights Management Mobile Device Extension" -BackendServerUrl https://adrms.litware369.com/_wmcs/ -ExternalPreauthentication "PassThrough" -ExternalUrl https://adrms.litware369.com/_wmcs/ -ExternalCertificateThumbprint $certificateThumbprint

PS C:\Users\AzureAdmin.LITWARE369> Add-WebApplicationProxyApplication -Name "Microsoft Rights Management Mobile Device Extension" -BackendServerUrl https://adrms.litware369.com/my/ -ExternalPreauthentication "PassThrough" -ExternalUrl https://adrms.litware369.com/my/ -ExternalCertificateThumbprint $certificateThumbprint

Since the AD RMS server is published through WAP, in addition to publishing the /_wmcs folder to the Internet, you need to also publish the /my folder, i.e. https:// adrms.litware369.com/my.

As this point, the semi-automated guided construction of the Azure-based test lab environment is complete.

You may wish to test some content protection scenarios to ensure that the Mobile Device Extension for AD RMS along w/ all the pre-requisites are correctly configured and worked as expected.

Testing the Mobile Device Extension

The Azure-based test lab environment enables to easily test the Mobile Device Extension endpoints from any supported devices connected on the Internet thanks to the above publication of the related endpoints over the Internet.

For that purpose, you can use the release of the RMS Sharing application for Android available at https://portal.aadrm.com that is specially designed to work with the Mobile Device Extension.

If you don't have any Android device in your possession to do the testing, section § Simulating an Android device in the Appendix provides a procedure to create a virtual machine running on Hyper-V on your local Windows machine to fully emulate such an Android device with an Internet connection.

Troubleshooting the Mobile Device Extension

The section provides troubleshooting information for the Mobile Device Extension if needed your own (Azure-based) test lab environment.

Turning on logging

If you run into some specifics issues when testing of the Mobile Device Extension, you can turn on logging and then check the mobile device logs in the AD RMS database.

To turn on logging of the rights management server ADRMS1, proceed with the following steps:

  • Open a remote desktop connection on the ADRMS1 computer as LITWARE369\AzureAdmin with "pass@word1" as password.
  • Open an elevated Windows PowerShell command prompt, and run the following command to import this time the AdRmsAdmin set of Windows PowerShell cmdlets:

PS C:\Users\AzureAdmin.LITWARE369> Import-Module AdRmsAdmin
PS C:\Users\AzureAdmin.LITWARE369>

  • Run the following command to create a Windows PowerShell drive that represents the cluster hosted by the local computer:

PS C:\Users\AzureAdmin.LITWARE369> New-PSDrive -Name AdrmsCluster -PsProvider AdRmsAdmin -Root https://localhost
PS C:\Users\AzureAdmin.LITWARE369>

At this stage, we can now set properties on objects in the drive namespace AdrmsCluster:\ that represent the configuration settings.

  • Run the following command to turn on logging:

PS C:\Users\AzureAdmin.LITWARE369> Set-ItemProperty -Path AdrmsCluster:\ -Name IsLoggingEnabled -Value $true
PS C:\Users\AzureAdmin.LITWARE369>

Note    To turn off logging, you simply need to rerun the above command with a value of $false. 

  • Close the Windows PowerShell command prompt.

At this stage, any call to the Mobile Device Extension are logged in the Mobile Device Extension logs to help you in troubleshooting the issue if any, and resolve it.

If you are still stumped, please join the user group AskIPTeam on Yammer at http://www.yammer.com/AskIPTeam and search/request for troubleshooting information pertaining to the same issue you face with.

Analyzing the Mobile Device Extension logs

The Mobile Device Extension provides the following two tables to help investigate and troubleshoot client issues:

  1. The Client Debug Log (ClientDebugLog) table.
  2. The Client Performance Log (Client Performance Log) table.

The next two sections provide a description of these tables.

Understanding the Client Debug Log table

The Client Debug Log (ClientDebugLog) table in the AD RMS database contains as its name indicates the debug logs in order to investigate client issues.

The following table provides the field definitions.

Field name

Data type

Description

Example value

Id

uniqueidentifier

GUID of the trace entry. This helps in troubleshooting client issues.

201724F-270D-430E-AFD2-0BB26F896C05

UserId

nvarchar

User who made the request. Their user email address is used to identify the user.

janets@litware369.com

ClientTimeStamp

datetime

UTC Date and Time in 24H format the trace entry was written.

2014-07-08 23:19:45.000

Message

nvarchar

Free form text that contains the message for the trace entry.

getAuthInfo: authInfo:{mAuthServerUrl:https://adfs.litware369.com/adfs/oauth2/authorize}{mResource:api.rms.rest.com}{mScope:null}

ThreadId

int

Identifier that can tie the set of operations that are happening the same thread.

5021

TraceLevel

nchar

Type of the message of the trace entry. Supported types are

  • Error
  • Warning
  • Info
    • Verbose

Info

ClientCorrelationId

uniqueidentifier

GUID that is common between the RMS client and the server for a given request. This helps in troubleshooting client issues. If the trace entry is not a call to the server, this is empty.

00000000-0000-0000-0000-000000000000

ClientScenarioId

uniqueidentifier

GUID that identifies the client scenario the trace entry was written under. A client scenario cover zero or more call to the server.

6BD8AF07-AE25-41D9-AAA2-6641BFF2A1A2

CreateTime

datetime

UTC Date and Time in 24H format when the call was served. The source is the local clock on the server that served the call.

2014-07-08 23:19:48.803

FullClientInformation

nvarchar

Client side information including the device environment (platform OS and model), the RMS SDK version, the RMS-enlightened application

DevicePlatform=Android;DeviceModel=Samsung ABC;SDKVersion=4.0;AppName=SampleApp.exe;AppPublisherId=123

Understanding the Client Performance Log table

The Client Performance Log table in the AD RMS database contains as its name indicates the performance logs in order to help understand the experience that the end users are having when using their mobile device(s) with RMS-enlightened applications.

The following table provides the field definitions.

Field name

Data type

Description

Example value

Id

uniqueidentifier

GUID of the trace entry. This helps in troubleshooting client issues.

19A56FFA-7386-4C87-BEAA-2765627E2EDD

UserId

nvarchar

User who made the request. Their user email address is used to identify the user.

janets@litware369.com

ClientTimeStamp

datetime

UTC date and time in 24H format the trace entry was written.

2014-06-27 07:11:28.000

OperationName

nvarchar

Name of the operation. Operations serve two purposes. Operations can represent client scenarios, which cover zero or more calls to the server (like Consume or Protect), and they can represent a specific call to the server. In the case it represents a specific call to the server, the ClientCorrelationId field is set. In the case it represents a client scenario, the ClientCorrelationId is empty (See below). In both cases, the ClientScenarioId field is set.

GetServiceDiscoveryURLs

Latency

bigint

Time it took to complete the operation in milliseconds.

142

ClientCorrelationId

uniqueidentifier

GUID that is common between RMS client and server for a given call. This helps in troubleshooting client issues. If the trace entry is not a call to the server, this is empty.

B079C03D-FD9A-4CE3-BA16-4C8745491854

ClientScenarioId

uniqueidentifier

GUID that identifies the client scenario the trace entry was written under. A client scenario cover zero or more call to the server.

6BD8AF07-AE25-41D9-AAA2-6641BFF2A1A2

FullClientInformation

nvarchar

Client side information including the device environment (platform OS and model), the RMS SDK version, the RMS-enlightened application

DevicePlatform=Android;DeviceModel=Samsung ABC;SDKVersion=4.0;AppName=SampleApp.exe;AppPublisherId=123

NetworkType

nvarchar

Placeholder for future network information for the RMS client. This is empty.

 

CreateTime

Datetime

UTC Date and Time in 24H format when the call was served. The source is the local clock on the server that served the call.

2014-06-27 07:11:18.280

This concludes the guided tour of the Mobile Device Extension for AD RMS.

Appendix

This appendix describes how to change the default User Account Control (UAC) behavior.

Setting UAC behavior of the elevation prompt for administrators

By default, UAC is enabled in Windows Server 2012 R2. This service will prompt for permission to continue during several of the configuration tasks described in this guide. In all cases, you can click Continue in the UAC dialog box to grant this permission, or you can use the following procedure to change the UAC behavior of the elevation prompt for administrators.

To set UAC behavior of the elevation prompt for administrators, proceed with the following steps:

  1. From the Start screen, type "secpol.msc", and press ENTER.
  2. In the console tree, open Local Policies, and then click Security Options.
  3. In the contents pane, double-click User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode.
  4. Select Elevate without prompting in the list, and then click OK.
  5. Close the Local Security Policy window

Simulating an Android device

To simulate an Android device, you can create a Linux virtual machine running on Hyper-V on your local machine to fully emulate an Android device thanks to the open source Android x86 project.

Note    For additional information, see the blog posts Creating an Android x86 Virtual Machine for testing Windows Intune and EMS capabilities and Installing Android-x86 on Hyper-V with Windows 8.1 in under 5 minutes.

New-TestLabEnvironment.ps1

<# 
.Synopsis 
   Setup the test lab base configuration in Azure to evaluate the Mobile Device Extension for AD RMS. 
.DESCRIPTION 
   This script enables you to setup the Azure-based test lab base configuration in Azure to evaluate the Mobile Device Extension for AD RMS along
   with AD FS in Windows Server 2012 R2. It more particularly add a VM and script it to become a domain controller for a new forest, add additional 
   member server VMs to the domain for AD FS, SQL Server and AD RMS, as well as another edge server VM by adding them to a cloud service on the 
   same VNet. A new VNet is created for the deployment, if a VNet site with the same name exists, the script does not continue. 
.EXAMPLE 
    Using all of the required parameters 
 
   .\New-TestLabEnvironment.ps1 -ServiceName "rmstest" -Location "North Europe"
 
    Using all of the parameters including the optional VNet details and VM sizes 
 
    .\New-TestLabEnvironment.ps1 -ServiceName "rmstest" -Location "North Europe" ` 
		-DC1Name "dc1" -DCVMSize "Small" -FQDNDomainName "litware369.com" -NetBIOSDomainName "LITWARE369"  `
		-ADFS1Name "adfs1" -ADFS1VMSize "Small" -SQL1Name "sql1" -SQL1VMSize "Medium" ` 
		-ADRMS1Name "adrms1" -ADRMS1VMSize "Small" -EDGE1Name "edge1" EDGE1VMSize "ExtraSmall"  ` 
		-VNetAddressPrefix "10.0.0.0/8" -Subnet1AddressPrefix "10.0.1.0/24" -Subnet2AddressPrefix "10.0.2.0/24"
#> 
Param 
( 
    # Service name to deploy to. If the service exists, the  
    # VMs will be deployed in this service, otherwise, it will be created. 
    [Parameter(Mandatory=$true)] 
    [String] $ServiceName, 
 
    # Location (i.e. target region) of the service. This is used to create the  
    # affinity group if it does not exist. If the affinity group exists, but in 
    # a different region, the cmdlet displays a warning. 
    [Parameter(Mandatory=$true)] 
    [String] $Location, 
	
    # Name of the DC1 domain controller 
    [Parameter(Mandatory=$false)] 
    [String] $DC1Name = "dc1",     
 
    # VM Size for the DC1 domain controller 
    [Parameter(Mandatory=$false)] 
    [ValidateSet("ExtraSmall","Small","Medium","Large","ExtraLarge","A6","A7")] 
    [String] $DCVMSize = "Small",     

    # FDQN Domain name for the forest 
    [Parameter(Mandatory=$false)] 
    [String] $FQDNDomainName = "litware369.com",
	
    # NetBIOS domain name for the forest 
    [Parameter(Mandatory=$false)] 
    [String] $NetBIOSDomainName = "LITWARE369", 
	
    # Computer name for the ADFS1 member server 
    [Parameter(Mandatory=$false)] 
    [String] $ADFS1Name = "adfs1", 
 
    # VM Size for the the ADFS1 member server
    [Parameter(Mandatory=$false)] 
    [ValidateSet("ExtraSmall","Small","Medium","Large","ExtraLarge","A6","A7")] 
    [String] $ADFS1VMSize = "Small",     

    # Computer name for the SQL1 member server 
    [Parameter(Mandatory=$false)] 
    [String] $SQL1Name = "sql1", 
 
    # VM Size for the the SQL1 member server
    [Parameter(Mandatory=$false)] 
    [ValidateSet("Medium","Large","ExtraLarge","A6","A7")] 
    [String] $SQL1VMSize = "Medium",  
	
    # Computer name for the ADRMS1 member server 
    [Parameter(Mandatory=$false)] 
    [String] $ADRMS1Name = "adrms1", 
 
    # VM Size for the the ADRMS1 member server
    [Parameter(Mandatory=$false)] 
    [ValidateSet("ExtraSmall","Small","Medium","Large","ExtraLarge","A6","A7")] 
    [String] $ADRMS1VMSize = "Small",  

	# Name of the edge server 
    [Parameter(Mandatory=$false)] 
    [String] $EDGE1Name = "edge1", 
 
    # VM Size for the edge server 
    [Parameter(Mandatory=$false)] 
    [ValidateSet("ExtraSmall","Small","Medium","Large","ExtraLarge","A6","A7")] 
    [String] $EDGE1VMSize = "ExtraSmall",
	
	#VNet address prefix for the VNet 
    [Parameter(Mandatory=$false)] 
    [String] $VNetAddressPrefix = "10.0.0.0/8",  
	
	# Address space for the subnet #1 (aka edge subnet) to be used for the edge server
    [Parameter(Mandatory=$false)] 
    [String] $Subnet1AddressPrefix = "10.0.1.0/24", 

	# Address space for the subnet #2 (aka internal subnet) to be used for the DC and the member server 
    [Parameter(Mandatory=$false)] 
    [String] $Subnet2AddressPrefix = "10.0.2.0/24"  	
) 
 
# The script has been tested on Windows PowerShell 3.0 
Set-StrictMode -Version 3 
 
# Following modifies the Write-Verbose behavior to turn the messages on globally for this session 
$VerbosePreference = "Continue" 
 
# Check if Azure PowerShell is available 
if ((Get-Module -ListAvailable Azure) -eq $null) 
{ 
    throw "Azure PowerShell not found! Please install from http://www.windowsazure.com/en-us/downloads/#cmd-line-tools" 
} 

<# 
.SYNOPSIS 
   Installs a Windows Remote Management (WinRm) certificate to the local store 
.DESCRIPTION 
   Gets the WinRM certificate from the Virtual Machine in the Service Name specified, and  
   installs it on the Current User's personal store.  
.EXAMPLE 
    Install-WinRmCertificate -ServiceName testservice -vmName testVm 
.INPUTS 
   None 
.OUTPUTS 
   None 
#> 
function Install-WinRmCertificate($ServiceName, $VMName) 
{ 
    $vm = Get-AzureVM -ServiceName $ServiceName -Name $VMName 
    $winRmCertificateThumbprint = $vm.VM.DefaultWinRMCertificateThumbprint 
     
    $winRmCertificate = Get-AzureCertificate -ServiceName $ServiceName -Thumbprint $winRmCertificateThumbprint -ThumbprintAlgorithm sha1 
     
    $installedCert = Get-Item Cert:\CurrentUser\My\$winRmCertificateThumbprint -ErrorAction SilentlyContinue 
     
    if ($installedCert -eq $null) 
    { 
        $certBytes = [System.Convert]::FromBase64String($winRmCertificate.Data) 
        $x509Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate 
        $x509Cert.Import($certBytes) 
         
        $store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "LocalMachine" 
        $store.Open("ReadWrite") 
        $store.Add($x509Cert) 
        $store.Close() 
    } 
} 
 
<# 
.SYNOPSIS 
    Adds a new affinity group if it does not exist. 
.DESCRIPTION 
   Looks up the current subscription's (as set by Set-AzureSubscription cmdlet) affinity groups and creates a new 
   affinity group if it does not exist. 
.EXAMPLE 
   New-AzureAffinityGroupIfNotExists -AffinityGroupName "rmstestaff" -Location "North Europe"  
#> 
function New-AzureAffinityGroupIfNotExists 
{ 
	param 
    ( 
        # Name of the affinity group 
        [String] $AffinityGroupName, 
         
        # Location where the affinity group will be pointing to 
        [String] $Location
	) 
     
    $affinityGroup = Get-AzureAffinityGroup -Name $AffinityGroupName -ErrorAction SilentlyContinue 
    if ($affinityGroup -eq $null) 
    { 
        New-AzureAffinityGroup -Name $AffinityGroupName -Location $Location -Label $AffinityGroupName `
			-ErrorVariable lastError -ErrorAction SilentlyContinue | Out-Null 
        if (!($?)) 
        { 
            throw "Cannot create the affinity group $AffinityGroupName on $Location" 
        } 
        Write-Verbose "Created affinity group $AffinityGroupName" 
    } 
    else 
    { 
        if ($affinityGroup.Location -ne $Location) 
        { 
            Write-Warning "Affinity group with name $AffinityGroupName already exists but in location $affinityGroup.Location, not in $Location" 
        } 
    } 
} 

<# 
.SYNOPSIS 
    Adds a new service if it does not exist. 
.DESCRIPTION 
   Looks up the current subscription's (as set by Set-AzureSubscription cmdlet) services and creates a new 
   storage account if it does not exist. 
.EXAMPLE 
   New-AzureServiceIfNotExists -ServiceName "mfatest" -AffinityGroup "rmstestaff"
#> 
function New-AzureServiceIfNotExists 
{ 
	param 
    ( 
        # Name of the cloud service
        [String] $ServiceName, 
         
        # Affinity group name to which the cloud service will be associated 
        [String] $AffinityGroupName
	) 
    
	$service = Get-AzureService -ServiceName $ServiceName -ErrorAction SilentlyContinue
	if ($service -eq $null) 
	{ 
		New-AzureService -ServiceName $ServiceName -AffinityGroup $AffinityGroupName  `
			-ErrorVariable lastError -ErrorAction SilentlyContinue | Out-Null 
        if (!($?)) 
        { 
            throw "Cannot create the service $ServiceName with $AffinityGroupName in $Location" 
        } 
        Write-Verbose "Created service $ServiceName" 
	}
	else
	{
        if ($service.AffinityGroup -ne $AffinityGroupName) 
        { 
            Write-Warning "Cloud service with name $ServiceName already exists but with the affinity group $service.AffinityGroup, not with $AffinityGroupName" 
        } 
	} 
}

<# 
.SYNOPSIS 
    Adds a new storage account if it does not exist. 
.DESCRIPTION 
   Looks up the current subscription's (as set by Set-AzureSubscription cmdlet) storage accounts and creates a new 
   storage account if it does not exist. 
.EXAMPLE 
   New-AzureStorageAccountIfNotExists -StorageAccountName "rmsteststor" -AffinityGroup "rmstestaff"
#> 
function New-AzureStorageAccountIfNotExists 
{ 
	param 
    ( 
        # Name of the storage account
        [String] $StorageAccountName, 
         
        # Affinity group name to which the storage account will be associated 
        [String] $AffinityGroupName
	) 
     
    $storageAccount = Get-AzureStorageAccount -StorageAccountName $StorageAccountName -ErrorAction SilentlyContinue 
    if ($storageAccount -eq $null) 
    { 
        New-AzureStorageAccount -StorageAccountName $StorageAccountName -AffinityGroup $AffinityGroupName  `
				-ErrorVariable lastError -ErrorAction SilentlyContinue | Out-Null 
        if (!($?)) 
        { 
            throw "Cannot create the storage account $StorageAccountName with $AffinityGroupName in $Location" 
        } 
        Write-Verbose "Created storage account $StorageAccountName" 
    } 
    else 
    { 
        if ($storageAccount.AffinityGroup -ne $AffinityGroupName) 
        { 
            Write-Warning "Storage account with name $StorageAccountName already exists but with the affinity group $storageAccountName.AffinityGroup, not with $AffinityGroupName" 
        } 
    } 
} 
  
<# 
.Synopsis 
   Create an empty VNet configuration file. 
.DESCRIPTION 
   Create an empty VNet configuration file. 
.EXAMPLE 
    Add-AzureVnetConfigurationFile -Path c:\temp\rmstestvnet.xml
#> 
function Add-AzureVnetConfigurationFile 
{ 
    param ([String] $Path) 
     
    $configFileContent = [Xml] "<?xml version=""1.0"" encoding=""utf-8""?> 
    <NetworkConfiguration xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration""> 
              <VirtualNetworkConfiguration> 
                <Dns /> 
                <VirtualNetworkSites/> 
              </VirtualNetworkConfiguration> 
            </NetworkConfiguration>" 
     
    $configFileContent.Save($Path) 
} 
 
<# 
.SYNOPSIS 
   Sets the provided values in the VNet file of a subscription's VNet file  
.DESCRIPTION 
   It sets the VNetName and AffinityGroup of a given subscription's VNEt configuration file. 
.EXAMPLE 
    Set-VNetFileValues -FilePath c:\temp\rmstestvnet.xml -AffinityGroupName "rmstestaff" ` 
		-VNetName "rmstestvnet" -VNetAddressPrefix "10.0.0.0/8"  ` 
		-Subnet1Name "rmstestvnet-subnet1" -Subnet1AddressPrefix "10.0.1.0/24"  `
		-Subnet2Name "rmstestvnet-subnet2" -Subnet2AddressPrefix "10.0.2.0/24"
#> 
function Set-VNetFileValues 
{ 
    param ( 
         
        # The path to the exported VNet file 
        [String] $FilePath,  
         
        # The affinity group the new VNet site will be associated with 
        [String] $AffinityGroupName,  

        # Name of the new VNet site 
        [String] $VNet,  
                  
        # Address prefix for the VNet 
        [String] $VNetAddressPrefix,  
		
		# The name of the  subnet #2 (aka internal subnet) to be added to the VNet 
        [String] $Subnet2Name,  
         
        # Address space for the subnet #2 (aka internal subnet)
        [String] $Subnet2AddressPrefix,
         
        # The name of the  subnet #1 (aka edge subnet) to be added to the VNet 
        [String] $Subnet1Name,  
         
        # Address space for the subnet #1 (aka edge subnet)
        [String] $Subnet1AddressPrefix
	) 
     
    [Xml]$xml = New-Object XML 
    $xml.Load($FilePath) 
			
    $vnetSiteNodes = $xml.GetElementsByTagName("VirtualNetworkSite") 
     
    $foundVirtualNetworkSite = $null 
    if ($vnetSiteNodes -ne $null) 
    { 
        $foundVirtualNetworkSite = $vnetSiteNodes | Where-Object { $_.name -eq $VNet } 
    } 
 
    if ($foundVirtualNetworkSite -ne $null) 
    { 
        $foundVirtualNetworkSite.AffinityGroup = $AffinityGroupName 
    } 
    else 
    { 
        $virtualNetworkSites = $xml.NetworkConfiguration.VirtualNetworkConfiguration.GetElementsByTagName("VirtualNetworkSites") 
        if ($null -ne $virtualNetworkSites) 
        { 	
            $virtualNetworkElement = $xml.CreateElement("VirtualNetworkSite", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration") 
             
            $vNetSiteNameAttribute = $xml.CreateAttribute("name") 
            $vNetSiteNameAttribute.InnerText = $VNet 
            $virtualNetworkElement.Attributes.Append($vNetSiteNameAttribute) | Out-Null 
             
            $affinityGroupAttribute = $xml.CreateAttribute("AffinityGroup") 
            $affinityGroupAttribute.InnerText = $AffinityGroupName 
            $virtualNetworkElement.Attributes.Append($affinityGroupAttribute) | Out-Null 
             
            $addressSpaceElement = $xml.CreateElement("AddressSpace", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration")             
            $addressPrefixElement = $xml.CreateElement("AddressPrefix", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration") 
            $addressPrefixElement.InnerText = $VNetAddressPrefix 
            $addressSpaceElement.AppendChild($addressPrefixElement) | Out-Null 
            $virtualNetworkElement.AppendChild($addressSpaceElement) | Out-Null 
             
            $subnetsElement = $xml.CreateElement("Subnets", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration") 
                        
            $subnet1Element = $xml.CreateElement("Subnet", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration") 
            $subnet1NameAttribute = $xml.CreateAttribute("name") 
            $subnet1NameAttribute.InnerText = $Subnet1Name 
            $subnet1Element.Attributes.Append($subnet1NameAttribute) | Out-Null 
            $subnet1AddressPrefixElement = $xml.CreateElement("AddressPrefix", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration") 
            $subnet1AddressPrefixElement.InnerText = $Subnet1AddressPrefix
            $subnet1Element.AppendChild($subnet1AddressPrefixElement) | Out-Null 
            $subnetsElement.AppendChild($subnet1Element) | Out-Null 
            
            $subnet2Element = $xml.CreateElement("Subnet", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration") 
            $subnet2NameAttribute = $xml.CreateAttribute("name") 
            $subnet2NameAttribute.InnerText = $Subnet2Name 
            $subnet2Element.Attributes.Append($subnet2NameAttribute) | Out-Null 
            $subnet2AddressPrefixElement = $xml.CreateElement("AddressPrefix", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration") 
            $subnet2AddressPrefixElement.InnerText = $Subnet2AddressPrefix
            $subnet2Element.AppendChild($subnet2AddressPrefixElement) | Out-Null 
            $subnetsElement.AppendChild($subnet2Element) | Out-Null 
			
			$virtualNetworkElement.AppendChild($subnetsElement) | Out-Null 
			
            $virtualNetworkSites.AppendChild($virtualNetworkElement) | Out-Null 
        } 
        else 
        { 
            throw "Can't find 'VirtualNetworkSite' tag" 
        } 
    } 
     
    $xml.Save($filePath) 
} 
 
<# 
.SYNOPSIS 
   Creates a Virtual Network Site if it does not exist and sets the subnet details for the Azure-based test lab environment. 
.DESCRIPTION 
   Creates the VNet site if it does not exist. It leverages the network configuration provided for the Azure-based test lab environment. 
.EXAMPLE 
   New-VNetSite -VNetName "rmstestvnet" -AffinityGroupName "rmstestaff" -VNetAddressPrefix "10.0.0.0/8" ` 
		-Subnet1Name "rmstestvnet-subnet1" -Subnet1AddressPrefix "10.0.1.0/24" `
		-Subnet2Name "rmstestvnet-subnet2" -Subnet2AddressPrefix "10.0.2.0/24"
#> 
function New-VNetSite 
{ 
    param 
    ( 
        # Name of the VNet site 
        [String] $VNetName, 
         
         # The affinity group the vNet will be associated with 
        [Parameter(Mandatory = $true)] 
        [String] $AffinityGroupName, 

		# Address prefix for the VNet	
        [String] $VNetAddressPrefix, 
		
		# The name of the  subnet #2 (aka internal subnet) to be added to the VNet 
        [String] $Subnet2Name,  
         
        # Address space for the subnet #2 (aka internal subnet)
        [String] $Subnet2AddressPrefix,

        # The name of the  subnet #1 (aka edge subnet) to be added to the VNet 
        [String] $Subnet1Name,  
         
        # Address space for the subnet #1 (aka edge subnet)
        [String] $Subnet1AddressPrefix
	)
	
    $vNetFilePath = "$env:temp\$ServiceName" + "vnet.xml" 
    Get-AzureVNetConfig -ExportToFile $vNetFilePath  -ErrorAction SilentlyContinue | Out-Null 
    if (!(Test-Path $vNetFilePath)) 
    { 
        Add-AzureVnetConfigurationFile -Path $vNetFilePath 
    } 
    
    Set-VNetFileValues -FilePath $vNetFilePath -VNet $VNetName -VNetAddressPrefix $VNetAddressPrefix -AffinityGroup $AffinityGroupName `
	       -Subnet1Name $Subnet1Name -Subnet1AddressPrefix $Subnet1AddressPrefix -Subnet2Name $Subnet2Name -Subnet2AddressPrefix $Subnet2AddressPrefix
    Set-AzureVNetConfig -ConfigurationPath $vNetFilePath -ErrorAction SilentlyContinue -ErrorVariable errorVariable | Out-Null 
    if (!($?)) 
    { 
        throw "Cannot set the vNet configuration for the subscription, please see the file $vNetFilePath. Error detail is: $errorVariable" 
    } 
    Write-Verbose "Modified and saved the VNet Configuration for the subscription" 
     
    Remove-Item $vNetFilePath 
} 
 
<# 
.SYNOPSIS 
   Modifies the virtual network configuration xml file to include a DNS service reference. 
.DESCRIPTION 
   This a small utility that programmatically modifies the vNet configuration file to add a DNS server 
   then adds the DNS server's reference to the specified VNet site. 
.EXAMPLE 
    Add-AzureDnsServerConfiguration -Name "dc" -IpAddress "10.0.2.4" -VNetName "mfatestvnet" 
#> 
function Add-AzureDnsServerConfiguration 
{ 
   param 
    ( 
        [String] $Name, 
 
        [String] $IpAddress, 
 
        [String] $VNetName 
    ) 
 
    $vNet = Get-AzureVNetSite -VNetName $VNetName -ErrorAction SilentlyContinue 
    if ($vNet -eq $null) 
    { 
        throw "VNetSite $VNetName does not exist. Cannot add DNS server reference." 
    } 
 
    $vnetFilePath = "$env:temp\$ServiceName" + "vnet.xml" 
    Get-AzureVNetConfig -ExportToFile $vnetFilePath | Out-Null 
    if (!(Test-Path $vNetFilePath)) 
    { 
        throw "Cannot retrieve the vNet configuration file." 
    } 
 
    [Xml]$xml = New-Object XML 
    $xml.Load($vnetFilePath) 
 
    $dns = $xml.NetworkConfiguration.VirtualNetworkConfiguration.Dns 
    if ($dns -eq $null) 
    { 
        $dns = $xml.CreateElement("Dns", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration") 
        $xml.NetworkConfiguration.VirtualNetworkConfiguration.AppendChild($dns) | Out-Null 
    } 
 
    # Dns node is returned as an empy element, and in Windows PowerShell 3.0 the empty elements are returned as a string with dot notation 
    # use Select-Xml instead to bring it in. 
    # When using the default namespace in Select-Xml cmdlet, an arbitrary namespace name is used (because there is no name 
    # after xmlns:) 
    $namespace = @{network="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration"} 
    $dnsNode = select-xml -xml $xml -XPath "//network:Dns" -Namespace $namespace 
    $dnsElement = $null 
 
    # In case the returning node is empty, let's create it 
    if ($dnsNode -eq $null) 
    { 
        $dnsElement = $xml.CreateElement("Dns", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration") 
        $xml.NetworkConfiguration.VirtualNetworkConfiguration.AppendChild($dnsElement) 
    } 
    else 
    { 
        $dnsElement = $dnsNode.Node 
    } 
 
    $dnsServersNode = select-xml -xml $xml -XPath "//network:DnsServers" -Namespace $namespace 
    $dnsServersElement = $null 
 
    if ($dnsServersNode -eq $null) 
    { 
        $dnsServersElement = $xml.CreateElement("DnsServers", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration") 
        $dnsElement.AppendChild($dnsServersElement) | Out-Null 
    } 
    else 
    { 
        $dnsServersElement = $dnsServersNode.Node 
    } 
 
    $dnsServersElements = $xml.GetElementsByTagName("DnsServer") 
    $dnsServerElement = $dnsServersElements | Where-Object {$_.name -eq $Name} 
    if ($dnsServerElement -ne $null) 
    { 
        $dnsServerElement.IpAddress = $IpAddress 
    } 
    else 
    { 
        $dnsServerElement = $xml.CreateElement("DnsServer", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration") 
        $nameAttribute = $xml.CreateAttribute("name") 
        $nameAttribute.InnerText = $Name 
        $dnsServerElement.Attributes.Append($nameAttribute) | Out-Null 
        $ipAddressAttribute = $xml.CreateAttribute("IPAddress") 
        $ipAddressAttribute.InnerText = $IpAddress 
        $dnsServerElement.Attributes.Append($ipAddressAttribute) | Out-Null 
        $dnsServersElement.AppendChild($dnsServerElement) | Out-Null 
    } 
 
    # Now set the DnsReference for the network site 
    $xpathQuery = "//network:VirtualNetworkSite[@name = '" + $VNetName + "']" 
    $foundVirtualNetworkSite = select-xml -xml $xml -XPath $xpathQuery -Namespace $namespace  
 
    if ($foundVirtualNetworkSite -eq $null) 
    { 
        throw "Cannot find the VNet $VNetName" 
    } 
 
    $dnsServersRefElementNode = $foundVirtualNetworkSite.Node.GetElementsByTagName("DnsServersRef") 
 
    $dnsServersRefElement = $null 
    if ($dnsServersRefElementNode.Count -eq 0) 
    { 
        $dnsServersRefElement = $xml.CreateElement("DnsServersRef", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration") 
        $foundVirtualNetworkSite.Node.AppendChild($dnsServersRefElement) | Out-Null 
    } 
    else 
    { 
        $dnsServersRefElement = $foundVirtualNetworkSite.DnsServersRef 
    } 
     
    $xpathQuery = "/DnsServerRef[@name = '" + $Name + "']" 
    $dnsServerRef = $dnsServersRefElement.SelectNodes($xpathQuery) 
    $dnsServerRefElement = $null 
 
    if($dnsServerRef.Count -eq 0) 
    { 
        $dnsServerRefElement = $xml.CreateElement("DnsServerRef", "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration")         
        $dnsServerRefNameAttribute = $xml.CreateAttribute("name") 
        $dnsServerRefElement.Attributes.Append($dnsServerRefNameAttribute) | Out-Null 
        $dnsServersRefElement.AppendChild($dnsServerRefElement) | Out-Null 
    } 
 
    if ($dnsServerRefElement -eq $null) 
    { 
        throw "No DnsServerRef element is found" 
    }     
 
    $dnsServerRefElement.name = $name 
 
    $xml.Save($vnetFilePath) 
	
	Set-AzureVNetConfig -ConfigurationPath $vNetFilePath -ErrorAction SilentlyContinue -ErrorVariable errorVariable | Out-Null 
    if (!($?)) 
    { 
        throw "Cannot set the vNet configuration for the subscription, please see the file $vNetFilePath. Error detail is: $errorVariable" 
    } 
    Write-Verbose "Modified and saved the VNet Configuration for the subscription" 
     
    Remove-Item $vNetFilePath 
}
  
<# 
.SYNOPSIS 
  Returns the latest image for a given image family name filter. 
.DESCRIPTION 
  Will return the latest image based on a filter match on the ImageFamilyName and 
  PublisedDate of the image.  The more specific the filter, the more control you have 
  over the object returned. 
.EXAMPLE 
  The following example will return the latest Windows Server 2012 R2 image. This function will 
  also only select the image from images published by Microsoft:
    Get-LatestImage -ImageFamilyNameFilter "*Windows Server 2012 R2*" -OnlyMicrosoftImages 
#> 
function Get-LatestImage 
{ 
    param 
    ( 
        # A filter for selecting the image family. 
        # For example, "Windows Server 2012 R2*", "*2012 R2 Datacenter*", "*SQL* 
        [String] $ImageFamilyNameFilter, 
 
        # A switch to indicate whether or not to select the latest image where the publisher is Microsoft. 
        # If this switch is not specified, then images from all possible publishers are considered. 
        [switch] $OnlyMicrosoftImages 
    ) 
     
    # Get a list of all available images. 
    $imageList = Get-AzureVMImage 
     
    if ($OnlyMicrosoftImages.IsPresent)
    { 
        $imageList = $imageList | 
                         Where-Object { ` 
                             ($_.PublisherName -ilike "Microsoft*" -and ` 
                              $_.ImageFamily -ilike $ImageFamilyNameFilter ) } 
    } 
    else 
    { 
        $imageList = $imageList | 
                         Where-Object { ` 
                             ($_.ImageFamily -ilike $ImageFamilyNameFilter ) }  
    } 
 
    $imageList = $imageList |  
                     Sort-Object -Unique -Descending -Property ImageFamily | 
                     Sort-Object -Descending -Property PublishedDate 
 
    $imageList | Select-Object -First(1)
} 

$serviceNameCore = $ServiceName.ToLower() 

# Create the affinity group
$affinityGroupName = ($serviceNameCore + "aff").ToLower() 
New-AzureAffinityGroupIfNotExists -AffinityGroupName $affinityGroupName -Location $Location 
 
# Create the service name
$ServiceName= ($serviceNameCore  + "svc").ToLower()
New-AzureServiceIfNotExists -ServiceName $ServiceName -AffinityGroup $affinityGroupName

# Check the VNet site, and add it to the configuration if it does not exist. 
$VNetName = ($serviceNameCore  + "vnet").ToLower()
$vNet = Get-AzureVNetSite -VNetName $VNetName  -ErrorAction Ignore  | Out-Null
if ($vNet -ne $null) 
{ 

    throw "VNet site name $VNetName is taken. Please provide a different name." 
} 
 
$subnet1Name = ($VNetName + "-subnet1").ToLower()
$subnet2Name = ($VNetName + "-subnet2").ToLower() 

New-VNetSite -VNetName $VNetName -AffinityGroupName $affinityGroupName -VNetAddressPrefix $VNetAddressPrefix `
	-Subnet1Name $subnet1Name -Subnet1AddressPrefix $Subnet1AddressPrefix `
	-Subnet2Name $subnet2Name -Subnet2AddressPrefix $Subnet2AddressPrefix
 
# Create the storage account
$storageAccountName = ($serviceNameCore + "stor").ToLower() 
New-AzureStorageAccountIfNotExists -StorageAccountName $storageAccountName.ToLower() -AffinityGroup $affinityGroupName

$subscription = Get-AzureSubscription -Current 
Set-AzureSubscription -SubscriptionName $subscription.SubscriptionName -CurrentStorageAccount $storageAccountName -ErrorAction SilentlyContinue | Out-Null 
 
# Test if there are already VMs deployed with those names 
$existingVm = Get-AzureVM  -ServiceName $ServiceName -Name $DC1Name -ErrorAction SilentlyContinue | Out-Null 
if ($existingVm -ne $null) 
{ 
    throw "A VM with name $DC1Name exists on $ServiceName" 
} 

$existingVm = Get-AzureVM  -ServiceName $ServiceName -Name $ADFS1Name -ErrorAction SilentlyContinue | Out-Null 
if ($existingVm -ne $null) 
{ 
    throw "A VM with name $ADFS1Name exists on $ServiceName" 
} 
 
$existingVm = Get-AzureVM  -ServiceName $ServiceName -Name $SQL1Name -ErrorAction SilentlyContinue | Out-Null 
if ($existingVm -ne $null) 
{ 
    throw "A VM with name $SQL1Name exists on $ServiceName" 
} 

$existingVm = Get-AzureVM  -ServiceName $ServiceName -Name $ADRMS1Name -ErrorAction SilentlyContinue | Out-Null 
if ($existingVm -ne $null) 
{ 
    throw "A VM with name $ADRMS1Name exists on $ServiceName" 
} 

$existingVm = Get-AzureVM -ServiceName $ServiceName -Name $EDGE1Name -ErrorAction SilentlyContinue | Out-Null 
if ($existingVm -ne $null) 
{ 
    throw "A VM with name $EDGE1Name exists on $ServiceName" 
} 
	
$imageFamilyNameFilter = "Windows Server 2012 R2 Datacenter" 
$image = Get-LatestImage -ImageFamilyNameFilter $imageFamilyNameFilter -OnlyMicrosoftImages 
if ($image -eq $null) 
{ 
    throw "Unable to find an image for $imageFamilyNameFilter to provision Virtual Machine." 
} 

$imageFamilyNameFilter = "SQL Server 2012 SP1 Standard on Windows Server 2012" 
$sqlimage = Get-LatestImage -ImageFamilyNameFilter $imageFamilyNameFilter -OnlyMicrosoftImages 
if ($sqlimage -eq $null) 
{ 
    throw "Unable to find an image for $imageFamilyNameFilter to provision Virtual Machine." 
} 
 
Write-Verbose "Prompt user for administrator credentials to use when provisioning the virtual machine(s)." 
$credential = Get-Credential -Message "Please provide the administrator credentials for the virtual machines" 
$username = $credential.GetNetworkCredential().username
$password = $credential.GetNetworkCredential().password

$dc1VM = New-AzureVMConfig -Name $DC1Name -InstanceSize $DCVMSize -ImageName $image.ImageName |  
                        Add-AzureProvisioningConfig -Windows -AdminUsername $username -Password $password |  
                        Set-AzureSubnet -SubnetNames $subnet2Name | 
                        Add-AzureDataDisk -CreateNew -DiskSizeInGB 20 -DiskLabel 'DITDrive' -LUN 0 
New-AzureVM -ServiceName $ServiceName -VMs $dc1VM -VNetName $VNetName -WaitForBoot | Out-Null 
 
# Set the WinRmHTTPs communication information
$dc1WinRMUri= Get-AzureWinRMUri -ServiceName $ServiceName -Name $DC1Name
 
$option = New-PSSessionOption -SkipCACheck   
 
$domainInstallScript = { 
        param ([String] $FQDNDomainName, [string] $NetBIOSDomainName, [System.Security.SecureString] $safeModePassword) 
        initialize-disk 2 -PartitionStyle MBR  
        New-Partition -DiskNumber 2 -UseMaximumSize -IsActive -DriveLetter F | Format-Volume -FileSystem NTFS -NewFileSystemLabel "AD DS Data" -Force:$true -confirm:$false 
 
        Import-Module ServerManager 
        Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools 
        Install-WindowsFeature RSAT-AD-Tools 
        Import-Module ADDSDeployment
		Install-ADDSForest `
			-CreateDNSDelegation:$false `
			-DatabasePath "F:\NTDS" `
			-DomainMode "Win2012R2" `
			-DomainName $FQDNDomainName `
			-DomainNetBiosName $NetBIOSDomainName `
			-ForestMode "Win2012R2" `
			-InstallDns:$true `
			-LogPath "F:\NTDS" `
			-NoRebootOnCompletion:$false `
			-SysvolPath "F:\SYSVOL" `
			-SafeModeAdministratorPassword $safeModePassword  `
			-Force:$true   
} 

$safeModePassword = ConvertTo-SecureString -String $password -AsPlainText -Force
Invoke-Command -ConnectionUri $dc1WinRMUri.ToString() -Credential $credential -SessionOption $option -ScriptBlock $domainInstallScript -ArgumentList @($FQDNDomainName, $NetBIOSDomainName, $safeModePassword) 
 
do 
{ 
    Start-Sleep -Seconds 30 
    $vm = Get-AzureVM -ServiceName $ServiceName -Name $DC1Name     
} 
until ($vm.InstanceStatus -eq "ReadyRole") 
 
Add-AzureDnsServerConfiguration -Name $DC1Name -IpAddress $vm.IpAddress -VNetName $VNetName 
 
if ($vm -eq $null) 
{ 
    throw "Cannot get the details of the $DC1Name VM" 
} 
 
#Install-WinRmCertificate $serviceName $DC1Name
 
$adfs1VM = New-AzureVMConfig -Name $ADFS1Name -InstanceSize $ADFS1VMSize -ImageName $image.ImageName |  
                    Add-AzureProvisioningConfig -WindowsDomain -Password $password -AdminUsername $username  `
						-JoinDomain $FQDNDomainName -Domain $NetBIOSDomainName -DomainUserName $username -DomainPassword $password  | 
                    Set-AzureSubnet -SubnetNames $subnet2Name  
New-AzureVM -ServiceName $ServiceName -VMs $adfs1VM -VNetName $VNetName -WaitForBoot  | Out-Null 
							
# Set WinRmHTTPs communication information
$adfs1WinRMUri = Get-AzureWinRMUri -ServiceName $serviceName -Name $ADFS1Name 
$option = New-PSSessionOption -SkipCACheck    

Invoke-Command -ConnectionUri $adfs1WinRMUri.ToString() -Credential $credential `
    -SessionOption $option -ScriptBlock {
	Import-Module ServerManager
	# See Installing IIS 8.5 on Windows Server 2012 R2 (http://www.iis.net/learn/install/installing-iis-85/installing-iis-85-on-windows-server-2012-r2)
	Install-WindowsFeature NET-Framework-Core, AS-HTTP-Activation, NET-Framework-45-Features, Web-Mgmt-Console, Web-Asp-Net, Web-Asp-Net45, Web-Basic-Auth,  `
		Web-Client-Auth, Web-Digest-Auth, Web-Dir-Browsing, Web-Dyn-Compression, Web-Http-Errors, Web-Http-Logging, Web-Http-Redirect,  `
		Web-Http-Tracing, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Lgcy-Mgmt-Console, Web-Metabase, Web-Mgmt-Console, Web-Mgmt-Service,  `
		Web-Net-Ext, Web-Net-Ext45, Web-Request-Monitor, Web-Server, Web-Stat-Compression, Web-Static-Content, Web-Windows-Auth, Web-WMI,  `
		Windows-Identity-Foundation
	
	Install-WindowsFeature AD-Certificate -IncludeManagementTools
	Install-AdcsCertificationAuthority -Force
	
	Configure-SMRemoting.exe -enable
    Restart-Computer -Force
}

#Install-WinRmCertificate $serviceName $ADFS1Name

$sql1VM = New-AzureVMConfig -Name $SQL1Name -InstanceSize $SQL1VMSize -ImageName $sqlimage.ImageName |  
                    Add-AzureProvisioningConfig -WindowsDomain -Password $password -AdminUsername $username  `
						-JoinDomain $FQDNDomainName -Domain $NetBIOSDomainName -DomainUserName $username -DomainPassword $password  | 
                    Set-AzureSubnet -SubnetNames $subnet2Name  
New-AzureVM -ServiceName $ServiceName -VMs $sql1VM -VNetName $VNetName -WaitForBoot  | Out-Null 
							
# Set WinRmHTTPs communication information
$sql1WinRMUri = Get-AzureWinRMUri -ServiceName $serviceName -Name $SQL1Name 
$option = New-PSSessionOption -SkipCACheck    

Invoke-Command -ConnectionUri $sql1WinRMUri.ToString() -Credential $credential `
    -SessionOption $option -ScriptBlock {
	Import-Module ServerManager
	
	# Create the firewall rule for the SQL Server access 
    # netsh advfirewall firewall add rule name= "SQLServer" dir=in action=allow protocol=TCP localport=1433 
	
	Configure-SMRemoting.exe -enable
    Restart-Computer -Force
}

#Install-WinRmCertificate $serviceName $SQL1Name

$adrms1VM = New-AzureVMConfig -Name $ADRMS1Name -InstanceSize $ADRMS1VMSize -ImageName $image.ImageName |  
                    Add-AzureProvisioningConfig -WindowsDomain -Password $password -AdminUsername $username  `
						-JoinDomain $FQDNDomainName -Domain $NetBIOSDomainName -DomainUserName $username -DomainPassword $password  | 
                    Set-AzureSubnet -SubnetNames $subnet2Name  
New-AzureVM -ServiceName $ServiceName -VMs $adrms1VM -VNetName $VNetName -WaitForBoot  | Out-Null 
							
# Set WinRmHTTPs communication information
$adrms1WinRMUri = Get-AzureWinRMUri -ServiceName $serviceName -Name $ADRMS1Name 
$option = New-PSSessionOption -SkipCACheck    

Invoke-Command -ConnectionUri $adrms1WinRMUri.ToString() -Credential $credential `
    -SessionOption $option -ScriptBlock {
	Import-Module ServerManager
	# See Installing IIS 8.5 on Windows Server 2012 R2 (http://www.iis.net/learn/install/installing-iis-85/installing-iis-85-on-windows-server-2012-r2)
	Install-WindowsFeature NET-Framework-Core, AS-HTTP-Activation, NET-Framework-45-Features, Web-Mgmt-Console, Web-Asp-Net, Web-Asp-Net45, Web-Basic-Auth,  `
		Web-Client-Auth, Web-Digest-Auth, Web-Dir-Browsing, Web-Dyn-Compression, Web-Http-Errors, Web-Http-Logging, Web-Http-Redirect,  `
		Web-Http-Tracing, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Lgcy-Mgmt-Console, Web-Metabase, Web-Mgmt-Console, Web-Mgmt-Service,  `
		Web-Net-Ext, Web-Net-Ext45, Web-Request-Monitor, Web-Server, Web-Stat-Compression, Web-Static-Content, Web-Windows-Auth, Web-WMI,  `
		Windows-Identity-Foundation
	
	Configure-SMRemoting.exe -enable
    Restart-Computer -Force
}

#Install-WinRmCertificate $serviceName $ADRMS1Name
							
$edge1VM = New-AzureVMConfig -Name $EDGE1Name -InstanceSize $EDGE1VMSize -ImageName $image.ImageName |  
                    Add-AzureProvisioningConfig -WindowsDomain -Password $password -AdminUsername $username  `
						-JoinDomain $FQDNDomainName -Domain $NetBIOSDomainName -DomainUserName $username -DomainPassword $password  | 
					Set-AzureSubnet -SubnetNames $subnet1Name   
New-AzureVM -ServiceName $ServiceName -VMs $edge1VM -VNetName $VNetName  -WaitForBoot | Out-Null
Get-AzureVM -ServiceName $ServiceName -Name $EDGE1Name |
	Add-AzureEndpoint -Name "HttpsIn" -Protocol "tcp" -PublicPort 443 -LocalPort 443 -LBSetName "MFAWebFarm" -ProbePort 80 -ProbeProtocol "http" -ProbePath "/" | 
	Update-AzureVM | Out-Null
					
# Set WinRmHTTPs communication information
$edge1WinRMUri = Get-AzureWinRMUri -ServiceName $serviceName -Name $EDGE1Name 
$option = New-PSSessionOption -SkipCACheck    

Invoke-Command -ConnectionUri $edge1WinRMUri.ToString() -Credential $credential `
    -SessionOption $option -ScriptBlock {
    #Get-WindowsFeature Web-* | Add-WindowsFeature
	Import-Module ServerManager
	# See Installing IIS 8.5 on Windows Server 2012 R2 (http://www.iis.net/learn/install/installing-iis-85/installing-iis-85-on-windows-server-2012-r2)
	Install-WindowsFeature NET-Framework-Core, AS-HTTP-Activation, NET-Framework-45-Features, Web-Mgmt-Console, Web-Asp-Net, Web-Asp-Net45, Web-Basic-Auth,  `
		Web-Client-Auth, Web-Digest-Auth, Web-Dir-Browsing, Web-Dyn-Compression, Web-Http-Errors, Web-Http-Logging, Web-Http-Redirect,  `
		Web-Http-Tracing, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Lgcy-Mgmt-Console, Web-Metabase, Web-Mgmt-Console, Web-Mgmt-Service,  `
		Web-Net-Ext, Web-Net-Ext45, Web-Request-Monitor, Web-Server, Web-Stat-Compression, Web-Static-Content, Web-Windows-Auth, Web-WMI,  `
		Windows-Identity-Foundation
			
    Configure-SMRemoting.exe -enable
    Restart-Computer -Force
}

#Install-WinRmCertificate $serviceName $EDGE1Name

Write-Verbose "Test lab setup completed." 

Remove-TestLabEnvironment.ps1

<# 
.Synopsis 
   Remove the test lab base configuration used to evaluate in Windows Azure the Mobile Device Extension for AD RMS. 
.DESCRIPTION 
   This script enables you to remove the Azure-based test lab base configuration used to evaluate in Windows Azure the Mobile Device Extension for AD RMS. 
   It more particularly remove a DC, an AD FS, a SQL Server and an AD RMS VMs, along with the storage account, the cloud service and the affinitiy group created fo the
   circumstances. 
.EXAMPLE 
    Using all of the required parameters 
 
   .\Remove-TestLabEnvironment.ps1 -ServiceName "rmstest"
 
    Using all of the parameters including the optional VNet details and VM sizes 
 
    .\Remove-TestLabEnvironment.ps1 -ServiceName "rmstest" -Location "North Europe" ` 
		-DC1Name "dc1" -ADFS1Name "adfs1" -SQL1Name "sql1" -ADRMS1Name "adrms1" -EDGE1Name "edge1"
#> 
Param 
( 
    # Service name to deploy to 
    [Parameter(Mandatory=$true)] 
    [String] $ServiceName, 

    # Name of the DC1 domain controller
    [Parameter(Mandatory=$false)] 
    [String] $DC1Name = "dc1",     
	
    # Name of the ADFS1 member server 
    [Parameter(Mandatory=$false)] 
    [String] $ADFS1Name = "adfs1", 
    
    # Name of the SQL1 member server 
    [Parameter(Mandatory=$false)] 
    [String] $SQL1Name = "sql1", 

    # Name of the ADRMS1 member server 
    [Parameter(Mandatory=$false)] 
    [String] $ADRMS1Name = "adrms1", 

	# Name of the EDGE1 standalone server 
    [Parameter(Mandatory=$false)] 
    [String] $EDGE1Name = "edge1"	
) 
 
# The script has been tested on Windows PowerShell 3.0 
Set-StrictMode -Version 3 
 
# Following modifies the Write-Verbose behavior to turn the messages on globally for this session 
$VerbosePreference = "Continue" 
 
# Check if Windows Azure PowerShell is available 
if ((Get-Module -ListAvailable Azure) -eq $null) 
{ 
    throw "Windows Azure PowerShell not found! Please install from http://www.windowsazure.com/en-us/downloads/#cmd-line-tools" 
} 
 
$storageAccountName = ($ServiceName + "stor").ToLower()
$affinityGroupName = ($ServiceName + "aff").ToLower() 
$ServiceName= ($ServiceName  + "svc").ToLower() 

# Remove the edge server
$edge1VM = Get-AzureVM -ServiceName $ServiceName -Name $EDGE1Name -ErrorAction SilentlyContinue
if ($edge1VM -ne $null) 
{ 
	if ($edge1VM.InstanceStatus -ne 'StoppedDeallocated') 
	{
		Stop-AzureVM -Name $edge1VM.Name -ServiceName $ServiceName -Force | Out-Null 
		if (!($?)) 
		{ 
			throw "Cannot shut down the virtual machine $EDGE1Name." 
		} 	
	}
	
	Remove-AzureVM -ServiceName $ServiceName  -Name $EDGE1VM.Name -DeleteVHD -ErrorAction SilentlyContinue  | Out-Null 
	if (!($?)) 
    { 
        throw "Cannot delete the virtual machine $EDGE1Name." 
    } 	
	Write-Verbose "Virtual machine $EDGE1Name is deleted." 		
} 

# Remove the ADRMS1 member server
$adrms1VM = Get-AzureVM  -ServiceName $ServiceName -Name $ADRMS1Name -ErrorAction SilentlyContinue
if ($adrms1VM -ne $null) 
{ 
    if ($adrms1VM.InstanceStatus -ne 'StoppedDeallocated') 
	{
		Stop-AzureVM -Name $adrms1VM.Name -ServiceName $ServiceName -Force | Out-Null 
		if (!($?)) 
		{ 
			throw "Cannot shut down the virtual machine $ADRMS1Name." 
		} 	
	}
	
	Remove-AzureVM -ServiceName $ServiceName  -Name $adrms1VM.Name -DeleteVHD -ErrorAction SilentlyContinue  | Out-Null 
	if (!($?)) 
    { 
        throw "Cannot delete the virtual machine $ADRMS1Name." 
    } 	
	Write-Verbose "Virtual machine $ADRMS1Name is deleted." 	
} 

# Remove the SQL1 member server
$sql1VM = Get-AzureVM  -ServiceName $ServiceName -Name $SQL1Name -ErrorAction SilentlyContinue
if ($sql1VM -ne $null) 
{ 
    if ($sql1VM.InstanceStatus -ne 'StoppedDeallocated') 
	{
		Stop-AzureVM -Name $sql1VM.Name -ServiceName $ServiceName -Force | Out-Null 
		if (!($?)) 
		{ 
			throw "Cannot shut down the virtual machine $SQL1Name." 
		} 	
	}
	
	Remove-AzureVM -ServiceName $ServiceName  -Name $sql1VM.Name -DeleteVHD -ErrorAction SilentlyContinue  | Out-Null 
	if (!($?)) 
    { 
        throw "Cannot delete the virtual machine $SQL1Name." 
    } 	
	Write-Verbose "Virtual machine $SQL1Name is deleted." 	
} 

# Remove the ADFS1 member server
$adfs1VM = Get-AzureVM  -ServiceName $ServiceName -Name $ADFS1Name -ErrorAction SilentlyContinue
if ($adfs1VM -ne $null) 
{ 
    if ($adfs1VM.InstanceStatus -ne 'StoppedDeallocated') 
	{
		Stop-AzureVM -Name $adfs1VM.Name -ServiceName $ServiceName -Force | Out-Null 
		if (!($?)) 
		{ 
			throw "Cannot shut down the virtual machine $ADFS1Name." 
		} 	
	}
	
	Remove-AzureVM -ServiceName $ServiceName  -Name $adfs1VM.Name -DeleteVHD -ErrorAction SilentlyContinue  | Out-Null 
	if (!($?)) 
    { 
        throw "Cannot delete the virtual machine $ADFS1Name." 
    } 	
	Write-Verbose "Virtual machine $ADFS1Name is deleted." 	
} 

# Remove the DC1 domain controler
$dc1VM = Get-AzureVM  -ServiceName $ServiceName -Name $DC1Name -ErrorAction SilentlyContinue
if ($dc1VM -ne $null) 
{ 
    if ($dc1VM.InstanceStatus -ne 'StoppedDeallocated') 
	{
		Stop-AzureVM -Name $dc1VM.Name -ServiceName $ServiceName -Force | Out-Null 
		if (!($?)) 
		{ 
			throw "Cannot shut down the virtual machine $DC1Name." 
		} 	
	}
	
	Remove-AzureVM -ServiceName $ServiceName -Name $dc1VM.Name -DeleteVHD -ErrorAction SilentlyContinue | Out-Null 
	if (!($?)) 
    { 
        throw "Cannot delete the virtual machine $DC1Name." 
    } 	
	Write-Verbose "Virtual machine $DC1Name is delete." 		
} 
 
# Remove the storage account
$storageAccount = Get-AzureStorageAccount -StorageAccountName $storageAccountName -ErrorAction SilentlyContinue
if ($storageAccount -ne $null) 
{  
	Remove-AzureStorageAccount -StorageAccountName $storageAccountName  | Out-Null 
	if (!($?)) 
    { 
        throw "Cannot delete the storage account $storageAccountName." 
    } 
	Write-Verbose "Storage account $storageAccountName is deleted." 	
}

# Remove the service name
$service = Get-AzureService -ServiceName $ServiceName -ErrorAction SilentlyContinue
if ($service -ne $null) 
{  
	Remove-AzureService -ServiceName $service.ServiceName -Force -ErrorAction SilentlyContinue
	if (!($?)) 
    { 
        throw "Cannot delete the cloud service $ServiceName." 
    } 
	Write-Verbose "Cloud service $ServiceName is deleted." 	
}

# Remove the VNet configuration         
Remove-AzureVNetConfig -ErrorAction Ignore | Out-Null 

# Remove the affinity group
$affinityGroup = Get-AzureAffinityGroup -Name $affinityGroupName -ErrorAction SilentlyContinue 
if ($affinityGroup -ne $null) 
{ 
	Remove-AzureAffinityGroup -Name $affinityGroup.Name -ErrorAction SilentlyContinue  | Out-Null 
	if (!($?)) 
    { 
        throw "Cannot delete the affinity group $affinityGroupName." 
    } 	
	Write-Verbose "Affinity group $affinityGroupName is deleted." 
}