Deploy SQL Server Business Intelligence in Windows Azure ...
Deploy SQL Server Business Intelligence in Windows Azure Virtual MachinesSQL Server Technical ArticleWriter: Chuck Heinzelman | Senior Program Manager | Microsoft Azure SQLCATContributors: Omer BokerTechnical Reviewers: Craig Guyer, Kay Unkroth, Lara Rubbulke, Alexei Khalyako, Mike Plumley, Yorihito Tada, Mark Perry, Buck Woody, Xin Jin, Rajinder Singh, Madhan Arumugam Ramakrishnan, Beth InghramRevision: 1.03Published: August 2013Applies to: SQL Server 2012 SP1 and Windows AzureSummary: This document describes and walks you through the creation of a multiserver deployment of SQL Server Business Intelligence features, in a Windows Azure Virtual Machines environment. The document focuses on the use of Windows PowerShell scripts for each step of the configuration and deployment process.CopyrightThis document is provided “as-is”. Information and views expressed in this document, including URL and other Internet website references, may change without notice. You bear the risk of using it. Some examples depicted herein are provided for illustration only and are fictitious.? No real association or connection is intended or should be inferred.This document does not provide you with any legal rights to any intellectual property in any Microsoft product. You may copy and use this document for your internal, reference purposes. ? 2013 Microsoft. All rights reserved.Contents TOC \o "1-3" \h \z \u 1.Contents PAGEREF _Toc364062284 \h 32.Introduction PAGEREF _Toc364062285 \h 73.What Is Infrastructure as a Service (IaaS)? PAGEREF _Toc364062286 \h 74.Why Infrastructure as a Service (IaaS)? PAGEREF _Toc364062287 \h 75.Recommended Scenarios for BI on IaaS PAGEREF _Toc364062288 \h 76.Document Conventions PAGEREF _Toc364062289 \h 87.Getting Started with IaaS PAGEREF _Toc364062290 \h 97.1.Affinity Groups PAGEREF _Toc364062291 \h 97.2.Virtual Networks PAGEREF _Toc364062292 \h 97.2.1.Subnets PAGEREF _Toc364062293 \h 97.2.2.DNS PAGEREF _Toc364062294 \h 107.2.3.On-Premises Connectivity PAGEREF _Toc364062295 \h 107.3.Storage PAGEREF _Toc364062296 \h 107.3.1.Containers PAGEREF _Toc364062297 \h 117.3.2.Access Keys PAGEREF _Toc364062298 \h 117.4.Cloud Service PAGEREF _Toc364062299 \h 117.4.1.Deployments PAGEREF _Toc364062300 \h 117.4.2.Virtual IP Address PAGEREF _Toc364062301 \h 117.5.Endpoints PAGEREF _Toc364062302 \h 127.6.Virtual Machines PAGEREF _Toc364062303 \h 127.7.Availability Sets PAGEREF _Toc364062304 \h 127.8.Disks PAGEREF _Toc364062305 \h 127.9.Images PAGEREF _Toc364062306 \h 128.Prerequisites and Assumptions PAGEREF _Toc364062307 \h 149.Windows Azure PowerShell Commands PAGEREF _Toc364062308 \h 1510.Non-Windows Azure PowerShell Commands PAGEREF _Toc364062309 \h 1711.The Overall Environment PAGEREF _Toc364062310 \h 1712.Overview of the Deployment Steps PAGEREF _Toc364062311 \h 2013.Step 1: Configure the Windows Azure Environment PAGEREF _Toc364062312 \h 2113.1.Create the Affinity Group PAGEREF _Toc364062313 \h 2113.1.1.Validation PAGEREF _Toc364062314 \h 2113.work PAGEREF _Toc364062315 \h 2213.2.1.Create the Virtual Network PAGEREF _Toc364062316 \h 2213.2.2.Validation PAGEREF _Toc364062317 \h 2413.2.3.Point-to-Site VPN PAGEREF _Toc364062318 \h 2513.3.Cloud Service PAGEREF _Toc364062319 \h 2513.3.1.Create the Cloud Service PAGEREF _Toc364062320 \h 2513.3.2.Validation PAGEREF _Toc364062321 \h 2513.4.Storage Account PAGEREF _Toc364062322 \h 2513.4.1.Create the Storage Account PAGEREF _Toc364062323 \h 2513.4.2.Validation PAGEREF _Toc364062324 \h 2614.Step2: Deploy Active Directory Domain Services PAGEREF _Toc364062325 \h 2714.1.First Domain Controller PAGEREF _Toc364062326 \h 2714.1.1.Provision VM PAGEREF _Toc364062327 \h 2814.1.2.Validation PAGEREF _Toc364062328 \h 3014.1.3.Format Disks PAGEREF _Toc364062329 \h 3114.1.4.Create Domain PAGEREF _Toc364062330 \h 3114.1.5.Create Sites and Subnets PAGEREF _Toc364062331 \h 3214.1.6.Remove Forwarder PAGEREF _Toc364062332 \h 3414.2.Second Domain Controller PAGEREF _Toc364062333 \h 3414.2.1.Provision VM PAGEREF _Toc364062334 \h 3414.2.2.Format Disks PAGEREF _Toc364062335 \h 3814.2.3.Create Domain Controller PAGEREF _Toc364062336 \h 3814.2.4.Create Share PAGEREF _Toc364062337 \h 3914.3.Service User Accounts PAGEREF _Toc364062338 \h 3914.3.1.Create Service User Accounts PAGEREF _Toc364062339 \h 4015.Step 3: Configure SQL Server Database Servers (SharePoint Back End) PAGEREF _Toc364062340 \h 4315.1.First SQL Server Instance PAGEREF _Toc364062341 \h 4415.1.1.Provision VM PAGEREF _Toc364062342 \h 4415.2.Format Disks PAGEREF _Toc364062343 \h 4615.3.Enable Clustering PAGEREF _Toc364062344 \h 4615.4.Install SQL Server PAGEREF _Toc364062345 \h 4615.5.Second SQL Server Instance PAGEREF _Toc364062346 \h 4816.Step 4: Configure SQL Server PowerPivot Servers PAGEREF _Toc364062347 \h 4916.1.First PowerPivot Server PAGEREF _Toc364062348 \h 5016.1.1.Provision VM PAGEREF _Toc364062349 \h 5016.1.2.Install SQL Server PAGEREF _Toc364062350 \h 5216.2.Second PowerPivot Server PAGEREF _Toc364062351 \h 5317.Step 5: Deploy the first SharePoint Application/Central Administration Server PAGEREF _Toc364062352 \h 5417.1.SharePoint Image PAGEREF _Toc364062353 \h 5417.1.1.Provision VM PAGEREF _Toc364062354 \h 5417.1.2.Install SharePoint Prerequisites PAGEREF _Toc364062355 \h 5617.1.3.Install SharePoint PAGEREF _Toc364062356 \h 5717.1.4.Install Add-Ins PAGEREF _Toc364062357 \h 5717.1.5.Install Updates PAGEREF _Toc364062358 \h 5817.1.6.Sysprep PAGEREF _Toc364062359 \h 5817.1.7.Capture Image PAGEREF _Toc364062360 \h 5817.2.First SharePoint Server PAGEREF _Toc364062361 \h 5917.2.1.Provision VM PAGEREF _Toc364062362 \h 5917.2.2.Create New Farm PAGEREF _Toc364062363 \h 6117.2.3.Add PowerPivot Solutions PAGEREF _Toc364062364 \h 6117.2.4.Install PowerPivot Features PAGEREF _Toc364062365 \h 6217.2.5.Configure Service Instance PAGEREF _Toc364062366 \h 6217.2.6.Create PowerPivot Service Application PAGEREF _Toc364062367 \h 6217.2.7.Create Default Web Application PAGEREF _Toc364062368 \h 6217.2.8.Deploy Web Application Solution PAGEREF _Toc364062369 \h 6317.2.9.Create Site Collection PAGEREF _Toc364062370 \h 6317.2.10.Activate PowerPivot Feature PAGEREF _Toc364062371 \h 6317.2.11.Start the Claims to Windows Token Service PAGEREF _Toc364062372 \h 6317.2.12.Configure Secure Store Service PAGEREF _Toc364062373 \h 6417.2.13.Configure Alternate Access Mappings PAGEREF _Toc364062374 \h 6517.2.14.Install Reporting Services PAGEREF _Toc364062375 \h 6617.2.15.Install Reporting Services Bits PAGEREF _Toc364062376 \h 6617.2.16.Enable Reporting Services PAGEREF _Toc364062377 \h 6717.2.17.Create Reporting Services Shared Service Application PAGEREF _Toc364062378 \h 6817.2.18.Grant Reporting Services permissions PAGEREF _Toc364062379 \h 6817.3.Section Validation PAGEREF _Toc364062380 \h 6918.Step 6: Configure AlwaysOn Availability Groups PAGEREF _Toc364062381 \h 7018.1.Create Cluster PAGEREF _Toc364062382 \h 7018.1.1.Validation PAGEREF _Toc364062383 \h 7118.2.Enable AlwaysOn Availability Groups PAGEREF _Toc364062384 \h 7118.2.1.Validation PAGEREF _Toc364062385 \h 7218.3.Create Availability Group PAGEREF _Toc364062386 \h 7218.3.1.Validation PAGEREF _Toc364062387 \h 7318.4.Enable High Availability in SharePoint PAGEREF _Toc364062388 \h 7418.4.1.Validation PAGEREF _Toc364062389 \h 7419.Step 7: Deploy SharePoint Web Front End Servers PAGEREF _Toc364062390 \h 7519.1.Provision VM PAGEREF _Toc364062391 \h 7519.1.1.Validation PAGEREF _Toc364062392 \h 7719.2.Join SharePoint Farm PAGEREF _Toc364062393 \h 7719.2.1.Validation PAGEREF _Toc364062394 \h 7719.3.Import Certificate PAGEREF _Toc364062395 \h 7819.3.1.Validation PAGEREF _Toc364062396 \h 7819.4.Deploy PowerPivot Solutions PAGEREF _Toc364062397 \h 7819.4.1.Validation PAGEREF _Toc364062398 \h 7919.5.Configure Second SharePoint Web Front End PAGEREF _Toc364062399 \h 7920.Step 8: Deploy Additional SharePoint Application/Central Administration Servers PAGEREF _Toc364062400 \h 8020.1.Provision VM PAGEREF _Toc364062401 \h 8020.1.1.Validation PAGEREF _Toc364062402 \h 8120.2.Join SharePoint Farm PAGEREF _Toc364062403 \h 8220.2.1.Validation PAGEREF _Toc364062404 \h 8220.3.Configure Local Service Instances PAGEREF _Toc364062405 \h 8220.3.1.Validation PAGEREF _Toc364062406 \h 8220.4.Start the SharePoint Services PAGEREF _Toc364062407 \h 8320.4.1.Validation PAGEREF _Toc364062408 \h 8320.5.Deploy PowerPivot Solutions PAGEREF _Toc364062409 \h 8320.5.1.Validation PAGEREF _Toc364062410 \h 8320.6.Install Reporting Services Bits PAGEREF _Toc364062411 \h 8420.6.1.Validation PAGEREF _Toc364062412 \h 8420.7.Enable Reporting Services PAGEREF _Toc364062413 \h 8420.7.1.Validation PAGEREF _Toc364062414 \h 8521.Conclusion PAGEREF _Toc364062415 \h 8621.1.For more information: PAGEREF _Toc364062416 \h 8621.2.Feedback PAGEREF _Toc364062417 \h 86IntroductionWe’ve been getting more and more requests for guidance on running Business Intelligence (BI) workloads in Windows Azure Virtual Machines. This paper is a joint effort between the Microsoft SQL Server BI portion of the Windows Azure Customer Advisory Team and Microsoft's Israel Development Center. The deployment guidance in this document is based on customer experiences, customer feedback, and user research.The environment outlined in this document works as a stand-alone environment that does not need to connect to an on-premises Active Directory domain. It emphasizes BI deployment techniques for Windows Azure Virtual Machines without going too deeply into individual BI technologies. The paper assumes that you already understand how to build BI environments in general and you now want to deploy a Microsoft SharePoint based BI environment in Windows Azure Virtual Machines. This document should serve as a starting point to build such a Windows Azure-based BI environment. Although this paper describes the use of Windows PowerShell to build the environment, most of these tasks can also be accomplished through other tools, including the Windows Azure Management Portal, SQL Server Management Studio, and SharePoint Central Administration. The Windows PowerShell approach does not require the use of multiple tools and can easily be automated and repeated as needed.What Is Infrastructure as a Service (IaaS)?IaaS is any environment that enables you to host virtual machines (VMs) without having to build and maintain the hosting infrastructure yourself. Many corporate IT departments take advantage of virtualization environments to run their workloads. IaaS eliminates the need to install or maintain host servers, enabling you to focus on your VMs rather than the infrastructure. In Windows Azure, IaaS is provided through the Windows Azure Virtual Machines service.Why Infrastructure as a Service (IaaS)?There are several reasons to run BI workloads on IaaS. Some reasons are related to the general benefits of an IaaS environment. Other reasons are derived from the combination of IaaS advantages with the characteristics of BI solutions:Seamless migration to the cloud. IaaS is the most accessible alternative for migrating BI workloads to the cloud, because IaaS is very similar to existing on-premises architectures.No physical infrastructure maintenance. Windows Azure takes care of physical infrastructure deployment and maintenance for you.IaaS solutions are flexible. Additional VMs can be created from predefined Windows Azure gallery images or from custom images. You can deploy additional servers to increase capacity dynamically.Reduced total cost of ownership (TCO). By accruing costs only for consumed resources, required software SKUs, and actual resource usage time, IaaS can help to lower TCO. This is especially significant for short-lived projects, such as demos or proof-of-concept (POC) deployments.Recommended Scenarios for BI on IaaSIaaS is a good choice for the following scenarios: Demonstrations – IaaS is a convenient option when you need to demonstrate the new Microsoft BI stack. No hardware is required, and the deployed solution is available from everywhere. Also, cost is associated only with the time during which the solution is deployed.Proof of concept (POC) – IaaS can be used for creating a POC of a BI solution. Running the POC on IaaS enables trial and error of various architectures while avoiding the high costs associated with buying hardware. After the BI solution architecture is clear, it can be decided which hardware to buy, or even continue using IaaS for the production solution. Also, the Windows Azure gallery provides some building blocks that can save some work in comparison to the on-premises alternative, for example VM images that contain Operating Systems and so on.Development/Test/Lab/Training – Development and test environments commonly require an iterative build-and-try workflow. Training environments frequently require several machines configured in a specific way for several days, and lab environments can be used for various explorations and scenario testing. For all these cases, using IaaS is convenient because it provides maximum flexibility—different environments can be created quickly, and IaaS is easy to scale as needed. Also, as in previous scenarios, cost is minimized to the actual required resources.Document ConventionsThis section describes documentation conventions used in this paper.Each implementation section starts with a description of the desired end result of that section. If you feel comfortable implementing the particular section without using the sample scripts included in the document, feel free to skip the scripted guidance and implement that section on your own. Important: The implementation sections are progressively dependent on each other; later sections build on previous sections. You cannot complete sections later in the document if the previous sections have not been completed by either the scripts provided or manually by you.Each implementation section concludes with steps and recommendations for how to verify that the steps for that section completed successfully. You should verify the results of each section before you proceed to the next section.Scripting Conventions – This document makes wide use of Windows PowerShell script fragments. If the fragment contains a single command, the text leading up to it provides information on what the script does. If the fragment contains several commands, the text leading up to it provides information on what the fragment as a whole does, and comments (Windows PowerShell comments start with #) embedded in the fragment describe what is happening in more detail.Getting Started with IaaSThis section goes over the topics and terminology specific to Windows Azure. The content in the section is not specific to BI, but if you are new to Windows Azure, it helps you understand the overall Windows Azure IaaS environment. If you are comfortable with these topics already, feel free to skip this section and move on to the architectural guidance.Note that this information is believed to be accurate at the time of the paper’s publication. The Windows Azure environment is a live service that receives updates and improvements. For the most up-to-date information about Windows Azure, see the following:Windows Azure – Machines – GroupsIn Windows Azure, an affinity group is a logical grouping of resources defined by the user. When storage and virtual machines are grouped into affinity groups, Windows Azure does all it can to locate these resources physically close together in the data center, which helps minimize latency. It is important to locate your virtual machines and the storage close together physically, because the virtual hard disks (VHDs) used by the virtual machines are stored as blobs in Windows Azure storage.Virtual Networks In Windows Azure, you can define one or more virtual networks within your subscription. A virtual network is private to you and the services that you deploy to it—VMs that are not a part of the virtual network cannot see into the virtual network. You can define a single address space or multiple address spaces within your virtual network, and you can divide those address spaces up into multiple subnets if you want—the flexibility is yours.It is worth mentioning at this point that it is important to plan your virtual network carefully before you create resources. After resources (virtual machines in this case) are deployed to a network, most of the configuration settings on that network cannot be changed. The only way to change configuration settings after deployment is to deprovision the resources from the network, make your changes, and then add the resources back to the network. This is time-consuming, and it requires downtime of your applications and services while the work is being performed. All IP addresses within Windows Azure Virtual Machines are assigned through Dynamic Host Configuration Protocol (DHCP) and remain assigned to the VM until the VM is deallocated. It is important that you do not change the IP address in your virtual machines. If you manually change the IP address, you may lose connectivity to the VM. Let Windows Azure provide the network settings for all of the machines that you deploy. For more information, see virtual network in Windows Azure supports address space divided into multiple subnets. Routing between the subnets is automatically handled through Windows Azure, so VMs in one subnet on your virtual network are automatically able to see VMs in other subnets within the same virtual network. You can add more subnets to a virtual network after machines are deployed, but you cannot change the settings of existing subnets without removing all of the deployed resources.Windows Azure uses some of the addresses in each subnet defined for its own internal purposes. Currently Windows Azure consumes three addresses from every subnet defined (which is why a /29 subnet is the smallest that you can define). When you plan your network, make sure that you take this information into account. You might need to use a larger subnet than you think to accommodate for the addresses that Windows Azure consumes.Avoid making assumptions about IP address assignments. It is common for administrators to make the assumption that the first IP address that they receive in a subnet will be the fourth possible IP address. For example, for a 10.10.10.0/29 subnet, you might assume that the first IP address handed out is 10.10.10.4. Although that assumption is currently correct, the pattern of IP address assignment can change at any time without warning. The best bet here is to refrain from making assumptions about the IP address that your VM will receive.DNSWindows Azure provides a Domain Name System (DNS) server that allows you to access the Internet from your virtual machines. You can also provide your own DNS servers on your virtual network to handle name resolution within your own network. In the example deployment that we build in this paper, two DNS servers are defined, and they provide name resolution within the virtual network.You can define the DNS servers in two places, at the virtual network level and at the Cloud Service level. DNS settings that are defined at the Cloud Service level apply to every machine deployed into that Cloud Service, regardless of what the virtual network-level settings are. DNS settings that are defined at the virtual network level apply to every machine deployed to that network, unless that machine is part of a Cloud Service that has custom DNS settings.On-Premises ConnectivityWindows Azure Virtual Networks can be set up for on-premises connectivity in two different ways —point-to-site and site-to-site. Each method has its own purpose, and both can be used in the same virtual network.Point-to-Site On-Premises ConnectivityPoint-to-site connectivity is essentially a virtual private network (VPN) connection into your virtual network. Your machine gets an IP address on the virtual network, and you can then communicate with the machines via IP address or via names resolved by a DNS server, if you have configured one. This best way to think about point-to-site connectivity is like a corporate VPN. When you are off-site, you can use VPN software provided by your employer to connect to network resources at the office. This is the same basic technology that corporate VPNs use. The communication channel between your machine and the virtual network in Windows Azure is handled through certificates that you create and load rather than user names and passwords.Site-to-Site On-Premises ConnectivitySite-to-site connectivity is different from point-to-site connectivity. Site-to-site connectivity is meant to be a permanent tunnel between your corporate environment and your virtual network in Windows Azure. If you set up site-to-site connectivity, your cloud-based virtual machines can actually be a part of your corporate domain structure.StorageWindows Azure Virtual Machines make extensive use of .vhd files, similar to what is used in on-premises Windows Server Hyper-V environment. You can have multiple distinct storage accounts within a single Windows Azure subscription, and you can spread files from VMs across multiple storage accounts. The .vhd files used by Windows Azure Virtual Machines are stored in Windows Azure Blob Storage as page blobs. This is an important distinction because there are two types of blobs in blob storage: page blobs and block blobs. For .vhd files, you use page blobs.If you have existing machines that you want to host and run in Windows Azure Virtual Machines, you can upload the .vhd files to Windows Azure Blob Storage and create a virtual machine based on them. You can also upload a .vhd that includes a sysprepped virtual machine that can be used as an image to create multiple virtual machines. You can also create new .vhd by creating a new virtual machine ‘Disk’ in the management portal (or Windows PowerShell Add-AzureDatadisk).ContainersRather than folders, blob storage uses containers to store blobs. When you are working with virtual machines, a “vhds” container is automatically created for you. Containers have three different levels of security: Private, Public Container, and Public Blob. The “vhds” container that is created when you create virtual machines is created as Private.When you work with virtual machines, you can use whatever container structure works best for you. All you need to do when creating a virtual machine is provide the full path to the .vhd file.The following diagram illustrates the Windows Azure objects that are part of the storage environment:Access KeysWindows Azure storage accounts can be accessed from various third-party tools (as well as the published API). This access is commonly done by using one of the access keys on the storage account. Each storage account has two access keys: a Primary Access Key and a Secondary Access Key. Both keys provide the same level of access. There are two keys so that if you want to perform periodic key maintenance you can change one of them while still accessing your storage through the other.Cloud ServiceThe cloud service is the heart of your cloud-based deployment. It provides a public face to your infrastructure if you want it to have one. Your level of exposure to the Internet is controlled by how much you open your cloud service.DeploymentsCloud services can have multiple deployments. For the purposes of working with Windows Azure Virtual Machines, the examples in this paper use production deployments.Virtual IP AddressEach cloud service gets a single public-facing IP address. Along with that, it gets a public DNS entry. If you name your cloud service “BIPaper”, its public DNS entry will be “BIPaper.”. This IP address (and public DNS entry) is how you connect to the resources running as part of the cloud service.EndpointsFor each virtual machine that you deploy, you can define one or more public endpoints. An endpoint is a public/private port pairing that acts as a bridge between the public virtual IP address and the private virtual machine IP address. For example, if you want inbound (public) traffic on port 53186 of the virtual IP address routed to port 3389 on a given virtual machine, you can set up an endpoint on that virtual machine with a public port of 53186 and a private port of 3389.A public port can only be used once per cloud service—unless you set the endpoints up as load-balanced endpoints. You can share a single public endpoint across multiple virtual machines by using the built-in load balancer in Windows Azure.Many people may want to use remote desktop to connect to their Windows Azure-based virtual machines. The easiest way to do this is through a point-to-site VPN, but you can still do it without a VPN. Set up an endpoint on each virtual machine that you want to access with a private port of 3389 (the standard port for RDP) and an obfuscated public port. The obfuscation of the public port provides two benefits: 1) multiple machines in the same cloud service can use the same private port without load balancing, and 2) port 3389 is a well-known port and using it as your public RDP port can open your infrastructure up for potential attacks.Virtual MachinesVirtual machines are at the core of what we are doing in this paper. In many ways, the machines that you host in Windows Azure are no different than the machines that you host in Hyper-V on-premises. There are a few things, such as snapshots, that you are unable to do with Windows Azure Virtual Machines, and you do not have direct access to the Hyper-V management tools. All management of virtual machines needs to be done either through the Windows Azure Management Portal () or through the exposed APIs.Availability SetsAvailability sets are logical groupings of virtual machines. Periodically, the host operating systems that run underneath your virtual machines need to be updated. When these updates happen, any virtual machine running on that host is taken offline. To get the promised service-level agreement (SLA) for Windows Azure Virtual Machines, you need to have at least two machines running in a given role (two domain controllers, for example). Placing those machines in the same availability set tells Windows Azure that it should make sure that one machine always remains up while host maintenance is being performed.DisksTo present a .vhd stored in blob storage to a virtual machine, verify that the .vhd has a Windows Azure Disk defined. Disks can be marked as data disks, bootable disks (which contain an operating system image), or images (which contain a sysprepped image that can be used for creating other virtual machines). In this paper, all three disk types are used.ImagesImages are templates in the world of Windows Azure Virtual Machines. There are prebuilt gallery images for a variety of technologies, including Windows Server and SQL Server. If you have a situation where you need to add machines to your deployments quickly (such as scaling out a SharePoint environment), you can create your own custom images with your software preinstalled. These images can then be used as a template for creating additional machines. One word of caution—make sure that the software you install on the image supports being sysprepped. The procedures in this document use a base Windows Server image from the Windows Azure Virtual Machines gallery. The procedures do not use gallery images that contain SQL Server. We made this choice for the following reasons:The gallery images have most of SQL Server installed and running. Many of these features are not needed for the BI scenarios covered in this document. To simplify the installation and configuration procedure, the scripts install only the SQL Server features that are needed for the BI scenarios.Leveraging the gallery images that have SQL Server already installed does not allow you to make use of your existing licenses. The procedures in this document assume you supply the installation files and necessary licenses for SQL Server and SharePoint. For more information, see the prerequisites and assumptions section of this document.Prerequisites and AssumptionsWe made several assumptions about our readers and your environments while we were writing this paper:Installation Bits – For the purpose of this paper we used the Windows Server 2012 gallery images. These images do not have any additional software installed on them. You will need to provide the installation media for SQL Server 2012 with SP1 (Enterprise or Business Intelligence edition), SharePoint Server 2013 (Enterprise) and any service packs and cumulative updates you want to apply. The paper was written using the following software:SQL Server 2012 Enterprise Core editionSQL Server 2012 ervice pack (SP) 1 and cumulative update (CU) 4SharePoint Server 2013 Enterprise editionSharePoint Server 2013 March 2013 CUSharePoint Server 2013 April 2013 CULicensing – Through the use of the Windows Server 2012 gallery images, the Windows licensing is covered on a pay-by-the-hour basis. Any licensing for the SQL Server and SharePoint components are the responsibility of the person doing the installation. For more information about Windows Azure pricing and licensing, see Azure Subscription – You will need access to a Windows Azure subscription with a sufficient number of cores allocated. The default is 20 cores per subscription. To build the entire lab outlined in this document, you need 66 cores at the recommended machine sizes. To increase the core quota, contact . Important: After you are finished developing and testing the scripts, verify that the Windows Azure resources are in the desired state so you are not charged for resources you do not need. For example, if you leave Windows Azure Virtual Machines running, you are charged compute hours. If you do not want to delete virtual machines and you do not want to incur charges while the virtual machine is unused, shut down the virtual machine(s) in the Windows Azure Management Portal. For more information about the cost of Windows Azure compute charges, see . Management Certificate – To use the scripts included in this paper, you need to create a management certificate and upload it into the Windows Azure Management Portal. For more information about how to do this, see Cloud Spelunking, Managing Azure form your Desktop via PowerShell (the Setup) ().VPN Certificate – If you plan to use the point-to-site VPN functionality to access your virtual machines, you need to create your root and client certificates. For more information about how to do this, see Configure a Point-to-Site VPN in the Management Portal ().Windows Azure PowerShell Cmdlets – If you intend to use the scripts included in this paper, you need to download and install the Windows Azure PowerShell cmdlets (the scripts in this document were created using the June 2013 cmdlets). For more information about how to download Windows Azure PowerShell, see Downloads ().Windows PowerShell Scripting – It is our assumption that people using this document will have a basic working knowledge of Windows PowerShell, including the definition and use of variables and scripts. For more information about using Windows PowerShell, see Getting Started with Windows PowerShell ().Windows PowerShell Integrated Scripting Environment (ISE) – We recommend that you use the Windows PowerShell ISE tool for running the scripts included in this document. The Windows PowerShell ISE is installed by default on Windows Server 2012.On-Box vs. Off-Box Scripts – In this paper, the terms on-box and off-box are used when in discussions of Windows PowerShell scripts. On-box scripts are Windows PowerShell scripts that should be run while you are logged into the specified virtual machine. They do not require any of the Windows Azure settings, but they do require certain variables to be created and populated. Off-box scripts are Windows PowerShell scripts that should be run from a local workstation. They require the Windows Azure settings and variables.Windows Azure PowerShell CommandsThis section describes script related document conventions and best practices regarding the Windows Azure-related PowerShell commands contained in this document. Run the following command before you run any Windows Azure PowerShell commands.Import-Module "C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure\Azure.psd1"This command ensures that the Windows Azure PowerShell cmdlets are loaded. Make sure that the path is correct for where your Azure.psd1 file is located.The following standard variable names are used throughout the document.Variable namePurpose/source$subscriptionNameThe name of your Windows Azure subscription$subscriptionIDThe unique identifier for your Windows Azure subscription (can be found in the Settings section of the Windows Azure Management Portal under Management Certificates)$thumbPrintThe thumbprint of the management certificate that you uploaded to the Windows Azure Management Portal$affinityGroupLocationThe Windows Azure data center where you will be deploying your resources$affinityGroupNameThe name of the affinity group (must be unique in your subscription)$affinityGroupDescriptionThe description for the affinity group$affinityGroupLabelThe label for the affinity group$virtualNetworkNameThe name for the virtual network (must be unique in your subscription)$cloudServiceNameThe cloud service name you want to use (must be globally unique)$cloudServiceDescriptionThe description for the cloud service$cloudServiceLabelThe label for the cloud service$storageAccountNameThe storage account name you want to use (must be globally unique)$storageAccountLabelThe label for the storage account$domainNameThe NetBIOS name of the domain being created (BIPaper, for example)$domainNameFQThe fully qualified domain name (FQDN) of the domain being created (BIPaper.local, for example)We suggest having these variables and the Import-Module command in a script file that you run with each of the off-box scripts that you run. Here is a sample script block that contains these variables, including default values for responses that are assumed in the paper.# Import PowerShell Module...Import-Module "C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure\Azure.psd1"# Variable Block...# Subscription Information...$subscriptionName = ""$subscriptionID = ""$thumbPrint = ""# Affinity Group Information...$affinityGroupLocation = "" # To see possible locations, run the command: Get-AzureLocation | FT Name, AvailableServices$affinityGroupName = "BIPaper-AffinityGroup"$affinityGroupDescription = "Affinity Group used for the BI in IaaS Paper" # Maximum of 1024 Characters...$affinityGroupLabel = "BI in IaaS Paper Affinity Group" # Maximum of 100 Characters...# Virtual Network Information...$virtualNetworkName = "BIPaper-Network"# Cloud Service Information...$cloudServiceName = ""$cloudServiceDescription = "Cloud Service used for the BI in IaaS Paper"$cloudServiceLabel = "BI in IaaS Paper Cloud Service"# Storage Account Information...$storageAccountName = "" # Must be globally unique and all lowercase...$storageAccountLabel = ""# Domain Information...$domainName = "BIPaper"$domainNameFQ = "BIPaper.local"In addition, you should set and select your subscription with each command, especially if your account is associated with more than one subscription. There are two different methods for setting your subscription, one for a subscription that contains a storage account and one for a subscription that does not have a storage account. Each script listed includes information about which method to use.Without storage account:$certificate = Get-Item cert:\currentuser\my\$thumbPrint Set-AzureSubscription ` -SubscriptionName $subscriptionName ` -SubscriptionId $subscriptionID ` -Certificate $certificateSelect-AzureSubscription ` -SubscriptionName $subscriptionName With storage account:$certificate = Get-Item cert:\currentuser\my\$thumbPrint Set-AzureSubscription ` -SubscriptionName $subscriptionName ` -SubscriptionId $subscriptionID ` -Certificate $certificate ` -CurrentStorageAccount $storageAccountNameSelect-AzureSubscription ` -SubscriptionName $subscriptionNameNon-Windows Azure PowerShell CommandsThe following is the list of standard variables that this paper uses for Windows PowerShell commands. The variables are not used for Windows Azure PowerShell.Variable namePurpose/source$domainNameFQThe fully qualified domain name (FQDN) that you want to use (BIPaper.local, for example)$domainNameThe NetBIOS name for the domain (BIPaper, for example)$dbServerThe name of the primary database server (BIPaper-DB1, for example)$dbServer2The name of the secondary database server (BIPaper-DB2, for example)$farmServiceAccountThe name of the service account to use for running the SharePoint farm (SP_Farm, for example)$reportingServiceAccountThe name of the service account to use for running SQL Server Reporting Services (SQL_Reporting, for example)$cloudServiceNameThe name used for the Windows Azure cloud service (BIPaper, for example)$clusterNameThe name used for the Windows Failover Cluster required by AlwaysOn Availability Groups (BIPaper-DB, for example)$quorumServerNameThe name of the server that hosts the Quorum share (BIPaper-DC2, for example)As with the off-box variables discussed earlier, we suggest including all of these variables and their values in a script file that can be run with each of the on-box scripts that you run. Here is a sample script block containing these variables, including default values for responses that are assumed in the paper.# Variable Block...$domainNameFQ = "BIPaper.local"$domainName = "BIPaper"$dbServer = "BIPaper-DB1"$dbServer2 = "BIPaper-DB2"$farmServiceAccount = "SP_Farm"$reportingServiceAccount = "SQL_Reporting"$cloudServiceName = "BIPaper"$clusterName = "BIPaper-DB"$quorumServerName = "BIPaper-DC2"The Overall EnvironmentIn this document, we are going to build a SharePoint-based BI environment that has high availability (HA) designed in at each level. The environment is illustrated in the following diagram. We start with the Windows Azure infrastructure, and then we proceed through building:Domain controllers (BiPaper-DC1, Bipaper-DC2)Database servers (Bipaper-DB1, Bipaper-DB2)PowerPivot servers (BiPaper-PP1, Bipaper-PP2)SharePoint farm server (BiPaper-App1).After the system is up and operational, we scale it out by adding:Two Web Front End (WFE) servers (BiPaper-WFE1, BiPaper-WFE2) behind a Windows Azure load balancer. A second SharePoint application-tier server (BiPaper-App2) for HAThe following diagram shows the complete architecture used in this paper, including IP addresses, subnets, and computer names.Overview of the Deployment StepsThe following table lists the high-level steps to deploy a full-featured BI environment in IaaS. The steps walk you through a deployment that is intended to illustrate several useful technologies and how they work together in a highly available design. You may decide in your environment to not include some technologies.#StepDescription1Configure the Windows Azure EnvironmentConfiguration of the core elements of the Windows Azure environment: affinity group, virtual networking, storage, and cloud service.2Deploy Active Directory Domain Services (AD DS)Provisioning and configuration of two domain controllers to support the environment and creation of user accounts for services.3Configure SQL Server Database ServersProvisioning and configuration of two SQL Server database servers to support highly available storage of the SharePoint databases.4Configure PowerPivot ServersProvisioning and configuration of two (or more) SQL Server Analysis Services SharePoint mode servers to support loading of PowerPivot workbooks.5Deploy the first SharePoint Application/Central Administration ServerProvisioning and configuration of the first SharePoint App-Tier server, including Central Administration, Microsoft Excel Services, Reporting Services, and PowerPivot.6Configure AlwaysOn Availability GroupsConfiguring an availability group, including all of the SharePoint databases that were created.7Deploy SharePoint Web Front End ServersProvisioning and configuration of multiple SharePoint Web Front End servers to support Internet traffic.8Deploy Additional SharePoint Application/Central Administration ServersProvisioning and configuration of additional SharePoint App-Tier servers to support scaled-out load balancing.Step 1: Configure the Windows Azure EnvironmentThe first step of the process is to configure the Windows Azure environment to make it ready for deploying our virtual machines. If you are comfortable with creating a Windows Azure infrastructure on your own without the samples, create the following infrastructure objects and skip to the section Step2: Deploy Active Directory Domain Services. Otherwise, continue reading for the step-by-step instructions.The following list describes the different elements this paper uses in the Windows Azure environment. Important: The bold names in the following list are names that are required through the remainder of this paper. If you use different names, be sure to adjust the other scripts that use these names.Affinity group – BIPaper-AffinityGroupThe affinity group that we create binds all of the infrastructure assets together. The affinity group lets Windows Azure know that these different pieces (network, virtual machine, storage, and so on) are working together and that they should be physically located near each other to reduce latency between the different parts of the work:Name – BIPaper-NetworkAffinity Group – BIPaper-AffinityGroupPoint-to-Site Address Space – 172.16.128.0/29 (this is necessary only if you are using point-to-site VPN)Address Space – 172.16.0.0/17Subnets:ADNet – 172.16.1.0/29DBNet – 172.16.2.0/24AppNet – 172.16.3.0/24WebNet – 172.16.4.0/24Gateway – 172.16.127.0/29 (this is necessary only if you are using point-to-site VPN)If you are configuring point-to-site VPN:Create GatewayUpload Root CertificateConfigure VPN ConnectionCloud Service:Name – Choose a globally unique name (for this paper, we used bipaper)Affinity Group – BIPaper-AffinityGroupStorage Account:Name – Choose a globally unique name (for this paper, we used bipapersp)Affinity Group – BIPaper-AffinityGroupCreate the Affinity GroupTo create the affinity group, run the following Windows Azure PowerShell command (use the variable/subscription block without the storage account).New-AzureAffinityGroup ` -Location $affinityGroupLocation ` -Name $affinityGroupName ` -Description $affinityGroupDescription ` -Label $affinityGroupLabelValidationThere are two ways to verify that the affinity group has been created:Portal – In the Windows Azure Management Portal (), click Settings and then click Affinity Groups to verify that it exists (you might need to refresh the page). Windows PowerShell – Run the following Windows PowerShell command (include the same variable script block used to run the command listed earlier). It should return the value True.((Get-AzureAffinityGroup | where {$_.Name -eq $affinityGroupName}) -ne $NULL)NetworkThe network that we will be creating provides subnets and address spaces for each virtual machine that we deploy. We have divided our network up as follows:Address Space – 172.16.0.0/17. This is the total possible pool of IP addresses that can be assigned in our virtual network. There are 32,763 usable addresses.Point-to-Site Address Space – 172.16.128.0/29. This is the address space allocated to the machines that connect via the point-to-site VPN feature. There are six usable addresses.Subnets: The subnets defined here are strictly for logical grouping of machines.ADNet – 172.16.1.0/29. This is the address space allocated to our Active Directory servers. There are three usable addresses.DBNet – 172.16.2.0/24. This is the address space allocated to our database servers, There are 251 usable addresses.AppNet – 172.16.3.0/24. This is the address space allocated to our app-tier servers. There are 251 usable addresses.WebNet – 172.16.4.0/24. This is the address space allocated to our web servers. There are 251 usable addresses.Gateway – 172.16.127.0/29. This is a subnet used by the internal gateway. There are three usable addresses.Create the Virtual NetworkThe way that the network is created depends on whether you have existing virtual networks defined. If your subscription has existing networks defined, you can merge the new network configuration into the existing configuration. If your subscription does not have existing networks defined, you can create the entire network from scratch. The script in step 3 automatically detects which scenario you have and acts accordingly.Here are the steps for network creation:Save the following XML block into a file named “C:\Temp\NetworkDef.xml”.<VirtualNetworkSite name="placeholder-network" AffinityGroup="placeholder-affinitygroup"> <AddressSpace> <AddressPrefix>172.16.0.0/17</AddressPrefix> </AddressSpace> <Subnets> <Subnet name="ADNet"> <AddressPrefix>172.16.1.0/29</AddressPrefix> </Subnet> <Subnet name="DBNet"> <AddressPrefix>172.16.2.0/24</AddressPrefix> </Subnet> <Subnet name="AppNet"> <AddressPrefix>172.16.3.0/24</AddressPrefix> </Subnet> <Subnet name="WebNet"> <AddressPrefix>172.16.4.0/24</AddressPrefix> </Subnet> <Subnet name="GatewaySubnet"> <AddressPrefix>172.16.127.0/29</AddressPrefix> </Subnet> </Subnets> <Gateway> <VPNClientAddressPool> <AddressPrefix>172.16.128.0/29</AddressPrefix> </VPNClientAddressPool> <ConnectionsToLocalNetwork /> </Gateway></VirtualNetworkSite>Save the following XML block into a file named “C:\Temp\NetworkDef-Full.xml”.<NetworkConfiguration xmlns:xsd="" xmlns:xsi="" xmlns=""> <VirtualNetworkConfiguration> <Dns /> <VirtualNetworkSites> <VirtualNetworkSite name="placeholder-network" AffinityGroup="placeholder-affinitygroup"> <AddressSpace> <AddressPrefix>172.16.0.0/17</AddressPrefix> </AddressSpace> <Subnets> <Subnet name="ADNet"> <AddressPrefix>172.16.1.0/29</AddressPrefix> </Subnet> <Subnet name="DBNet"> <AddressPrefix>172.16.2.0/24</AddressPrefix> </Subnet> <Subnet name="AppNet"> <AddressPrefix>172.16.3.0/24</AddressPrefix> </Subnet> <Subnet name="WebNet"> <AddressPrefix>172.16.4.0/24</AddressPrefix> </Subnet> <Subnet name="GatewaySubnet"> <AddressPrefix>172.16.127.0/29</AddressPrefix> </Subnet> </Subnets> <Gateway> <VPNClientAddressPool> <AddressPrefix>172.16.128.0/29</AddressPrefix> </VPNClientAddressPool> <ConnectionsToLocalNetwork /> </Gateway> </VirtualNetworkSite> </VirtualNetworkSites> </VirtualNetworkConfiguration></NetworkConfiguration>Run the following Windows Azure PowerShell (use the variable/subscription block without the storage account).# Get a temporary path for the network config...$networkTempPath = [IO.Path]::GetTempFileName()# Get the current network configuration...Get-AzureVNetConfig -ExportToFile $networkTempPath# Determine whether we got the network configuration...if ((Test-Path $networkTempPath) -eq $false){ # Didn't get a config file... # Load the full network config... [string]$networkConfig = Get-Content ("C:\Temp\NetworkDef-Full.xml") # Replace the placeholder name and affinity group with the variable values... $networkConfig = $networkConfig.Replace("placeholder-network", $virtualNetworkName).Replace("placeholder-affinitygroup", $affinityGroupName) # Save the network configuration... $networkConfig.Save($networkTempPath)}else{ # Got a config file... # Load the config file... [xml]$networkConfig = Get-Content $networkTempPath # Check for VirtualNetworkSites node... if ($networkConfig.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("VirtualNetworkSites") -eq $NULL) { # VirtualNetworkSites node not found...create one... $virtualNetworkNamespace = "" $vncNode = $networkConfig.CreateNode("element", "VirtualNetworkSites", $virtualNetworkNamespace) $networkConfig.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").AppendChild($vncNode) } # Merge in the predefined configuration... # Load the network config fragment... [string]$networkConfigNode = Get-Content ("C:\Temp\NetworkDef.xml") # Replace the placeholder name and affinity group with the variable values... $networkConfigNode = $networkConfigNode.Replace("placeholder-network", $virtualNetworkName).Replace("placeholder-affinitygroup", $affinityGroupName) # Merge the fragment into the full file... $networkConfig.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("VirtualNetworkSites").InnerXML += $networkConfigNode # Save the network configuration... $networkConfig.Save($networkTempPath)}# Upload the network configuration...Set-AzureVNetConfig -ConfigurationPath $networkTempPath# Clean up the temporary file...Remove-Item -Path $networkTempPathValidationThere are two ways to verify that the network has been created:Portal – In the Windows Azure Management Portal, click Networks and verify that the network exists (you might need to refresh the page); also review the configuration to make sure it looks like what was defined earlier in the paper.Windows PowerShell – Run the following Windows PowerShell command (include the same variable script block used to run the command listed earlier). It should return the value True.((Get-AzureVnetSite | Where {$_.Name -eq $virtualNetworkName}) -ne $NULL) Point-to-Site VPNIf you want to use the point-to-site VPN capabilities (as of this writing, the feature is in a preview state), complete the configuration as outlined here: (starting with the “Create a dynamic routing gateway” heading; everything prior to that has already been completed through the network configuration). If you chose not to not the point-to-site VPN functionality, you will need to remove the “-NoRDPEndpoint” switch from the “Add-AzureProvisioningConfig” commands for your virtual machines. This change allows Windows Azure to create a RDP endpoint that you can use to connect to the machine.Cloud ServiceThe cloud service provides a container for all of the virtual machines to live in, as well as a public IP and DNS entry for us to use for access. It is possible to have multiple cloud services sharing a single virtual network, but for this paper we have only one.Create the Cloud ServiceTo create the cloud service, run the following Windows Azure PowerShell command (use the variable/subscription block without the storage account).New-AzureService ` -AffinityGroup $affinityGroupName ` -ServiceName $cloudServiceName ` -Description $cloudServiceDescription ` -Label $cloudServiceLabel ValidationThere are two ways to verify that the cloud service was created:Portal – In the Windows Azure Management Portal, click Cloud Services and then verify that the cloud service exists (you might need to refresh the page). PowerShell – Run the following Windows PowerShell command (include the same variable script block used to run the command listed earlier). It should return the value True.((Get-AzureService | where {$_.ServiceName -eq $cloudServiceName}) -ne $NULL)Storage AccountFor the purposes of this paper, we will put all of our resources into a single storage account. This may not be the optimal situation for a high-throughput production system (especially if you have database servers that perform a large number of storage transactions). There is one reason, however, to put multiple virtual machines into a single storage account—custom-built images (which we discuss later in the paper).Create the Storage AccountTo create the storage account, run the following Windows Azure PowerShell command (use the variable/subscription block without the storage account defined).New-AzureStorageAccount ` -StorageAccountName $storageAccountName ` -Label $storageAccountLabel ` -AffinityGroup $affinityGroupNameValidationThere are two ways to verify that the storage account was created:Portal – In the Windows Azure Management Portal, click Storage and then verify that the storage account exists (you might need to refresh the page).Windows PowerShell – Run the following Windows PowerShell command.((Get-AzureStorageAccount | where {$_.StorageAccountName -eq $storageAccountName}) -ne $NULL)At this point, your Windows Azure environment should be configured and ready for us to move on to creating the actual virtual machines. To Overview of the deployment stepsStep2: Deploy Active Directory Domain ServicesNow that our Windows Azure infrastructure is in place, we need to start building out the virtual machines that will support the BI scenario. This starts with two domain controllers (BIPaper-DC1 and BIPaper-DC2). We need two domain controllers for high availability and to meet the Windows Azure SLA (which requires two or more machines in the same role—in this case the role is domain controller). One of the machines will have a share on it to hold our installation media for the other servers that we build, and the other machine will have a share that will serve as the quorum share for the Windows Failover Cluster that we build in a later step. It is a best practice to put your Active Directory databases on a disk that does not have write caching enabled (the C: drive of your VM will have caching enabled, and you should not change that setting), so that will be part of our build-out procedure. Another thing that we learned in testing is that the Windows Azure DNS server automatically gets added to the first domain controller as a forwarder. In the scripts we remove this automatic configuration.At the end of this section, you will have an environment that looks like this:First Domain Controller:Server Name – BIPaper-DC1Storage Account – <your globally unique name>Domain/Forest Name – BIPaper.localDomain/Forest Functional Level – Windows Server 2012Acting as a DNS ServerActive Directory Sites and Subnets Created to match the Virtual Network definitionAttached Disk – 50 GB for Active Directory databases (scripts format as Z)Network Subnet – ADNetAvailability Set – ADAvailabilitySetServer added to Windows Azure Virtual Network as a DNS serverSecond Domain Controller:Server Name – BIPaper-DC2Storage Account – <your globally unique name>Domain/Forest Name – BIPaper.localDomain/Forest Functional Level – Windows Server 2012Acting as a DNS ServerAttached Disk – 50 GB for Active Directory databases (scripts format as Z)Network Subnet – ADNetAvailability Set – ADAvailabilitySetServer added to Windows Azure Virtual Network as a DNS serverPublic Share – QuorumChange access granted to everyoneIf you feel comfortable creating this environment on your own, you can do so and then skip to the “Service User Accounts” section.First Domain ControllerThe first domain controller that we will create provides the foundation for all other machines that we build. It serves as not only an Active Directory server, but also as an internal DNS server for name resolution between our VMs. As with all of the virtual machines we will be creating, the first step is a Windows Azure PowerShell command that runs off-box and creates the machine itself. The remaining steps are Windows PowerShell commands that run while you are logged into the VM.Provision VMThis is the only off-box task within the scope of creating the first domain controller. All other scripts are run in a remote desktop session on the machine. This script consists of the following elements:Variable Block – This section gathers information (in addition to the standard variable block you provide as outlined earlier in the document).VM Creation – This section (starting with the comment “Creating the virtual machine…”) consists of the following Windows Azure commands:New-AzureVMConfig – This command begins the definition of the virtual machine. It sets the name, size, image, vhd location and label, and availability set.Add-AzureProvisioningConfig – This command determines how Windows Azure should provision the VM defined in the last command. It tells Windows Azure that this will be a Windows machine, that automatic updates should be disabled (you can turn this back on if you want), that there should not be endpoints for RDP or Remote Windows PowerShell, and what the administrator user and password should be.Set-AzureSubnet – This command defines what subnet the virtual machine should be deployed into.Add-AzureDataDisk – This command attaches an empty disk to the virtual machine when it is created. The command defines the size and storage location of the disk, as well as the LUN and cache setting.New-AzureVM – This command creates the virtual machine that was defined in the earlier commands. In addition to the information gathered from the earlier commands, it defines the cloud service and virtual network that should be used. The script loops until creation of the VM is complete and the script writes a status to the screen every 15 seconds.DNS Creation – This section (starting with the comment “DNS Variables…”) consists of the following sections:DNS Variables – A set of variables used to create a DNS entry in the virtual network.Get the Windows Azure Network Configuration File – Loads the current virtual network configuration.Check for DNS Node – Checks the network configuration XML for a DNS node and creates one if it does not exist.Check for DnsServers Node – Checks the network configuration XML for a DnsServers node and creates one if it does not exist.Add DNS Server Entry – Adds the newly created domain controller as an available DNS server.Add DNS Servers Reference – Checks the network configuration XML for a DnsServersRef node in the paper’s virtual network and creates one if it does not exist.Add DNS Server Reference – Checks the network configuration XML for a DnsServerRef node in the paper’s virtual network and creates one if it does not exist.Save the Network Configuration – Saves the network configuration XML.Update the Network Configuration – Uploads the updated network configuration to Windows Azure.Clean Up After Yourself – Cleans up the temporary file used for the network configuration.To create the first domain controller, run the following Windows Azure PowerShell command (use the variable/subscription block with the storage account defined).# Get the name for the VM...$vmName = "BIPaper-DC1" # Get the admin user name for the VM...$vmAdminUserName = Read-Host -Prompt "Server Administrator User Name"# Ask for the password that should be used for the server and convert it to a format usable by the commands...$vmAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Server Administrator Password"$stringMarshal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($vmAdminPasswordSecure)$vmAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal)# Get the name of the VM Image to use...$vmImageName = (Get-AzureVMImage | Where { $_.Category -eq "Microsoft Windows Server Group" -and $_.Label -like "Windows Server 2012 Datacenter*" } | Sort-Object PublishedDate -Descending | SELECT ImageName)[0].ImageName# Set the location for the .vhd files...$storageAccountContainer = "https://" + $storageAccountName + ".blob.core.vhds/"$vmVHDLocation = $storageAccountContainer + $vmName + ".vhd"$vmADVHDLocation = $storageAccountContainer + $vmName + "_ADData.vhd"$vmADVHDName = $vmName + " AD Data"# Create the virtual machine...Write-Host "Creating the VM..."New-AzureVMConfig ` -Name $vmName ` -InstanceSize Small ` -ImageName $vmImageName ` -MediaLocation $vmVHDLocation ` -DiskLabel "OS" ` -AvailabilitySetName "ADAvailabilitySet" | Add-AzureProvisioningConfig ` -Windows ` -DisableAutomaticUpdates ` -DisableWinRMHttps ` -NoRDPEndpoint ` -AdminUsername $vmAdminUserName ` -Password $vmAdminPassword | Set-AzureSubnet ` -SubnetNames "ADNet" | Add-AzureDataDisk ` -CreateNew ` -DiskSizeInGB "50" ` -MediaLocation $vmADVHDLocation ` -DiskLabel $vmADVHDName ` -LUN 0 ` -HostCaching "None" | New-AzureVM ` -ServiceName $cloudServiceName ` -VNetName $virtualNetworkName# Loop until Status = ReadyRole...Write-Host "`tWaiting for Provisioning to Complete..."$VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceNameWhile ($VMStatus.InstanceStatus -ne "ReadyRole"){ write-host "`t`tWaiting...Current Status = " $VMStatus.InstanceStatus Start-Sleep -Seconds 15 $VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceName}# DNS Variables...Write-Host "Configuring DNS..."$dnsChanged = 0$virtualNetworkNamespace = ""$networkTempPath = [IO.Path]::GetTempFileName()$dcIPAddress = (Get-AzureVM -ServiceName $cloudServiceName -Name $vmName).IpAddress# Remove Temporary File if It Exists...if ((Test-Path $networkTempPath) -eq $true){ Remove-Item $networkTempPath}# Get the Azure Network Configuration File...Get-AzureVNetConfig -ExportToFile $networkTempPath[xml]$dnsNetwork = Get-Content $networkTempPath# Check for DNS Node...if ($dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("Dns") -eq $NULL){ $dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").AppendChild($dnsNetwork.CreateNode("element", "Dns", $virtualNetworkNamespace)) $dnsChanged = 1}# Check for DnsServers Node...if ($dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("Dns").Item("DnsServers") -eq $NULL){ $dnsServersNode = $dnsNetwork.CreateNode("element", "DnsServers", $virtualNetworkNamespace) $dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("Dns").AppendChild($dnsServersNode) $dnsChanged = 1}# Add DNS Server Entry...if (($dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("Dns").Item("DnsServers").ChildNodes | Where {$_.Name -eq $vmName}) -eq $NULL){ $dnsServerNode = $dnsNetwork.CreateNode("element", "DnsServer", $virtualNetworkNamespace) $dnsServerNode.SetAttribute("name", $vmName) $dnsServerNode.SetAttribute("IPAddress", $dcIPAddress) $dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("Dns").Item("DnsServers").AppendChild($dnsServerNode) $dnsChanged = 1}# Add DNS Servers Reference...$virtualNetwork = $dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("VirtualNetworkSites").ChildNodes | Where {$_.Name -eq $virtualNetworkName}if ($virtualNetwork.Item("DnsServersRef") -eq $NULL){ $virtualNetwork.AppendChild($dnsNetwork.CreateNode("element", "DnsServersRef", $virtualNetworkNamespace)) $dnsChanged = 1}# Add DNS Server Reference...$dnsServerRef = ($dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("VirtualNetworkSites").ChildNodes | Where {$_.Name -eq $virtualNetworkName}).Item("DnsServersRef")if (($dnsServerRef.ChildNodes | Where {$_.Name -eq $dnsServerName}) -eq $NULL){ $dnsServerRefNode = $dnsNetwork.CreateNode("element", "DnsServerRef", $virtualNetworkNamespace) $dnsServerRefNode.SetAttribute("name", $vmName) $dnsServerRef.AppendChild($dnsServerRefNode) $dnsChanged = 1}# Save the Network Configuration...$dnsNetwork.Save($networkTempPath)# Update the Network Configuration...if ($dnsChanged -eq 1){ Set-AzureVNetConfig -ConfigurationPath $networkTempPath}# Clean Up After Yourself...Remove-Item $networkTempPathValidationThere are two ways to verify that the virtual machine was created:Portal – In the Windows Azure Management Portal, click Virtual Machines and then verify that the virtual machine exists (you might need to refresh the page).PowerShell – Run the following Windows PowerShell command (include the same variable script block used to run the command listed earlier). It should return the value True.((Get-AzureVM -name "BIPaper-DC1" -ServiceName $cloudServiceName) -ne $NULL)To validate that the DNS server entry was created, open the Windows Azure Management portal, select the network used for this paper (BIPaper-Network is the default unless you used a different name) and navigate to the Configure page. You should see an entry under dns servers for the domain controller that was just created and its IP address (you might need to refresh the page).The rest of the scripts for this domain controller are run while you are logged into the machine. Connect through remote desktop (either through a public endpoint on the virtual machine or through a point-to-site VPN) before you run these scripts.Format DisksThis on-box script formats the disk that was created to host the Active Directory databases.The script block requires that the following text be stored in a text file named “C:\Temp\DiskpartUnattended.txt”.rescanselect disk 2online disk noerrcreate partition primaryselect part 1format quickassign letter=Z:After that file is created, run the following script in Windows PowerShell on the target machine (this script does not require the variable block defined earlier).diskpart /s ("C:\Temp\DiskpartUnattended.txt")ValidationTo verify that this command worked, start Windows Explorer and then verify that the Z:\ drive exists.Create DomainThis command promotes the machine to a domain controller. There are four components to the script:Get the Safe Mode Administrator Password – Prompts the user for the safe mode administrator password that you want to use for the domain.Install the Active Directory Feature – Installs the Windows feature for Active Directory Domain Services and also installs the appropriate management tools.Import the ADDS PowerShell Module – Imports the Windows PowerShell module for the feature that was just installed so that it can be used for the next command.Promote the Domain Controller – Turns this server into a domain controller. Run the following script in Windows PowerShell on the target machine using the on-box variable block defined earlier in the document.# Get the Safe Mode Administrator Password...$password = Read-Host -AsSecureString -Prompt "Safe Mode Administrator Password"# Install the Active Directory Feature...Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools# Import the ADDS PowerShell Module...Import-Module ADDSDeployment# Promote the Domain Controller...Install-ADDSForest ` -DomainName $domainNameFQ ` -DomainNetbiosName $domainName ` -ForestMode "Win2012" ` -DomainMode "Win2012" ` -SafeModeAdministratorPassword $password ` -DatabasePath "Z:\Windows\NTDS" ` -LogPath "Z:\Windows\NTDS" ` -SysvolPath "Z:\Windows\SYSVOL" ` -InstallDns:$true ` -CreateDnsDelegation:$false ` -NoRebootOnCompletion:$true ` -Force:$trueNote: You will receive warnings about the server not having a static IP address. This is fine, because the IP address that is assigned to a VM in Windows Azure, though it is dynamically assigned, has an infinite lease.Note: After you promote the machine to a domain controller, you will need to log in with domain\username (using the same user name you specified for the local machine administrator account).After you run this command, restart the server.ValidationTo verify that this command worked:Log in to the server.Open Windows Explorer.In the left-hand tree view, right-click Computer, and then click Properties.In the window that is displayed, verify that the domain listed is what you set for the variable $domainNameFQ.Create Sites and SubnetsThis script will create the Active Directory sites and subnets to support the network configuration that we defined earlier.Run the following script in Windows PowerShell on the target machine using the on-box variable block defined earlier in the document.# Split FQDN...$dc = ""foreach ($part in $domainNameFQ.Split(".")){ $dc += (",DC=" + $part)}# Import the Active Directory PowerShell Module...Import-Module ActiveDirectory# Create the Default Subnet...New-ADObject ` -Name '172.16.0.0/17' ` -Type subnet ` -Description 'DefaultSubnet' ` -Path "CN=Subnets,CN=Sites,CN=Configuration$dc" ` -OtherAttributes @{siteObject="CN=Default-First-Site-Name,CN=Sites,CN=Configuration$dc"}# Create the DC Site...New-ADObject ` -Name 'DC' ` -Type site ` -Path "CN=Sites,CN=Configuration$dc"# Create the DCNet Subnet...New-ADObject ` -Name '172.16.1.0/29' ` -Type subnet ` -Description 'DCNet' ` -Path "CN=Subnets,CN=Sites,CN=Configuration$dc" ` -OtherAttributes @{siteObject="CN=DC,CN=Sites,CN=Configuration$dc"}# Create the DB Site...New-ADObject ` -Name 'DB' ` -Type site ` -Path "CN=Sites,CN=Configuration$dc"# Create the DBNet Subnet...New-ADObject ` -Name '172.16.2.0/24' ` -Type subnet ` -Description 'DBNet' ` -Path "CN=Subnets,CN=Sites,CN=Configuration$dc" ` -OtherAttributes @{siteObject="CN=DB,CN=Sites,CN=Configuration$dc"}# Create the App Site...New-ADObject ` -Name 'App' ` -Type site ` -Path "CN=Sites,CN=Configuration$dc"# Create the AppNet Subnet...New-ADObject ` -Name '172.16.3.0/24' ` -Type subnet ` -Description 'AppNet' ` -Path "CN=Subnets,CN=Sites,CN=Configuration$dc" ` -OtherAttributes @{siteObject="CN=App,CN=Sites,CN=Configuration$dc"}# Create the Web Site...New-ADObject ` -Name 'Web' ` -Type site ` -Path "CN=Sites,CN=Configuration$dc"# Create the WebNet Subnet...New-ADObject ` -Name '172.16.4.0/24' ` -Type subnet ` -Description 'WebNet' ` -Path "CN=Subnets,CN=Sites,CN=Configuration$dc" ` -OtherAttributes @{siteObject="CN=Web,CN=Sites,CN=Configuration$dc"}ValidationTo verify that this command worked:Log in to the server.Start Active Directory Sites and Services.In the left-hand tree-view, expand the Sites node.In the left-hand tree-view, you should see nodes for App, DB, DC, Default-First-Site-Name and Web.In the left-hand tree-view, click Subnets.In the right-hand list-view, verify that the following subnet/name combinations are present:172.16.0.0/17Default-First-Site-Name172.16.1.0/29DC172.16.2.0/24DB172.16.3.0/24App172.16.4.0/24WebRemove ForwarderWhen the server was promoted to a domain controller, the Windows Azure DNS server was added to the list of DNS forwarders. It is not necessary to have it there, so it can be removed.Run the following script in Windows PowerShell on the target machine using the on-box variable block defined earlier in the document.Get-DnsServerForwarder | Remove-DnsServerForwarder -ForceValidationTo verify that this command worked:Log in to the server.Start DNS Manager.In the left-hand tree-view, right-click BIPaper-DC1 (or your server name if you have changed it from the default used in the scripts), and then click Properties.In the Properties dialog box, click Forwarders.Verify that the list of forwarders is empty.Second Domain ControllerThe second domain controller that we will create provides the high availability that is required for this environment. It will serve as not only an Active Directory server, but also as an internal DNS server for name resolution between our VMs. As with all of the virtual machines we will be creating, the first step is a Windows Azure PowerShell command that runs off-box and creates the machine itself. The remaining steps are Windows PowerShell commands that run while you are logged into the VM.Provision VMThis is the only off-box task within the scope of creating the second domain controller. All other scripts are run in a remote desktop session on the machine. This script consists of the following elements:Variable Block – This section gathers information (in addition to the standard variable block you provide as outlined earlier in the document).VM Creation – This section (starting with the comment “Creating the virtual machine…”) consists of the following Windows Azure commands:New-AzureVMConfig – This command begins the definition of the virtual machine. It sets the name, size, image, vhd location and label, and availability set.Add-AzureProvisioningConfig – This command determines how Windows Azure should provision the VM defined in the last command. It tells Windows Azure that this will be a Windows machine, that automatic updates should be disabled (you can turn this back on if you want), that there should not be endpoints for RDP or Remote Windows PowerShell, and what the administrator user and password should be. Additionally, this command provides the information necessary to automatically join the machine to our domain.Set-AzureSubnet – This command defines what subnet the virtual machine should be deployed into.Add-AzureDataDisk – This command attaches an empty disk to the virtual machine when it is created. The command defines the size and storage location of the disk, as well as the LUN and cache setting.New-AzureVM – This command does the work of creating the virtual machine that was defined in the earlier commands. In addition to the information gathered from the earlier commands, it defines the cloud service and virtual network that should be used. The script loops until creation of the VM is complete and writes a status to the screen every 15 seconds.DNS Creation – This section (starting with the comment “DNS Variables…”) consists of the following sections:DNS Variables – A set of variables used to create a DNS entry in the virtual network.Get the Windows Azure Network Configuration File – Loads the current virtual network configuration.Check for DNS Node – Checks the network configuration XML for a DNS node and creates one if it does not exist.Check for DnsServers Node – Checks the network configuration XML for a DnsServers node and creates one if it does not exist.Add DNS Server Entry – Adds the newly created domain controller as an available DNS server.Add DNS Servers Reference – Checks the network configuration XML for a DnsServersRef node in the paper’s virtual network and creates one if it does not exist.Add DNS Server Reference – Checks the network configuration XML for a DnsServerRef node in the paper’s virtual network and creates one if it does not exist.Save the Network Configuration – Saves the network configuration XML.Update the Network Configuration – Uploads the updated network configuration to Windows Azure.Clean Up After Yourself – Cleans up the temporary file used for the network configuration.To create the second domain controller, run the following Windows Azure PowerShell command (use the variable/subscription block with the storage account defined).# Get the name for the VM...$vmName = "BIPaper-DC2"# Get the admin user name for the VM...$vmAdminUserName = Read-Host -Prompt "Server Administrator User Name"# Ask for the password that should be used for the server and convert it to a format usable by the commands...$vmAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Server Administrator Password"$stringMarshal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($vmAdminPasswordSecure)$vmAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal)# Get the domain admin user name...$domainAdminUserName = Read-Host -Prompt "Domain Administrator User Name"# Ask for the domain admin password and convert it to a format usable by the commands...$domainAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Domain Administrator Password"$stringMarshal2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($domainAdminPasswordSecure)$domainAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal2)# Get the name of the VM Image to use...$vmImageName = (Get-AzureVMImage | Where { $_.Category -eq "Microsoft Windows Server Group" -and $_.Label -like "Windows Server 2012 Datacenter*" } | Sort-Object PublishedDate -Descending | SELECT ImageName)[0].ImageName# Set the location of the .vhd files...$storageAccountContainer = "https://" + $storageAccountName + ".blob.core.vhds/"$vmVHDLocation = $storageAccountContainer + $vmName + ".vhd"$vmADVHDLocation = $storageAccountContainer + $vmName + "_ADData.vhd"$vmADVHDName = $vmName + " AD Data"# Create the virtual machine...Write-Host "Creating the VM..."New-AzureVMConfig ` -Name $vmName ` -InstanceSize Small ` -ImageName $vmImageName ` -MediaLocation $vmVHDLocation ` -DiskLabel "OS" ` -AvailabilitySetName "ADAvailabilitySet" | Add-AzureProvisioningConfig ` -WindowsDomain ` -DisableAutomaticUpdates ` -DisableWinRMHttps ` -NoRDPEndpoint ` -Domain $domainName ` -JoinDomain $domainNameFQ ` -DomainPassword $domainAdminPassword ` -DomainUserName $domainAdminUserName ` -AdminUsername $vmAdminUserName ` -Password $vmAdminPassword | Set-AzureSubnet ` -SubnetNames "ADNet" | Add-AzureDataDisk ` -CreateNew ` -DiskSizeInGB "50" ` -MediaLocation $vmADVHDLocation ` -DiskLabel $vmADVHDName ` -LUN 0 ` -HostCaching "None" | New-AzureVM ` -ServiceName $cloudServiceName# Loop until Satus = ReadyRole...Write-Host "`tWaiting for Provisioning to Complete..."$VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceNameWhile ($VMStatus.InstanceStatus -ne "ReadyRole"){ write-host "`t`tWaiting...Current Status = " $VMStatus.InstanceStatus Start-Sleep -Seconds 15 $VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceName}# DNS Variables...Write-Host "Configuring DNS..."$dnsChanged = 0$virtualNetworkNamespace = ""$networkTempPath = [IO.Path]::GetTempFileName()$dcIPAddress = (Get-AzureVM -ServiceName $cloudServiceName -Name $vmName).IpAddress# Remove Temporary File if it Exists...if ((Test-Path $networkTempPath) -eq $true){ Remove-Item $networkTempPath}# Get the Azure Network Configuration File...Get-AzureVNetConfig -ExportToFile $networkTempPath[xml]$dnsNetwork = Get-Content $networkTempPath# Check for DNS Node...if ($dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("Dns") -eq $NULL){ $dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").AppendChild($dnsNetwork.CreateNode("element", "Dns", $virtualNetworkNamespace)) $dnsChanged = 1}# Check for DnsServers Node...if ($dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("Dns").Item("DnsServers") -eq $NULL){ $dnsServersNode = $dnsNetwork.CreateNode("element", "DnsServers", $virtualNetworkNamespace) $dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("Dns").AppendChild($dnsServersNode) $dnsChanged = 1}# Add DNS Server Entry...if (($dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("Dns").Item("DnsServers").ChildNodes | Where {$_.Name -eq $vmName}) -eq $NULL){ $dnsServerNode = $dnsNetwork.CreateNode("element", "DnsServer", $virtualNetworkNamespace) $dnsServerNode.SetAttribute("name", $vmName) $dnsServerNode.SetAttribute("IPAddress", $dcIPAddress) $dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("Dns").Item("DnsServers").AppendChild($dnsServerNode) $dnsChanged = 1}# Add DNS Servers Reference...$virtualNetwork = $dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("VirtualNetworkSites").ChildNodes | Where {$_.Name -eq $virtualNetworkName}if ($virtualNetwork.Item("DnsServersRef") -eq $NULL){ $virtualNetwork.AppendChild($dnsNetwork.CreateNode("element", "DnsServersRef", $virtualNetworkNamespace)) $dnsChanged = 1}# Add DNS Server Reference...$dnsServerRef = ($dnsNetwork.Item("NetworkConfiguration").Item("VirtualNetworkConfiguration").Item("VirtualNetworkSites").ChildNodes | Where {$_.Name -eq $virtualNetworkName}).Item("DnsServersRef")if (($dnsServerRef.ChildNodes | Where {$_.Name -eq $dnsServerName}) -eq $NULL){ $dnsServerRefNode = $dnsNetwork.CreateNode("element", "DnsServerRef", $virtualNetworkNamespace) $dnsServerRefNode.SetAttribute("name", $vmName) $dnsServerRef.AppendChild($dnsServerRefNode) $dnsChanged = 1}# Save the Network Configuration...$dnsNetwork.Save($networkTempPath)# Update the Network Configuration...if ($dnsChanged -eq 1){ Set-AzureVNetConfig -ConfigurationPath $networkTempPath}# Clean Up After Yourself...Remove-Item $networkTempPathValidationThere are two ways to verify that the Virtual Machine was created:Portal – In the Windows Azure Management Portal, click Virtual Machines and then verify that the virtual machine exists (you might need to refresh the page).Windows PowerShell – Run the following Windows PowerShell command (include the same variable script block used to run the command above). It should return the value True.((Get-AzureVM -name "BIPaper-DC2" -ServiceName $cloudServiceName) -ne $NULL)To verify that the DNS server entry was created, open the Windows Azure Management portal, select the network used for this paper (BIPaper-Network is the default unless you used a different name) and navigate to the Configure page. You should see an entry under dns servers for the domain controller that was just created and its IP address (you might need to refresh the page).The rest of the scripts for this domain controller will be run while you are logged into the machine. Connect through remote desktop (either through a public endpoint on the virtual machine or through a point-to-site VPN) before you run these scripts.Format DisksThis on-box script formats the disk that was created to host the Active Directory databases.The script block requires that the following text be stored in a text file named “C:\Temp\DiskpartUnattended.txt”.rescanselect disk 2online disk noerrcreate partition primaryselect part 1format quickassign letter=Z:After that file is created, run the following script in Windows PowerShell on the target machine (this script does not require the variable block defined earlier).diskpart /s ("C:\Temp\DiskpartUnattended.txt")ValidationTo verify that this command worked, start Windows Explorer and then verify that the Z:\ drive exists.Create Domain ControllerThis command promotes the machine to a domain controller. There are four components to the script:Get the Safe Mode Administrator Password – Prompts the user for the safe mode administrator password that they want to use for the domain. Provide the same password that was used when the domain was created with the first domain controller.Install the Active Directory Feature – Installs the Windows feature for Active Directory Domain Services and also installs the appropriate management tools.Import the ADDS PowerShell Module – Imports the Windows PowerShell module for the feature that was just installed so that it can be used for the next command.Promote the Domain Controller – Turns this server into a domain controller. Run the following script in Windows PowerShell on the target machine using the on-box variable block defined earlier in the document.# Get the Safe Mode Administrator Password...$password = Read-Host -AsSecureString -Prompt "Safe Mode Administrator Password"# Install the Active Directory Feature...Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools# Import the ADDS PowerShell Module...Import-Module ADDSDeployment# Promote the Domain Controller...Install-ADDSDomainController ` -DomainName $domainNameFQ ` -SiteName "Default-First-Site-Name" ` -SafeModeAdministratorPassword $password ` -DatabasePath "z:\Windows\NTDS" ` -LogPath "z:\Windows\NTDS" ` -SysvolPath "z:\Windows\SYSVOL" ` -InstallDns:$true ` -CreateDnsDelegation:$false ` -NoGlobalCatalog:$false ` -CriticalReplicationOnly:$false ` -NoRebootOnCompletion:$true ` -Force:$trueNote: You will receive warnings about the server not having a static IP address. This is fine, because the IP address that is assigned to a VM in Windows Azure, though it is dynamically assigned, has an infinite lease.Note: After you promote the machine to a domain controller, you will need to log in with domain\username (using the same user name you specified for the local machine administrator account).After you run this command, restart the server.ValidationTo verify that this command worked:Log in to the server.Open Windows Explorer.In the left-hand tree view, right-click Computer, and then click Properties.In the window that is displayed, verify that the domain listed is what you set for the variable $domainNameFQ.Create ShareThis on-box script creates a share that will be used as a quorum disk for the Windows Failover Cluster that will be created in a later step.Run the following script in Windows PowerShell on the target machine using the on-box variable block defined earlier in the document.# Create Quorum Share...C:CD \mkdir Quorumnet share Quorum=c:\Quorum /grant`:Everyone`,CHANGEValidationTo verify that this command worked:Log in to the server.Open Windows Explorer.Browse to the root of C:\, and then verify that a directory named Quorum exists.Right-click on the Quorum directory, and then click Properties.In the Properties dialog box, select the Sharing tab.Verify that directory is shared with the network path \\BIPaper-DC2\Quorum (or the name of the server that you used in the script if you changed it).Click Advanced Sharing, and then click Permissions. Verify that the group Everyone has been granted Change permissions.Service User AccountsIn this step we will create a series of accounts that will be used to run the services that we create during the rest of the paper. When we are finished, the following Active Directory objects will have been created:Note: The values in bold in the list are names that are relied on through the rest of the paper. If you use different names, you will need to adjust future scripts that use these anizational UnitName – Service AccountsCreated In – BIPaper.localUser AccountsName – DB1_SQL_EngineOrganizational Unit – Service AccountsDisplay Name – DB1 SQL Server Engine Service AccountSAM Account Name – DB1_SQL_EngineName – DB1_SQL_AgentOrganizational Unit – Service AccountsDisplay Name – DB1 SQL Server Agent Service AccountSAM Account Name – DB1_SQL_AgentName – DB2_SQL_EngineOrganizational Unit – Service AccountsDisplay Name – DB2 SQL Server Engine Service AccountSAM Account Name – DB2_SQL_EngineName – DB2_SQL_AgentOrganizational Unit – Service AccountsDisplay Name – DB2 SQL Server Agent Service AccountSAM Account Name – DB2_SQL_AgentName – SP_FarmOrganizational Unit – Service AccountsDisplay Name – SharePoint Farm Service AccountSAM Account Name – SP_FarmName – SQL_ReportingOrganizational Unit – Service AccountsDisplay Name – Reporting Services Service AccountSAM Account Name – SQL_ReportingName – PP1_PowerPivotOrganizational Unit – Service AccountsDisplay Name – PP1 PowerPivot Service AccountSAM Account Name – PP1_PowerPivotName – PP2_PowerPivotOrganizational Unit – Service AccountsDisplay Name – PP2 PowerPivot Service AccountSAM Account Name – PP2_PowerPivotThe accounts created here are configured so that their passwords never expire. If you are using this paper to configure a production environment, be sure to follow your organization’s password requirements.Create Service User AccountsLog in to one of the two domain controllers (either will work) and run the following script in Windows PowerShell using the on-box variable block defined earlier in the document.# Get the password for the service accounts...$serviceAccountPassword = Read-Host -AsSecureString -Prompt "Service Account Password"# Create an OU for the Accounts...New-ADOrganizationalUnit -Name "Service Accounts"$organizationalUnit = Get-ADOrganizationalUnit -Filter "Name -eq 'Service Accounts'"# Create the DB1 SQL Server Engine Account...New-ADUser ` -Name "DB1_SQL_Engine" ` -AccountPassword $serviceAccountPassword ` -Path $organizationalUnit.DistinguishedName ` -ChangePasswordAtLogon 0 ` -DisplayName "DB1 SQL Server Engine Service Account" ` -Enabled 1 ` -PasswordNeverExpires 1 ` -SamAccountName "DB1_SQL_Engine"# Create the DB1 SQL Server Agent Account...New-ADUser ` -Name "DB1_SQL_Agent" ` -AccountPassword $serviceAccountPassword ` -Path $organizationalUnit.DistinguishedName ` -ChangePasswordAtLogon 0 ` -DisplayName "DB1 SQL Server Agent Service Account" ` -Enabled 1 ` -PasswordNeverExpires 1 ` -SamAccountName "DB1_SQL_Agent"# Create the DB2 SQL Server Engine Account...New-ADUser ` -Name "DB2_SQL_Engine" ` -AccountPassword $serviceAccountPassword ` -Path $organizationalUnit.DistinguishedName ` -ChangePasswordAtLogon 0 ` -DisplayName "DB2 SQL Server Engine Service Account" ` -Enabled 1 ` -PasswordNeverExpires 1 ` -SamAccountName "DB2_SQL_Engine"# Create the DB2 SQL Server Agent Account...New-ADUser ` -Name "DB2_SQL_Agent" ` -AccountPassword $serviceAccountPassword ` -Path $organizationalUnit.DistinguishedName ` -ChangePasswordAtLogon 0 ` -DisplayName "DB2 SQL Server Agent Service Account" ` -Enabled 1 ` -PasswordNeverExpires 1 ` -SamAccountName "DB2_SQL_Agent"# Create the SharePoint Farm Account...New-ADUser ` -Name "SP_Farm" ` -AccountPassword $serviceAccountPassword ` -Path $organizationalUnit.DistinguishedName ` -ChangePasswordAtLogon 0 ` -DisplayName "SharePoint Farm Service Account" ` -Enabled 1 ` -PasswordNeverExpires 1 ` -SamAccountName "SP_Farm"# Create the Reporting Services Service Account...New-ADUser ` -Name "SQL_Reporting" ` -AccountPassword $serviceAccountPassword ` -Path $organizationalUnit.DistinguishedName ` -ChangePasswordAtLogon 0 ` -DisplayName "Reporting Services Service Account" ` -Enabled 1 ` -PasswordNeverExpires 1 ` -SamAccountName "SQL_Reporting"# Create the PP1 PowerPivot Service Account...New-ADUser ` -Name "PP1_PowerPivot" ` -AccountPassword $serviceAccountPassword ` -Path $organizationalUnit.DistinguishedName ` -ChangePasswordAtLogon 0 ` -DisplayName "PP1 PowerPivot Service Account" ` -Enabled 1 ` -PasswordNeverExpires 1 ` -SamAccountName "PP1_PowerPivot"# Create the PP2 PowerPivot Service Account...New-ADUser ` -Name "PP2_PowerPivot" ` -AccountPassword $serviceAccountPassword ` -Path $organizationalUnit.DistinguishedName ` -ChangePasswordAtLogon 0 ` -DisplayName "PP2 PowerPivot Service Account" ` -Enabled 1 ` -PasswordNeverExpires 1 ` -SamAccountName "PP2_PowerPivot"ValidationTo verify that this command was successful:Log in to one of the domain controllers.Start Active Directory Users and Computers.In the left-hand tree view, expand BIPaper.local (or your domain name if you have changed it).In the left-hand tree view, click Service Accounts, and then verify that the user accounts detailed in this section appear in the right-hand list view. To Overview of the deployment stepsStep 3: Configure SQL Server Database Servers (SharePoint Back End)In the previous sections we built the foundation with the Windows Azure environment and the two domain controllers. Now it is time to build the database servers (BiPaper-DB1 and BiPaper-DB2) that will support the SharePoint content and configuration databases. In this environment two instances of SQL Server host an availability group that contains the SharePoint databases. During this step we install the individual database servers, but we will configure AlwaysOn Availability Groups; that will happen after SharePoint is installed.At the end of this section, you will have an environment that looks like this:First Database ServerServer Name – BIPaper-DB1Storage Account – <your globally unique name>Domain/Forest Name – BIPaper.localAttached Disk – 250 GB for SQL Server (scripts format as S)Network Subnet – DBNetAvailability Set - DBAvailabilitySetSQL Server installed as the default instance with the following settings:Features – SQL Server Engine, SQL Server Management Studio with Advanced ToolsInstance directory on data driveEngine User Account – BIPaper\DB1_SQL_EngineAgent Startup Mode - AutomaticAgent User Account – BIPaper\DB1_SQL_AgentAgent Startup Mode – AutomaticMixed Mode SecurityDomain Administrator Account set as system adminTCP EnabledInbound TCP ports 1433 and 5022 open in firewall for domain networksFailover Clustering feature installedSecond Database ServerServer Name – BIPaper-DB2Storage Account – <your globally unique name>Domain/Forest Name – BIPaper.localAttached Disk – 250GB for SQL Server (scripts format as S)Network Subnet – DBNetAvailability Set - DBAvailabilitySetSQL Server installed as the default instance with the following settings:Features – SQL Server Engine, SQL Server Management Studio with Advanced ToolsInstance directory on data driveEngine User Account – BIPaper\DB2_SQL_EngineAgent Startup Mode - AutomaticAgent User Account – BIPaper\DB2_SQL_AgentAgent Startup Mode – AutomaticMixed Mode SecurityDomain Administrator Account set as system adminTCP EnabledInbound TCP ports 1433 and 5022 open in firewall for domain networksFailover Clustering feature installedIf you feel comfortable creating this environment on your own, you can do so and then skip to the “Step 4: configure SQL Server PowerPivot Servers” section. Important: This step requires installation media for SQL Server 2012 SP1 and at least . Place the information in the following directories on the VM:D:\SQL Server 2012\ – This should be the contents of the SQL Server installation media (use the media with SP1 slipstreamed). Do not just put the .iso file in this directory—it needs to be the contents of the media extracted.D:\SQL Server 2012 CU\ – This should be the .exe file that you would run to apply the CU. The CUs are delivered as executable .zip files, the contents of which are what we are looking for in this directory.Tip: When we configured this environment for the first time, we loaded all of the bits on a share on the first domain controller. Then when we needed to install software, we copied the bits to the local D:\ drive from the share.First SQL Server InstanceThe first SQL Server instance that we create will provide the landing zone for the databases that will be created during the configuration of our SharePoint farm. As with all of the virtual machines we will be creating, the first step is a Windows Azure PowerShell command that runs off-box and creates the machine itself. The remaining steps will be Windows PowerShell commands that are run while you are logged into the VM.Provision VMThis is the only off-box task within the scope of creating the first instance of SQL Server. All other scripts will be run in a remote desktop session on the machine. The script consists of the following elements:Variable Block – This section gathers information (in addition to the standard variable block you provide as outlined earlier in the document).VM Creation – This section (starting with the comment “Creating the virtual machine…”) consists of the following Windows Azure commands:New-AzureVMConfig – This command begins the definition of the virtual machine. It sets the name, size, image, .vhd location and label, and availability set.Add-AzureProvisioningConfig – This command determines how Windows Azure should provision the VM defined in the last command. It tells Windows Azure that this will be a Windows machine, that automatic updates should be disabled (you can turn this back on if you want), that there should not be endpoints for RDP or Remote Windows PowerShell, and what the administrator user and password should be. Additionally, this command provides the information necessary to automatically join the machine to our domain.Set-AzureSubnet – This command defines what subnet the virtual machine should be deployed into.Add-AzureDataDisk – This command attaches an empty disk to the virtual machine when it is created. The command defines the size and storage location of the disk, as well as the LUN and cache setting.New-AzureVM – This command does the work of creating the virtual machine that was defined in the earlier commands. In addition to the information gathered from the earlier commands, it defines the cloud service that should be used. The script loops until creation of the VM is complete and writes a status to the screen every 15 seconds.To create the first instance of SQL Server, run the following Windows Azure PowerShell command (use the variable/subscription block with the storage account defined).# Get the name for the VM...$vmName = "BIPaper-DB1"# Get the admin user name for the VM...$vmAdminUserName = Read-Host -Prompt "Server Administrator User Name"# Ask for the password that should be used for the server and convert it to a format usable by the commands...$vmAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Server Administrator Password"$stringMarshal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($vmAdminPasswordSecure)$vmAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal)# Get the domain admin user name...$domainAdminUserName = Read-Host -Prompt "Domain Administrator User Name"# Ask for the domain admin password and convert it to a format usable by the commands...$domainAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Domain Administrator Password"$stringMarshal2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($domainAdminPasswordSecure)$domainAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal2)# Get the name of the VM Image to use...$vmImageName = (Get-AzureVMImage | Where { $_.Category -eq "Microsoft Windows Server Group" -and $_.Label -like "Windows Server 2012 Datacenter*" } | Sort-Object PublishedDate -Descending | SELECT ImageName)[0].ImageName# Set the location of the .vhd files...$storageAccountContainer = "https://" + $storageAccountName + ".blob.core.vhds/"$vmVHDLocation = $storageAccountContainer + $vmName + ".vhd"$vmSQLVHDLocation = $storageAccountContainer + $vmName + "_SQLData.vhd"$vmSQLVHDName = $vmName + " SQL Data"# Create the virtual machine...Write-Host "Creating the VM..."New-AzureVMConfig ` -Name $vmName ` -InstanceSize ExtraLarge ` -ImageName $vmImageName ` -MediaLocation $vmVHDLocation ` -DiskLabel "OS" ` -AvailabilitySetName "DBAvailabilitySet" | Add-AzureProvisioningConfig ` -WindowsDomain ` -DisableAutomaticUpdates ` -DisableWinRMHttps ` -NoRDPEndpoint ` -Domain $domainName ` -JoinDomain $domainNameFQ ` -DomainPassword $domainAdminPassword ` -DomainUserName $domainAdminUserName ` -AdminUsername $vmAdminUserName ` -Password $vmAdminPassword | Set-AzureSubnet ` -SubnetNames "DBNet" | Add-AzureDataDisk ` -CreateNew ` -DiskSizeInGB "250" ` -MediaLocation $vmSQLVHDLocation ` -DiskLabel $vmSQLVHDName ` -LUN 0 ` -HostCaching "None" | New-AzureVM ` -ServiceName $cloudServiceName# Loop until Satus = ReadyRole...Write-Host "`tWaiting for Provisioning to Complete..."$VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceNameWhile ($VMStatus.InstanceStatus -ne "ReadyRole"){ write-host "`t`tWaiting...Current Status = " $VMStatus.InstanceStatus Start-Sleep -Seconds 15 $VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceName}ValidationThere are two ways to verify that the virtual machine was created:Portal – In the Windows Azure Management Portal, click Virtual Machines and then verify that the virtual machine exists (you might need to refresh the page).Windows PowerShell – Run the following Windows PowerShell command (include the same variable script block used to run the command above). It should return the value True.((Get-AzureVM -name "BIPaper-DB1" -ServiceName $cloudServiceName) -ne $NULL)Format DisksThis on-box script formats the disk that was created to host the SQL Server installation.The script block requires that the following text be stored in a text file named “C:\Temp\DiskpartUnattended.txt”.rescanselect disk 2online disk noerrcreate partition primaryselect part 1format quickassign letter=S:After that file is created, run the following script in Windows PowerShell on the target machine (this script does not require the variable block defined earlier).diskpart /s ("C:\Temp\DiskpartUnattended.txt")ValidationTo verify that this command worked, start Windows Explorer and then verify that the S:\ drive exists.Enable ClusteringThis on-box script enables Windows Clustering, which is required to support AlwaysOn Availability Groups (configured in a later process). This script does not require the variable block defined earlier.Add-WindowsFeature Failover-Clustering -IncludeManagementToolsValidationTo verify that this command worked, log in to the server and then run the following Windows PowerShell command. It should return the value True.((Get-WindowsFeature | where {$_.Name -eq "Failover-Clustering" -and $_.InstallState -eq "Installed"}) -ne $NULL)Install SQL ServerThis on-box script installs the SQL Server engine and opens the required firewall ports. You are prompted for the passwords of the service accounts (DB1_SQL_Agent and DB1_SQL_Engine), the password that you want to use for the sa account, the domain administrator user name to make a SQL Server system administrator, and the license key for your SQL Server media. Important: Don’t forget to copy your installation media to the directories listed earlier in this section before you run this script.Run the following script in Windows PowerShell on the target machine using the on-box variable block defined earlier in the document.# Script-level variables...$agentAccountUserName = "DB1_SQL_Agent"$engineAccountUserName = "DB1_SQL_Engine"# Get domain admin user...$domainAdminUser = Read-Host -Prompt "Domain Administrator User Name"# Get the passwords...$agentServicePasswordSecure = Read-Host -AsSecureString -Prompt "Agent Service Account ($agentAccountUserName) Password"$stringMarshal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($agentServicePasswordSecure)$agentServicePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal)$engineServicePasswordSecure = Read-Host -AsSecureString -Prompt "Engine Service Account ($engineAccountUserName) Password"$stringMarshal2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($engineServicePasswordSecure)$engineServicePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal2)$saPasswordSecure = Read-Host -AsSecureString -Prompt "SA Password"$stringMarshal3 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($saPasswordSecure)$saPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal3)# Get the SQL Server license key...$sqlpid = Read-Host -Prompt "SQL Server License Key"# Install SQL Server...D:CD "\SQL Server 2012".\setup.exe ` /Action=Install ` /ENU ` /UpdateEnabled=1 ` /UpdateSource="D:\SQL Server 2012 CU" ` /ErrorReporting=0 ` /Features=SQLEngine,SSMS,ADV_SSMS ` /IndicateProgress ` /InstanceName=MSSQLServer ` /InstanceDir=S:\SQL\ ` /QS ` /SQLSvcAccount=$domainName\$engineAccountUserName ` /SQLSvcPassword=$engineServicePassword ` /SQLSvcStartupType=Automatic ` /AGTSvcAccount=$domainName\$agentAccountUserName ` /AGTSvcPassword=$agentServicePassword ` /AGTSvcStartupType=Automatic ` /SecurityMode=SQL ` /SAPwd=$saPassword ` /SQLSysAdminAccounts=$domainName\$domainAdminUser ` /TCPEnabled=1 ` /PID="$sqlpid" ` /IACCEPTSQLSERVERLICENSETERMS# Open firewall ports...netsh advfirewall firewall add rule name="SQL Server inbound on TCP 1433" dir=in action=allow protocol=TCP localport=1433 profile=domainnetsh advfirewall firewall add rule name="SQL Server Mirroring inbound on TCP 5022" dir=in action=allow protocol=TCP localport=5022 profile=domainValidationFollow these steps to verify that this command worked:Check the services. Log in to the server, open Services, and then in the right-hand list view, verify that SQL Server (MSSQLSERVER) exists, is running, is set to start up automatically, and is running as the DB1_SQL_Engine account.Verify that SQL Server Agent (MSSQLSERVER) exists, is running, is set to start up automatically, and is running at the DB1_SQL_Agent account.Check the log. Log in to the server, open the summary.txt file (found at C:\Program Files\Microsoft SQL Server\110\Setup Bootstrap\Log), and then verify that the Final result is Passed and the Exit code (Decimal) is 0.Check the firewall. Log in to the server, open the Windows Firewall control panel, and then click Advanced settings.In the Windows Firewall with Advanced Security window, in the left-hand tree view, click Inbound Rules.Verify that “SQL Server inbound on TCP 1433” exists, is set for the Domain profile, and is enabled. Verify that the local port is 1433.Verify that “SQL Server Mirroring inbound on TCP 5022” exists, is set for the Domain profile, and is enabled. Verify that the local port is 5022.Second SQL Server InstanceTo install the second instance of SQL Server that is required for this infrastructure, repeat all of the steps for installing the first instance of SQL Server, but replace the text DB1 with DB2 (including in the validation steps). To Overview of the deployment stepsStep 4: Configure SQL Server PowerPivot ServersIn this section we will install the Analysis Services SharePoint mode instances (BiPaper-PP1, BiPaper-PP2) to support loading PowerPivot models stored in Excel workbooks. As with all of the other server roles in this document, we will configure two of these servers to provide high availability. Additionally, SharePoint will use both of the servers to load models so having more than one server will increase your system’s performance.Note: Although we are only installing two servers during this step, you can use more than two servers if you want to improve performance.At the end of this section, you will have an environment that looks like the following:First PowerPivot ServerServer Name – BIPaper-PP1Storage Account – <your globally unique name>Domain/Forest Name – BIPaper.localNetwork Subnet – DBNetAvailability Set – PPAvailabilitySetSQL Server PowerPivot installationRole – SharePoint Existing FarmInstance Name - PowerPivotAnalysis Services Engine Account – BIPaper\PP1_PowerPivotAnalysis Services Startup Mode – AutomaticAnalysis Services Administrator AccountsDomain Administrator AccountBIPaper\SP_FarmBIPaper\SQL_ReportingListening on static port 2383Inbound TCP ports 2382 and 2383 open in firewall for domain networksSecond PowerPivot ServerServer Name – BIPaper-PP2Storage Account – <your globally unique name>Domain/Forest Name – BIPaper.localNetwork Subnet – DBNetAvailability Set – PPAvailabilitySetSQL Server PowerPivot installationRole – SharePoint Existing FarmInstance Name - PowerPivotAnalysis Services Engine Account – BIPaper\PP2_PowerPivotAnalysis Services Startup Mode – AutomaticAnalysis Services Administrator AccountsDomain Administrator AccountBIPaper\SP_FarmBIPaper\SQL_ReportingListening on static port 2383Inbound TCP ports 2382 and 2383 open in firewall for domain networksIf you feel comfortable creating this environment on your own, you can do so and then skip to the “Configure First SharePoint Application/Central Administration Server” section. Important: This step requires installation media for SQL Server 2012 SP1 and at least SQL Server 2012 SP1 CU4. Place the information in the following directories on the VM:D:\SQL Server 2012\ – This should be the contents of the SQL Server installation media (use the media with SP1 slipstreamed). Do not just put the .iso file in this directory—it needs to be the contents of the media extracted.D:\SQL Server 2012 CU\ – This should be the .exe file that you would run to apply the CU. The CUs are delivered as executable .zip files, the contents of which are what we are looking for in this directory.Tip: When we configured this environment for the first time, we loaded all of the bits on a share on the first domain controller. Then when we needed to install software, we copied the bits to the local D:\ drive from the share.First PowerPivot ServerThe PowerPivot servers that we create in this section will be added to SharePoint in the next section where we configure the farm. As with all of the virtual machines we will be creating, the first step is a Windows Azure PowerShell command that runs off-box and creates the machine itself. The remaining steps will be Windows PowerShell commands that run while you are logged into the VM.Provision VMThis is the only off-box task within the scope of creating the first PowerPivot server. All other scripts run in a remote desktop session on the machine. The script consists of the following elements:Variable Block – This section gathers information (in addition to the standard variable block you provide as outlined earlier in the document).VM Creation – This section (starting with the comment “Creating the virtual machine…”) consists of the following Windows Azure commands:New-AzureVMConfig – This command begins the definition of the virtual machine. It sets the name, size, image, .vhd location and label, and availability set.Add-AzureProvisioningConfig – This command determines how Windows Azure should provision the VM defined in the last command. It tells Windows Azure that this will be a Windows machine, that automatic updates should be disabled (you can turn this back on if you want), that there should not be endpoints for RDP or Remote Windows PowerShell, and what the administrator user and password should be. Additionally, this command provides the information necessary to automatically join the machine to our domain.Set-AzureSubnet – This command defines what subnet the virtual machine should be deployed into.New-AzureVM – This command creates the virtual machine that was defined in the earlier commands. In addition to the information gathered from the earlier commands, it defines the cloud service that should be used. The script loops until creation of the VM is complete and writes a status to the screen every 15 seconds.To create the first PowerPivot server, run the following Windows Azure PowerShell command (use the variable/subscription block with the storage account defined).# Get the name for the VM...$vmName = "BIPaper-PP1"# Get the admin user name for the VM...$vmAdminUserName = Read-Host -Prompt "Server Administrator User Name"# Ask for the password that should be used for the server and convert it to a format usable by the commands...$vmAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Server Administrator Password"$stringMarshal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($vmAdminPasswordSecure)$vmAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal)# Get the domain admin user name...$domainAdminUserName = Read-Host -Prompt "Domain Administrator User Name"# Ask for the domain admin password and convert it to a format usable by the commands...$domainAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Domain Administrator Password"$stringMarshal2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($domainAdminPasswordSecure)$domainAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal2)# Get the name of the VM Image to use...$vmImageName = (Get-AzureVMImage | Where { $_.Category -eq "Microsoft Windows Server Group" -and $_.Label -like "Windows Server 2012 Datacenter*" } | Sort-Object PublishedDate -Descending | SELECT ImageName)[0].ImageName# Set the location of the .vhd files...$storageAccountContainer = "https://" + $storageAccountName + ".blob.core.vhds/"$vmVHDLocation = $storageAccountContainer + $vmName + ".vhd"# Create the virtual machine...Write-Host "Creating the VM..."New-AzureVMConfig ` -Name $vmName ` -InstanceSize ExtraLarge ` -ImageName $vmImageName ` -MediaLocation $vmVHDLocation ` -DiskLabel "OS" ` -AvailabilitySetName "PPAvailabilitySet" | Add-AzureProvisioningConfig ` -WindowsDomain ` -DisableAutomaticUpdates ` -DisableWinRMHttps ` -NoRDPEndpoint ` -Domain $domainName ` -JoinDomain $domainNameFQ ` -DomainPassword $domainAdminPassword ` -DomainUserName $domainAdminUserName ` -AdminUsername $vmAdminUserName ` -Password $vmAdminPassword | Set-AzureSubnet ` -SubnetNames "DBNet" | New-AzureVM ` -ServiceName $cloudServiceName# Loop until Satus = ReadyRole...Write-Host "`tWaiting for Provisioning to Complete..."$VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceNameWhile ($VMStatus.InstanceStatus -ne "ReadyRole"){ write-host "`t`tWaiting...Current Status = " $VMStatus.InstanceStatus Start-Sleep -Seconds 15 $VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceName}ValidationThere are two ways to verify that the virtual machine was created:Portal – In the Windows Azure Management Portal, click Virtual Machines and then verify that the virtual machine exists (you might need to refresh the page).PowerShell – Run the following Windows PowerShell command (include the same variable script block used to run the command above). It should return the value True.((Get-AzureVM -name "BIPaper-PP1" -ServiceName $cloudServiceName) -ne $NULL)Install SQL ServerThis on-box script installs the Analysis Services PowerPivot instance and opens the required firewall ports. You are prompted for the password for the service account (PP1_PowerPivot), the domain administrator user name to make an Analysis Services administrator, and the license key for your SQL Server media. Important: Don’t forget to copy your installation media to the directories listed earlier in this section before you run this script.Run the following script in Windows PowerShell on the target machine using the on-box variable block defined earlier in the document.# Script-level variables...$engineAccountUserName = "PP1_PowerPivot"# Get domain admin user...$domainAdminUser = Read-Host -Prompt "Domain Administrator User Name"# Get the passwords...$engineServicePasswordSecure = Read-Host -AsSecureString -Prompt "PowerPivot Service Account ($engineAccountUserName) Password"$stringMarshal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($engineServicePasswordSecure)$engineServicePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal)# Get the SQL Server license key...$sqlpid = Read-Host -Prompt "SQL Server License Key"# Install .NET 3.5...Add-WindowsFeature -Name "NET-Framework-Core"# Install SQL Server...D:CD "\SQL Server 2012".\setup.exe ` /Action=Install ` /ENU ` /UpdateEnabled=1 ` /UpdateSource="D:\SQL Server 2012 CU" ` /ErrorReporting=0 ` /IndicateProgress ` /InstanceName=POWERPIVOT ` /QS ` /SQMReporting=0 ` /ASSvcAccount=$env:USERDOMAIN\$engineAccountUserName ` /ASSvcPassword=$engineServicePassword ` /ASSvcStartupType=Automatic ` /ASSysAdminAccounts=$env:USERDOMAIN\$domainAdminUser, $env:USERDOMAIN\SP_Farm, $env:USERDOMAIN\SQL_Reporting ` /ROLE=SPI_AS_ExistingFarm ` /PID="$sqlpid" ` /IAcceptSQLServerLicenseTerms# Set the Analysis Services Port to 2383...Stop-Service "MSOLAP`$POWERPIVOT"[xml]$configAS = Get-Content "C:\Program Files\Microsoft SQL Server\MSAS11.POWERPIVOT\OLAP\Config\msmdsrv.ini"$configAS.ConfigurationSettings.Port = "2383"$configAS.Save("C:\Program Files\Microsoft SQL Server\MSAS11.POWERPIVOT\OLAP\Config\msmdsrv.ini")Start-Service "MSOLAP`$POWERPIVOT"# Open the Firewall...netsh advfirewall firewall add rule name="Analysis Services inbound on TCP 2383" dir=in action=allow protocol=TCP localport=2383 profile=domainnetsh advfirewall firewall add rule name="SQL Browser inbound on TCP 2382" dir=in action=allow protocol=TCP localport=2382 profile=domainValidationFollow these steps to validate that this command worked:Check the services. Log in to the server, start Services, and then in the right-hand list view, verify that “SQL Server Analysis Services (POWERPIVOT)” exists, is running, is set to start up automatically, and is running as the PP1_PowerPivot account.Verify that “SQL Server Browser” exists, is running, and is set to start up automatically.Check the log. Log in to the server, open the summary.txt file (found at C:\Program Files\Microsoft SQL Server\110\Setup Bootstrap\Log), and then verify that the Final result is Passed and the Exit code (Decimal) is 0.Check the configuration file. Log in to the server, and then open the msmdsrv.ini file (found at C:\Program Files\Microsoft SQL Server\MSAS11.POWERPIVOT\OLAP\Config).Find the ConfigurationSettings\Port node, and then verify that the value of the port node is set to 2383.Check the firewall. Log in to the server, open the Windows Firewall control panel, and then click Advanced settings.In the left-hand tree view of the Windows Firewall with Advanced Security window, click Inbound Rules.Verify that “Analysis Services inbound on TCP 2383” exists, is set for the Domain profile, and is enabled. Verify that the local port is 2383.Verify that “SQL Browser inbound on TCP 2382” exists, is set for the Domain profile, and is enabled. Verify that the local port is 2382.Second PowerPivot ServerTo install the second PowerPivot server that is required for this infrastructure, repeat all of the steps for installing the first PowerPivot server, but replace the text PP1 with PP2 (including in the validation steps). To Overview of the deployment stepsStep 5: Deploy the first SharePoint Application/Central Administration ServerIn this section we will create the SharePoint farm. In this step, we will only configure the first of the SharePoint application-tier servers (BiPapr-App1). The second server (for high availability) will be configured later in the document.This section is divided into two parts—image creation and installation. In the image creation part we will create a sysprepped image that will be used to create all of the SharePoint servers that we deploy. This will save time and also ensure that all of your servers are configured identically.SharePoint ImageThe SharePoint image that we will be creating will be stored as a VM image in Windows Azure that can be used to create additional VMs. If you have used sysprepped VMs in your data center, this process should be fairly familiar to you.When this step is complete, we will have the following:SharePoint Image in Windows AzureImage Name – BIPaper-SharePointStorage Account – <your globally unique name>Software:SharePoint 2013 PrerequisitesSharePoint 2013 Enterprise (with desired patches)SQL Server 2012 RS Add-In (SP1)PowerPivot Add-In (2012 SP1 version)If you feel comfortable creating and capturing this image on your own, you can do so and then skip to the “First SharePoint Server” step in this section.Note: This step requires installation media for SharePoint 2013, the PowerPivot Add-In (SQL Server 2012 SP1), and the Reporting Services Add-In (SQL Server 2012 SP1). Place the information in the following directories on the VM:D:\SharePoint 2013\ - This should be the contents of the SharePoint installation media. Do not just put the .iso file in this directory – it needs to be the contents of the media extracted.D:\spPowerPivot.msi – This should be the .msi file for installing the PowerPivot Add-In (SQL Server 2012 SP1).D:\rsSharePoint.msi – This should be the .msi file for installing the Reporting Services Add-In (SQL Server 2012 SP1).Important: If you do not use the SQL Server 2012 SP1 versions of these add-ins you will run into version compatibility issues.Provision VMThis is the first of two off-box tasks within the scope of creating the SharePoint image. The script consists of the following elements:Variable Block: This section gathers information (in addition to the standard variable block you provide as outlined earlier in the document).VM Creation: This section (starting with the comment “Creating the virtual machine…”) consists of the following Windows Azure commands:New-AzureVMConfig – This command begins the definition of the virtual machine. It sets the name, size, image, .vhd location and label, and availability set.Add-AzureProvisioningConfig – This command determines how Windows Azure should provision the VM defined in the last command. It tells Windows Azure that this will be a Windows machine, that automatic updates should be disabled (you can turn this back on if you want), that there should not be endpoints for RDP or Remote Windows PowerShell, and what the administrator user and password should be. Additionally, this command provides the information necessary to automatically join the machine to our domain.Set-AzureSubnet: This command defines what subnet the virtual machine should be deployed into.New-AzureVM: This command does the work of creating the virtual machine that was defined in the earlier commands. In addition to the information gathered from the earlier commands, it defines the cloud service that should be used. The script loops until creation of the VM is complete and writes a status to the screen every 15 seconds.To create the SharePoint image server, run the following Windows Azure PowerShell command (use the variable/subscription block with the storage account defined).# Get the name for the VM...$vmName = "BIPaper-SP"# Get the admin user name for the VM...$vmAdminUserName = Read-Host -Prompt "Server Administrator User Name"# Ask for the password that should be used for the server and convert it to a format usable by the commands...$vmAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Server Administrator Password"$stringMarshal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($vmAdminPasswordSecure)$vmAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal)# Get the domain admin user name...$domainAdminUserName = Read-Host -Prompt "Domain Administrator User Name"# Ask for the domain admin password and convert it to a format usable by the commands...$domainAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Domain Administrator Password"$stringMarshal2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($domainAdminPasswordSecure)$domainAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal2)# Get the name of the VM Image to use...$vmImageName = (Get-AzureVMImage | Where { $_.Category -eq "Microsoft Windows Server Group" -and $_.Label -like "Windows Server 2012 Datacenter*" } | Sort-Object PublishedDate -Descending | SELECT ImageName)[0].ImageName# Set the location of the .vhd files...$storageAccountContainer = "https://" + $storageAccountName + ".blob.core.vhds/"$vmVHDLocation = $storageAccountContainer + $vmName + ".vhd"# Create the virtual machine...Write-Host "Creating the VM..."New-AzureVMConfig ` -Name $vmName ` -InstanceSize ExtraLarge ` -ImageName $vmImageName ` -MediaLocation $vmVHDLocation ` -DiskLabel "OS" ` -AvailabilitySetName "AppAvailabilitySet" | Add-AzureProvisioningConfig ` -WindowsDomain ` -DisableAutomaticUpdates ` -DisableWinRMHttps ` -NoRDPEndpoint ` -Domain $domainName ` -JoinDomain $domainNameFQ ` -DomainPassword $domainAdminPassword ` -DomainUserName $domainAdminUserName ` -AdminUsername $vmAdminUserName ` -Password $vmAdminPassword | Set-AzureSubnet ` -SubnetNames "AppNet" | New-AzureVM ` -ServiceName $cloudServiceName# Loop until Satus = ReadyRole...Write-Host "`tWaiting for Provisioning to Complete..."$VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceNameWhile ($VMStatus.InstanceStatus -ne "ReadyRole"){ write-host "`t`tWaiting...Current Status = " $VMStatus.InstanceStatus Start-Sleep -Seconds 15 $VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceName}ValidationThere are two ways to verify that the virtual machine was created:Portal – In the Windows Azure Management Portal, click Virtual Machines and then verify that the virtual machine exists (you might need to refresh the page).Windows PowerShell – Run the following Windows PowerShell command (include the same variable script block used to run the command above). It should return the value True.((Get-AzureVM -name "BIPaper-SP" -ServiceName $cloudServiceName) -ne $NULL)Install SharePoint PrerequisitesThese on-box steps install the SharePoint prerequisites on the machine that will be used as the image. This process will require you to restart the server twice, manually.Important: Don’t forget to copy your installation media to the locations listed earlier in this section before you run this script.Perform the following steps on the target server:Run the following script in Windows PowerShell on the target machine (no variable block is required).D:CD "SharePoint 2013".\prerequisiteinstaller.exe /unattendedWait-Process PrerequisiteInstallerRestart the server.Run the following script in Windows PowerShell on the target machine (no variable block is required).D:CD "SharePoint 2013".\prerequisiteinstaller.exe /unattended /continueWait-Process PrerequisiteInstallerRestart the server.Run the following script in Windows PowerShell on the target machine (no variable block is required).D:CD "SharePoint 2013".\prerequisiteinstaller.exe /unattended /continueWait-Process PrerequisiteInstallerValidationTo verify that the prerequisites were installed properly, log in to the server and then run the SharePoint 2013 Prerequisite Installer (D:\SharePoint 2013\PrerequisiteInstaller.exe). Step through the wizard to verify that all of the options have been installed.Install SharePointThis on-box script installs the SharePoint bits on the target server.Important: Don’t forget to copy your installation media to the locations listed earlier in this section before you run this script.Note: You will need to enter your license key into the file located at D:\SharePoint 2013\Files\SetupFarmSilent\Config.xml. If you do not provide the license key, the automated installation will not work. The key needs to be placed in the PIDKEY node (where the file says Enter Product Key Here) and that node needs to be uncommented.Run the following script in Windows PowerShell on the target machine (no variable block is required).D:CD "SharePoint 2013".\Setup.exe /config Files\SetupFarmSilent\Config.xml # TODO: make sure that you put your license key into this file...Wait-Process SetupValidationTo verify that SharePoint was installed:Log in to the server.In Control Panel, open Programs and Features.Verify that Microsoft SharePoint Server 2013 shows up in the list.Install Add-InsThese on-box steps install the PowerPivot and Reporting Services add-ins on the machine that will be used as the image.Important: Don’t forget to copy your installation media to the locations listed earlier in this section before you run this script.Perform the following steps on the target server:Run the following script in Windows PowerShell on the target machine (no variable block is required; you will need to wait for the installation dialog box to close before you proceed to the next step).D:CD \.\rsSharePoint.msi /passiveRun the following script in Windows PowerShell on the target machine (no variable block is required; you will need to wait for the installation dialog box to close before you proceed to the next step).D:CD\.\spPowerPivot.msi /passiveValidationTo verify that the add-ins were installed:Log in to the server.In Control Panel, open Programs and Features.Verify that Microsoft SQL Server 2012 PowerPivot for SharePoint 2013 shows up in the list.Verify that Microsoft SQL Server 2012 RS Add-in for SharePoint shows up in the list.Install UpdatesBecause the updates that you choose to install are your choice, we will not be providing scripts for installing the updates. For the paper, we chose to install the SharePoint Server 2013 March 2013 CU and the SharePoint Server 2013 April 2013 CU, but the updates that you install are entirely up to you.SysprepThis on-box script prepares the server for being made into a template.Run the following script in Windows PowerShell on the target machine (no variable block is required).C:cd \windows\system32\sysprep.\sysprep /generalize /oobe /shutdownValidationThis script is designed to shut down your machine when the sysprep process has completed. This process can take some time. You can monitor the machine in the Windows Azure Management Portal by watching for the machine to show as Stopped.Capture ImageThis is the second of two off-box tasks within the scope of creating the SharePoint image. The script consists of the following elements:Variable Block – This section gathers information (in addition to the standard variable block you provide as outlined earlier in the document).Image Capture – This section (starting with the comment “Save the image…”) contains the command that will capture the image.To finalize the creation of the SharePoint server image, run the following Windows Azure PowerShell command (use the variable/subscription block with the storage account defined).# Variable Block...$vmName = "BIPaper-SP"$newImageName = "BIPaper-SharePoint"$newImageLabel = "BI Paper SharePoint"# Save the image...Save-AzureVMImage ` -Name $vmName ` -NewImageName $newImageName ` -ServiceName $cloudServiceName ` -NewImageLabel $newImageLabelValidationThere are two ways to verify that the virtual machine image was created:Portal – In the Windows Azure Management Portal, click Virtual Machines. In the virtual machines screen, click Images and then verify that the virtual machine image exists (you might need to refresh the page).PowerShell – Run the following Windows PowerShell command (include the same variable script block used to run the command above). It should return the value True.((Get-AzureVMImage -ImageName "BIPaper-SharePoint") -ne $NULL)First SharePoint ServerThe SharePoint server that we will be creating will serve as our first application tier server, and it will also host the Central Administration web application for the farm.Although it would be possible to build this on your own, we suggest that you either use the scripts in this section or provision the VM from the SharePoint image created and then run the PowerPivot for SharePoint 2013 configuration tool to complete the configuration (followed by the Reporting Services installation).Note: This step requires installation media for SQL Server 2012 (to install Reporting Services). Place the information in the following directories on the VM:D:\SQL Server 2012\ – This should be the contents of the SQL Server installation media (use the media with SP1 slipstreamed). Do not just put the .iso file in this directory—it needs to be the contents of the media extracted.D:\SQL Server 2012 CU\ – This should be the .exe file that you would run to apply the CU. The CUs are delivered as executable .zip files, the contents of which are what we are looking for in this directory.Provision VMThis is the only off-box task within the scope of creating the first SharePoint application-tier server. All other scripts are run in a remote desktop session on the machine. The script consists of the following elements:Variable Block – This section gathers information (in addition to the standard variable block you provide as outlined earlier in the document).VM Creation – This section (starting with the comment “Creating the virtual machine…”) consists of the following Windows Azure commands:New-AzureVMConfig – This command begins the definition of the virtual machine. It sets the name, size, image, .vhd location and label, and availability set.Add-AzureProvisioningConfig – This command determines how Windows Azure should provision the VM defined in the last command. It tells Windows Azure that this will be a Windows machine, that automatic updates should be disabled (you can turn this back on if you want), that there should not be endpoints for RDP or Remote Windows PowerShell, and what the administrator user and password should be. Additionally, this command provides the information necessary to automatically join the machine to our domain.Set-AzureSubnet – This command defines what subnet the virtual machine should be deployed into.New-AzureVM – This command does the work of creating the virtual machine that was defined in the earlier commands. In addition to the information gathered from the earlier commands, it defines the cloud service that should be used. The script loops until creation of the VM is complete and writes a status to the screen every 15 seconds.To create the first SharePoint server, run the following Windows Azure PowerShell command (use the variable/subscription block with the storage account defined).# Get the name for the VM...$vmName = "BIPaper-App1"$vmImageName = "BIPaper-SharePoint"# Get the admin user name for the VM...$vmAdminUserName = Read-Host -Prompt "Server Administrator User Name"# Ask for the password that should be used for the server and convert it to a format usable by the commands...$vmAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Server Administrator Password"$stringMarshal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($vmAdminPasswordSecure)$vmAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal)# Get the domain admin user name...$domainAdminUserName = Read-Host -Prompt "Domain Administrator User Name"# Ask for the domain admin password and convert it to a format usable by the commands...$domainAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Domain Administrator Password"$stringMarshal2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($domainAdminPasswordSecure)$domainAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal2)# Set the location of the .vhd files...$storageAccountContainer = "https://" + $storageAccountName + ".blob.core.vhds/"$vmVHDLocation = $storageAccountContainer + $vmName + ".vhd"# Create the virtual machine...Write-Host "Creating the VM..."New-AzureVMConfig ` -Name $vmName ` -InstanceSize ExtraLarge ` -ImageName $vmImageName ` -MediaLocation $vmVHDLocation ` -DiskLabel "OS" ` -AvailabilitySetName "AppAvailabilitySet" | Add-AzureProvisioningConfig ` -WindowsDomain ` -DisableAutomaticUpdates ` -DisableWinRMHttps ` -NoRDPEndpoint ` -Domain $domainName ` -JoinDomain $domainNameFQ ` -DomainPassword $domainAdminPassword ` -DomainUserName $domainAdminUserName ` -AdminUsername $vmAdminUserName ` -Password $vmAdminPassword | Set-AzureSubnet ` -SubnetNames "AppNet" | New-AzureVM ` -ServiceName $cloudServiceName# Loop until Satus = ReadyRole...Write-Host "`tWaiting for Provisioning to Complete..."$VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceNameWhile ($VMStatus.InstanceStatus -ne "ReadyRole"){ write-host "`t`tWaiting...Current Status = " $VMStatus.InstanceStatus Start-Sleep -Seconds 15 $VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceName}ValidationThere are two ways to verify that the virtual machine was created:Portal – In the Windows Azure Management Portal, click Virtual Machines and then verify that the virtual machine exists (you might need to refresh the page).Windows PowerShell – Run the following Windows PowerShell command (include the same variable script block used to run the command above). It should return the value True.((Get-AzureVM -name "BIPaper-App1" -ServiceName $cloudServiceName) -ne $NULL)Create New FarmThis on-box script creates the SharePoint farm. You are prompted for the password for the SP_Farm service account and for the password that you want to use for the farm passphrase. The script installs the databases onto the server BIPaper-DB1 and it uses the SP_Farm service account—if you have changed either of these values while creating this environment you will need to adjust the variable block of the script.Note: These scripts perform the exact same actions that would be performed by running the PowerPivot for SharePoint 2013 configuration tool. If you are not comfortable running the scripts in this format, you can log in to the server and then run the PowerPivot for SharePoint 2013 configuration tool to create the farm—it will do exactly the same thing that we do here. If you choose to build the farm through the configuration tool, skip to the “Configure Alternate Access Mappings” script.Note: Individual scripts are not verified in this section. The entire section is verified after the “Configure Excel Services” section.Run the following script in Windows PowerShell on the target machine using the on-box variable block defined earlier in the document.# Variable Block...$caPort = 8080# Get passwords...$servicePasswordSecure = Read-Host -AsSecureString -Prompt "Service Account Password ($farmServiceAccount)"$farmPassphraseSecure = Read-Host -AsSecureString -Prompt "Farm Passphrase"$stringMarshal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($servicePasswordSecure)$servicePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal)$stringMarshal2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($farmPassphraseSecure)$farmPassphrase = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal2)# Configure farm...C:CD "\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\BIN\".\psconfig.exe ` -cmd configdb -create -server "$dbServer" -database "SharePoint_Config" -user "$domainName\$farmServiceAccount" -password $servicePassword -passphrase $farmPassphrase -admincontentdatabase "SharePoint_Admin" ` -cmd helpcollections -installall ` -cmd secureresources ` -cmd services -install ` -cmd installfeatures ` -cmd adminvs -provision -port $caPort -windowsauthprovider onlyusentlm ` -cmd applicationcontent -install ` -cmd quietAdd PowerPivot SolutionsTo add the PowerPivot solution to the farm, run the following script on the target server (no variable block is required).Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"Add-SPSolution -LiteralPath 'C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\powerpivotfarmsolution.wsp'Add-SPSolution -LiteralPath 'C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\PowerPivotFarm14Solution.wsp'Add-SPSolution -LiteralPath 'C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\powerpivotwebapplicationsolution.wsp'DeployFarmSolution $falseDeployWebAppSolutionToCentralAdmin $falseImportant: Close and reopen the PowerShell window before running the next script. The PowerPivot cmdlets were installed with this step and the PowerShell environment cannot use the PowerPivot cmdlets until the PowerShell window is restarted.Install PowerPivot FeaturesTo install the PowerPivot feature, run the following script on the target server (no variable block is required).Add-PSSnapin Microsoft.SharePoint.PowerShellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"Install-SPFeature -path PowerPivotFarm -ForceInstall-SPFeature -path PowerPivotFarm -Force -CompatibilityLevel 14Install-SPFeature -path PowerPivotCA -ForceInstallSiteCollectionFeaturesConfigure Service InstanceTo configure the PowerPivot service instance, run the following script on the target server (no variable block is required).Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"New-PowerPivotSystemServiceInstance -Provision:$trueCreate PowerPivot Service ApplicationTo create the PowerPivot Service application, run the following script on the target server using the on-box variable block defined earlier in the document.Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"New-PowerPivotServiceApplication ` -ServiceApplicationName 'Default PowerPivot Service Application' ` -DatabaseServerName $dbServer ` -DatabaseName 'DefaultPowerPivotServiceApplicationDB' ` -AddToDefaultProxyGroup:$trueSet-PowerPivotSystemService -Confirm:$falseCreate Default Web ApplicationTo create the default SharePoint web application, run the following script on the target server using the on-box variable block defined earlier in the document.Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"$serviceAccountPasswordSecure = Read-Host -AsSecureString -Prompt "Service Account Password ($farmServiceAccount)"$stringMarshal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($serviceAccountPasswordSecure)$serviceAccountPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal)CreateWebApplication "SharePoint - 80" "http://$cloudServiceName." "Default Application Pool" "$domainName\$farmServiceAccount" $serviceAccountPassword $dbServer "DefaultWebApplicationDB"Deploy Web Application SolutionTo deploy the web application solution, run the following script on the target server using the on-box variable block defined earlier in the document.Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"DeployWebAppSolution "http://$cloudServiceName." 2047 $falseCreate Site CollectionTo create the site collection, run the following script on the target server using the on-box variable block defined earlier in the document.# Variable block...$domainAdminAccount = Read-Host -Prompt "Domain Administrator Account Name"Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"New-SPSite ` -Url "http://$cloudServiceName." ` -OwnerAlias "$domainName\$farmServiceAccount" ` -SecondaryOwnerAlias "$domainName\$domainAdminAccount" ` -Template 'PowerPivot#0' ` -Name 'PowerPivot Site'Activate PowerPivot FeatureTo active the PowerPivot feature in the site that was just created, run the following script on the target server using the on-box variable block defined earlier in the document.Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"EnableSiteFeatures "http://$cloudServiceName." $trueStart the Claims to Windows Token ServiceTo start the Claims to Windows Token Service on the server, run the following script on the target server (no variable block is required).Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"StartService "Microsoft.SharePoint.Administration.Claims.SPWindowsTokenServiceInstance"Configure Secure Store ServiceTo configure the Secure Store service, run the following script on the target server using the on-box variable block defined earlier in the document (you will be prompted for the farm service account password and for a password that will be used for your secure store master key).# Variable block...$password = Read-Host -AsSecureString -Prompt "Farm Account Password ($farmServiceAccount)"$secureStorePassword = Read-Host -AsSecureString -Prompt "Secure Store Password"Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"StartSecureStoreServiceCreateSecureStoreApplicationService $dbServer "Secure Store Service"CreateSecureStoreApplicationServiceProxy "Secure Store Service" "Secure Store Proxy"UpdateSecureStoreMasterKey "Secure Store Proxy" $secureStorePasswordCreateUnattendedAccountForDataRefresh "http://$cloudServiceName." "PowerPivotUnattendedAccount" "PowerPivot Unattended Account for Data Refresh" "$domainName\$farmServiceAccount" $password Configure Excel ServicesTo configure Excel Services for the farm, run the following script on the target server (no variable block is required). If the server names you used for the PowerPivot servers are different from the default, you will need to change them in this script.# Variable block...$firstPowerPivotServer = "BIPaper-PP1\PowerPivot"$secondPowerPivotServer = "BIPaper-PP2\PowerPivot"Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"StartService "Microsoft.Office.Excel.Server.MossHost.ExcelServerWebServiceInstance"New-SPExcelServiceApplication -name 'ExcelServiceApp1' -Default -ApplicationPool 'SharePoint Web Services System' | Get-SPExcelServiceApplication | Set-SPExcelServiceApplication | iisreset Set-SPExcelFileLocation -ExternalDataAllowed 2 -WorkbookSizeMax 200 -WarnOnDataRefresh:$false -ExcelServiceApplication 'ExcelServiceApp1' -identity 'http://'$excelServiceApp = Get-SPExcelServiceApplication | where {$_.Name -eq "ExcelServiceApp1"}New-SPExcelBIServer -ServerId $firstPowerPivotServer -ExcelServiceApplication $excelServiceAppNew-SPExcelBIServer -ServerId $secondPowerPivotServer -ExcelServiceApplication $excelServiceAppSetECSUsageTracker 'ExcelServiceApp1'Note: In a production environment, you should use separate app pools for Excel Services and Secure Store for security isolation.ValidationTo verify that the SharePoint and PowerPivot configuration worked properly:Log in to the server.Start the PowerPivot for SharePoint 2013 Configuration tool.In the PowerPivot Configuration Tool dialog box, click Configure or Repair PowerPivot for SharePoint, and then click OK.Verify that no tasks appear in the left-hand tree view and that the message “No further action is required. This step is either already verified or configured” is displayed at the bottom of the right-hand side of the window.Configure Alternate Access MappingsTo create the alternate access mappings and self-signed SSL Certificate, run the following script on the target server using the variable block defined earlier in the document (you will be prompted for a password to use for the certificate output file).# Variable block...$certPassword = Read-Host -AsSecureString -Prompt "Certificate Password"Add-PSSnapin Microsoft.SharePoint.Powershell# Create Alternate Access Mapping...New-SPAlternateURL ` -Url "https://$cloudServiceName." ` -WebApplication "http://$cloudServiceName." ` -Zone "Extranet"New-SPAlternateURL ` -Url "http://$env:COMPUTERNAME" ` -WebApplication "http://$cloudServiceName." ` -Zone "Intranet"New-SPExcelFileLocation ` -Address "https://" ` -ExcelServiceApplication "ExcelServiceApp1" ` -IncludeChildren ` -ExternalDataAllowed "DclAndEmbedded" ` -WarnOnDataRefresh:$false# Make a certificate...if ((Test-Path "C:\Temp") -eq $false){ New-Item -Path "C:\Temp" -ItemType directory}cd "\Program Files\Microsoft Office Servers\15.0\Tools".\makecert -sky exchange -r -n "CN=$cloudServiceName." -pe -a sha1 -len 2048 -eku 1.3.6.1.5.5.7.3.1 -ss My -sr LocalMachine$cert = Get-ChildItem cert:\LocalMachine\My | Where {$_.Subject -eq "CN=$cloudServiceName."}Get-ChildItem -Path cert:\LocalMachine\my | where {$_.Subject -eq "CN=$cloudServiceName."} | Export-PfxCertificate -FilePath "C:\Temp\$cloudServiceName..pfx" -Password $certPassword# Create a new binding for the SharePoint site...New-WebBinding -Name "SharePoint - 80" -Protocol "https" -Port 443 -IPAddress "*"# Bind the certificate CD IIS:\SslBindings$cert | new-item 0.0.0.0!443ValidationFollow these steps to validate this task:Verify alternate access mappings. Log in to the server, start SharePoint 2013 Central Administration (you will need to disable IE ESC before this step if you haven’t already done it), and then click Application Management.Click Configure alternate access mappings under Web Applications, and then to the right of alternate Access Mapping Collection, click Show All. Click Change Alternate Access Mapping Collection.In the Select an Alternate Access Mapping Collection dialog box, click SharePoint – 80.Verify that there are three URLs: (<cloudservice> will be your unique cloud service name) (will be different if you gave your SharePoint server a different name) (<cloudservice> will be your unique cloud service name)Verify the Excel Services file location. Log in to the server, start SharePoint 2013 Central Administration, click Application Management, and then under Service Applications, click Manage service applications.Click ExcelServiceApp1 (there will be two listed; click the one that is left-justified), click Trusted File Locations, and then verify that both http:// and https:// are listed.Verify SSL binding. Log in to the server, and then start Internet Information Services (IIS) Manager.In the left-hand tree view, expand the server name, expand Sites, right-click SharePoint – 80, and then click Edit Bindings.In the Site Bindings dialog box, select https and then click Edit. Verify that the SSL certificate is the name of your cloud service’s public URL (<cloudservice>.).Verify the certificate file export. Log in to the server, open Windows Explorer, and then navigate to C:\Temp. Verify that the file <cloudservice>..pfx exists.Install Reporting ServicesThis step is divided into four parts:Install Reporting Services Bits – Installs the SQL Server Reporting Services binaries, but does not do any configuration.Enable Reporting Services – Installs the SQL Server Reporting Services binaries into SharePoint.Create Reporting Services Shared Service Application – Creates the SharePoint shared service application that will allow users to interact with reporting services.Grant Reporting Services permissions on the site content database – Gives the Reporting Services service account rights to access the SharePoint content database for our site collection.Install Reporting Services BitsThis step installs the SQL Server Reporting Services binaries onto the SharePoint application tier. This step needs to be run only on servers that will act as report servers—Web Front End servers do not need to have these binaries installed.Note: This step requires installation media for SQL Server 2012 (to install Reporting Services). Place the information in the following directories on the VM:D:\SQL Server 2012\ – This should be the contents of the SQL Server installation media (use the media with SP1 slipstreamed). Do not just put the .iso file in this directory—it needs to be the contents of the media extracted.D:\SQL Server 2012 CU\ – This should be the .exe file that you would run to apply the CU. The CUs are delivered as executable .zip files, the contents of which are what we are looking for in this directory.To install SQL Server Reporting Services, run the following script on the target server (no variable block is required, but you will be prompted for your SQL Server license key).# Get the SQL Server license key...$sqlpid = Read-Host -Prompt "SQL Server License Key"# Install SQL Server...D:CD "\SQL Server 2012".\setup.exe ` /Action=Install ` /PID="$sqlpid" ` /IACCEPTSQLSERVERLICENSETERMS ` /ENU ` /UpdateEnabled=1 ` /UpdateSource="D:\SQL Server 2012 CU" ` /ErrorReporting=0 ` /Features=RS_SHP ` /IndicateProgress ` /QSYou now need to restart the server.ValidationTo verify that Reporting Services was installed properly:Log in to the server.Open Windows Explorer.Navigate to “C:\Program Files\Microsoft SQL Server\110\Setup Bootstrap\Log” and open the “Summary.txt” file.Verify that the Final result is Passed but reboot required, see logs for details.Verify that the Exit code (Decimal) is 3010.Enable Reporting ServicesTo enable the Reporting Services bits within SharePoint, run the following script on the target server (no variable block is required).Add-PSSnapin Microsoft.SharePoint.Powershell$RS = Get-SPServiceInstance -Server $env:COMPUTERNAME | Where {$_.TypeName -eq "SQL Server Reporting Services Service"}if ($RS -eq $NULL){ Install-SPRSService Install-SPRSServiceProxy}$RS = Get-SPServiceInstance -Server $env:COMPUTERNAME | Where {$_.TypeName -eq "SQL Server Reporting Services Service"}Start-SPServiceInstance -Identity $RS.Id.ToString()ValidationTo verify that Reporting Services was successfully enabled:Log in to the server.Open Windows PowerShell.Run the command Add-PSSnapin Microsoft.SharePoint.Powershell to import the SharePoint PowerShell cmdlets.Run the following script (it should return the value True).((Get-SPServiceInstance | where {$_.TypeName -eq "SQL Server Reporting Services Service"}).Status -eq "Online")Create Reporting Services Shared Service ApplicationTo create the Reporting Services Shared Service Application, run the following script on the target server using the variable block defined earlier in the document (you will be prompted for the password for the Reporting Services service account).Add-PSSnapin Microsoft.SharePoint.Powershell# Get the Reporting Services Account Credentials...$cred = Get-Credential "$domainName\$reportingServiceAccount" # TODO: Type password when prompted...# Create a managed service account...New-SPManagedAccount -Credential $cred# Create a new application pool for Reporting Services...New-SPServiceApplicationPool -Name "Reporting Services" -Account "$domainName\$reportingServiceAccount"$appPool = Get-SPServiceApplicationPool "Reporting Services"# Create the Reporting Services Service Application...$rsService = New-SPRSServiceApplication -Name "Reporting Services Application" -ApplicationPool $appPool -DatabaseName "Reporting_Services_Application" -DatabaseServer "$dbServer"# Create the Reporting Services Service Application Proxy...$rsServiceProxy = New-SPRSServiceApplicationProxy -Name "Reporting Services Application Proxy" -ServiceApplication $rsService# Associate the Reporting Services Service Application Proxy with the default web site...Get-SPServiceApplicationProxyGroup -default | Add-SPServiceApplicationProxyGroupMember -Member $rsServiceProxyValidationTo verify that the Reporting Services application was successfully created:Log in to the server.Open Windows PowerShell.Run the command Add-PSSnapin Microsoft.SharePoint.Powershell to import the SharePoint PowerShell cmdlets.Run the following script (it should return the value True).((Get-SPServiceApplication | where {$_.DisplayName -eq "Reporting Services Application" -and $_.TypeName -eq "SQL Server Reporting Services Service Application"}) -ne $NULL)Grant Reporting Services permissionsTo grant the Reporting Services application permissions on the content database that was created, run the following script on the target server using the variable block defined earlier in the document.Add-PSSnapin Microsoft.SharePoint.Powershell$appPool = Get-SPServiceApplicationPool "Reporting Services"$webApp = Get-SPWebApplication "http://$cloudServiceName."$appPoolAccountName = $appPool.ProcessAccount.LookupName()$webApp.GrantAccessToProcessIdentity($appPoolAccountName)ValidationTo verify that the permissions have been set on the content database:Log in to the database server.Open SQL Server Management Studio, and then connect to the database server.In the left-hand tree view, expand the Security node.In the left-hand tree view, expand the Logins node.In the left-hand tree view, double-click BIPaper\SQL_Reporting (or the name of the Reporting Services service account if you changed it).In the Login Properties dialog box, click User Mapping, and then verify that rights have been granted to the DefaultWebApplicationDB database (it should be a member of the SPDataAccess role).Section ValidationAt this point, you have a fully functional SharePoint site with the BI features enabled. You can access the site only if you are logged into a server on the virtual network (we haven’t defined any public Web Front Ends yet). If you want to take the site out for a test, log in to one of the servers in the virtual network, open Internet Explorer, and then navigate to (or the name that you gave to the server if you did not use the default naming).Note: There is a chance that the first time you access the site you will be presented with an unhandled exception. If this happens, refresh the page and everything should be fine. To Overview of the deployment stepsStep 6: Configure AlwaysOn Availability GroupsEven though we have built out seven servers, only two out of the four tiers that we have deployed have high availability (HA) configured:Domain controllers – highly availableDatabase servers – HA ready (need cluster)PowerPivot servers – highly availableSharePoint App-Tier – no HA (single server)In this section, we will go through the steps of configuring HA for our database servers and letting SharePoint know how to take advantage of that configuration.At the end of this section we will have accomplished the following:Windows Failover ClusterCluster name – BIPaper-DBCluster nodesBIPaper-DB1BIPaper-DB2QuorumType – Node and File Share MajorityQuorum file share - \\BIPaper-DC2\QuorumAlwaysOn Availability Groups enabled on database servers (BIPaper-DB1 and BIPaper-DB2)Availability GroupName – SharePointPrimary server – BIPaper-DB1Secondary server – BIPaper-DB2Replicas are not readableDatabases – all user databases created during SharePoint configurationNote: Because listeners are not currently supported in Windows Azure Virtual Machines, we will use the database mirroring-style connection strings for SharePoint (we will set the FailoverPartner property for the secondary replica). This is why our replicas cannot be readable.If you feel comfortable creating this environment on your own, you can do so and then skip to the “Deploy SharePoint Web Front End Servers” section.Create ClusterThe following script verifys and creates a Windows failover cluster. It performs three tasks (Verify Cluster, Create Cluster, and Set Quorum). It should be run from the primary database server (BIPaper-DB1, if you haven’t changed it) using the on-box variable block defined earlier in the document.# Validate the Cluster Nodes...Test-Cluster -Node $dbServer, $dbServer2# Create the Cluster...New-Cluster -Name $clusterName -Node $dbServer, $dbServer2# Set the cluster quorum...Set-ClusterQuorum -NodeAndFileShareMajority "\\$quorumServerName\Quorum"ValidationThere are two parts to validating this step: the validation report and Failover Cluster Manager.Validation ReportIn the output of the Windows PowerShell command, find “Test report file path”.If you don’t have the path, check the AppData\Local\Temp\2\ path under the user that ran the Windows PowerShell script (the file should be a .mht file, the file name should start with “Validation Report”, and the file should contain the date and time that validation was run).Open the file. Both nodes should show up in the report as Validated and your results should either be Success or Warning.Failover Cluster ManagerLog into the target machine.Open Failover Cluster Manager.In the left-hand tree view, click the name of the cluster.In the center content, verify that the Quorum Configuration is Node and File Share Majority (\\BIPaper-DC2\Quorum) (or the name of the quorum server you used).In the left-hand tree view, expand the name of the cluster.In the left-hand tree view, click Nodes. In the center content well, you should see both of your database servers listed as cluster nodes.Enable AlwaysOn Availability GroupsThe following scripts enable the AlwaysOn Availability Groups feature for the SQL Server instances. There is one script for each database server.These scripts assume that you are using the default service accounts created in this paper. If you are not, you will need to adjust the service account variable at the top of each script.Note: This process restarts SQL Server and SQL Server Agent on the target machine.To run these scripts, you will need to set your execution policy to something other than the default (for this paper, we used RemoteSigned).To enable AlwaysOn Availability Groups on your first database server, run the following script on the first database server (this script does not require the variable block defined earlier in the paper).# Variable Block...$otherServiceAccount = "DB2_SQL_Engine"Import-Module "sqlps" -DisableNameChecking# Enable the Feature...$computerName = $env:COMPUTERNAMEEnable-SqlAlwaysOn -Path SQLSERVER:\SQL\$computerName\Default -ForceStart-Service -Name "SQL Server Agent (MSSQLSERVER)"# Enable the Endpoint...$endpoint = New-SqlHadrEndpoint MirrorEndpoint -Port 5022 -Path SQLSERVER:\SQL\$computerName\DefaultSet-SqlHadrEndpoint -InputObject $endpoint -State "Started"# Grant Permissions...Invoke-SqlCmd -Query "CREATE LOGIN [$env:USERDOMAIN\$otherServiceAccount] FROM WINDOWS" -ServerInstance $computerNameInvoke-SqlCmd -Query "GRANT CONNECT ON ENDPOINT::[MirrorEndpoint] TO [$env:USERDOMAIN\$otherServiceAccount]" -ServerInstance $computerNameTo enable AlwaysOn Availability Groups on your second database server, run the following script on the second database server (this script does not require the variable block defined earlier in the paper).# Variable Block...$otherServiceAccount = "DB1_SQL_Engine"Import-Module "sqlps" -DisableNameChecking# Enable the Feature...$computerName = $env:COMPUTERNAMEEnable-SqlAlwaysOn -Path SQLSERVER:\SQL\$computerName\Default -ForceStart-Service -Name "SQL Server Agent (MSSQLSERVER)"# Enable the Endpoint...$endpoint = New-SqlHadrEndpoint MirrorEndpoint -Port 5022 -Path SQLSERVER:\SQL\$computerName\DefaultSet-SqlHadrEndpoint -InputObject $endpoint -State "Started"# Grant Permissions...Invoke-SqlCmd -Query "CREATE LOGIN [$env:USERDOMAIN\$otherServiceAccount] FROM WINDOWS" -ServerInstance $computerNameInvoke-SqlCmd -Query "GRANT CONNECT ON ENDPOINT::[MirrorEndpoint] TO [$env:USERDOMAIN\$otherServiceAccount]" -ServerInstance $computerNameValidationPerform these validation steps on each database server:Log in to the server.Start SQL Server Configuration Manager. In the left-hand tree view, click SQL Server Services.In the right-hand list view, double-click SQL Server (MSSQLSERVER). In the Properties dialog box, click AlwaysOn High Availability, and then verify that the cluster name is populated and the Enable AlwaysOn Availability Groups check box is selected.Start SQL Server Management Studio, and then connect to the local server instance.In the left-hand tree view, expand Server Objects, expand Endpoints, and then expand Database Mirroring.Verify that the endpoint MirrorEndpoint exists.In the left-hand tree view, expand Security, expand Logins, and then double-click the name of the service account that is running the other database server.In the Login Properties dialog box, click Securables, click MirrorEndpoint, and then verify that Grant permissions have been granted for Connect.Create Availability GroupThis script configures the availability group between the two database servers. It performs the following tasks:Sets the appropriate recovery model (full) for WSS_Logging databasePerforms full and log backups of each database on the primary serverRestores each database and log backup onto the secondary serverCreates the availability group and joins the secondary server and databases to itSynchronizes logins to secondary serverTo perform these tasks, run the following script on the primary database server using the on-box variable block defined earlier in this document.Import-Module "sqlps" -DisableNameCheckingSQLServer:CD "\sql\$dbServer\default\databases"# Change WSS_Logging to full recovery model...Invoke-Sqlcmd -Query "ALTER DATABASE [WSS_Logging] SET RECOVERY FULL WITH NO_WAIT" -ServerInstance $dbServer# Backup Databases and Logs...ls | foreach-object { Backup-SqlDatabase -Database $_.name -ServerInstance $dbServer -BackupAction Database -BackupFile ("\\$quorumServerName\quorum\" + $_.name.ToString() + ".bak") -CompressionOption On }ls | foreach-object { Backup-SqlDatabase -Database $_.name -ServerInstance $dbServer -BackupAction Log -BackupFile ("\\$quorumServerName\quorum\" + $_.name + ".log") -CompressionOption On }# Restore Databases and Logs...ls | foreach-object { Restore-SqlDatabase -Database $_.name -ServerInstance $dbServer2 -BackupFile ("\\$quorumServerName\quorum\" + $_.name + ".bak") -NoRecovery -RestoreAction Database }ls | foreach-object { Restore-SqlDatabase -Database $_.name -ServerInstance $dbServer2 -BackupFile ("\\$quorumServerName\quorum\" + $_.name + ".log") -NoRecovery -RestoreAction Log }# Create primary replica template...$primaryReplica = New-SqlAvailabilityReplica -AvailabilityMode "SynchronousCommit" -EndpointUrl "TCP://$dbServer`:5022" -FailoverMode "Automatic" -Name $dbServer -AsTemplate -Version 11# Create secondary replica template...$secondaryReplica = New-SqlAvailabilityReplica -AvailabilityMode "SynchronousCommit" -EndpointUrl "TCP://$dbServer2`:5022" -FailoverMode "Automatic" -Name $dbServer2 -AsTemplate -Version 11# Create Availability Group...New-SqlAvailabilityGroup -Name "SharePoint" -Path "SQLSERVER:\SQL\$dbServer\Default" -AvailabilityReplica @($primaryReplica, $secondaryReplica)ls | foreach-object { Add-SQLAvailabilityDatabase -Path "SQLSERVER:\SQL\$dbServer\Default\AvailabilityGroups\SharePoint" -Database $_.name }# Join Secondary to Availability Group...Join-SqlAvailabilityGroup -Path "SQLSERVER:\SQL\$dbServer2\Default" -Name "SharePoint"# Join Secondary Databases to Availability Group...ls | foreach-object { Add-SQLAvailabilityDatabase -Path "SQLSERVER:\SQL\$dbServer2\Default\AvailabilityGroups\SharePoint" -Database $_.name }# Synchronize Logins...Invoke-Sqlcmd -Query "CREATE LOGIN [$domainName\$farmServiceAccount] FROM WINDOWS WITH DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english]" -ServerInstance $dbServer2Invoke-Sqlcmd -Query "ALTER SERVER ROLE [securityadmin] ADD MEMBER [$domainName\$farmServiceAccount]" -ServerInstance $dbServer2Invoke-Sqlcmd -Query "ALTER SERVER ROLE [dbcreator] ADD MEMBER [$domainName\$farmServiceAccount]" -ServerInstance $dbServer2Invoke-Sqlcmd -Query "CREATE LOGIN [$domainName\$reportingServiceAccount] FROM WINDOWS WITH DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english]" -ServerInstance $dbServer2ValidationTo verify this step:Log in to the primary database server.Open SQL Server Management Studio.Open connections to both database servers.Verify that all of the user databases on the primary server are also on the secondary server.In the left-hand tree view, expand the AlwaysOn High Availability node of the primary server.In the left-hand tree view, expand the Availability Groups node, and then expand SharePoint (Primary).In the Availability Replicas node, verify that both servers exist.In the Availability Databases node, verify that all user databases exist.Enable High Availability in SharePointIn this step, we will tell the SharePoint server how to communicate with our highly available databases. The environment does not use the Session State Service.To enable high availability in SharePoint, run the following Windows PowerShell script on the SharePoint application server using the on-box variable block defined earlier in this document.Add-PSSnapin Microsoft.SharePoint.Powershellget-spdatabase | where { $_.FailoverServer -eq $null } | ForEach-Object { $_.AddFailoverServiceInstance($dbServer2) ; $_.Update() }ValidationTo verify that this step worked, log into the SharePoint server and then run the following Windows PowerShell command (no variable block is required). It should return an empty list.Add-PSSnapin Microsoft.SharePoint.Powershellget-spdatabase | where { $_.FailoverServer -eq $null }At this point your SharePoint farm is configured with highly available databases. To Overview of the deployment stepsStep 7: Deploy SharePoint Web Front End ServersIn this section we will create the SharePoint Web Front End servers (Bipaper-WFE1 and BiPaper-WFE2). We will use the SharePoint image that was created earlier in this paper as a basis for the VM so that we can skip the process of installing all of the software.At the end of this section, you will have an environment that looks like this:First SharePoint Web Front EndServer Name – BIPaper-WFE1Storage Account – <your globally unique name>Domain/Forest Name – BIPaper.localNetwork Subnet – WebNetAvailability Set – WebAvailabilitySetLoad Balanced EndpointName – httpsPublic Port – 443Private Port – 443Joined to SharePoint FarmPowerPivot Solutions DeployedSecond SharePoint Web Front EndServer Name – BIPaper-WFE2Storage Account – <your globally unique name>Domain/Forest Name – BIPaper.localNetwork Subnet – WebNetAvailability Set – WebAvailabilitySetLoad Balanced EndpointName – httpsPublic Port – 443Private Port – 443Joined to SharePoint FarmPowerPivot Solutions DeployedIf you feel comfortable creating this environment on your own, you can do so and then skip to the “Deploy Additional SharePoint Application/Central Administration Servers” section.Provision VMThis is the only off-box task within the scope of creating the first SharePoint Web Front End server. All other scripts run in a remote desktop session on the machine. The script consists of the following elements:Variable Block – This section gathers information (in addition to the standard variable block you provide as outlined earlier in the document).VM Creation – This section (starting with the comment “Creating the virtual machine…”) consists of the following Windows Azure commands:New-AzureVMConfig – This command begins the definition of the virtual machine. It sets the name, size, image, .vhd location and label, and availability set.Add-AzureProvisioningConfig – This command determines how Windows Azure should provision the VM defined in the last command. It tells Windows Azure that this will be a Windows machine, that automatic updates should be disabled (you can turn this back on if you want), that there should not be endpoints for RDP or Remote Windows PowerShell, and what the administrator user and password should be. Additionally, this command provides the information necessary to automatically join the machine to our domain.Set-AzureSubnet – This command defines what subnet the virtual machine should be deployed into.Add-AzureEndpoint – This command creates the load-balanced endpoint that will be the public gateway to this VM.New-AzureVM – This command does the work of creating the virtual machine that was defined in the earlier commands. In addition to the information gathered from the earlier commands, it defines the cloud service that should be used. The script loops until creation of the VM is complete and writes a status to the screen every 15 seconds.To create the first SharePoint Web Front End server, run the following Windows Azure PowerShell command (use the variable/subscription block with the storage account defined).# Get the name for the VM...$vmName = "BIPaper-WFE1"$vmImageName = "BIPaper-SharePoint"# Get the admin user name for the VM...$vmAdminUserName = Read-Host -Prompt "Server Administrator User Name"# Ask for the password that should be used for the server and convert it to a format usable by the commands...$vmAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Server Administrator Password"$stringMarshal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($vmAdminPasswordSecure)$vmAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal)# Get the domain admin user name...$domainAdminUserName = Read-Host -Prompt "Domain Administrator User Name"# Ask for the domain admin password and convert it to a format usable by the commands...$domainAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Domain Administrator Password"$stringMarshal2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($domainAdminPasswordSecure)$domainAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal2)# Set the location of the .vhd files...$storageAccountContainer = "https://" + $storageAccountName + ".blob.core.vhds/"$vmVHDLocation = $storageAccountContainer + $vmName + ".vhd"# Create the virtual machine...Write-Host "Creating the VM..."New-AzureVMConfig ` -Name $vmName ` -InstanceSize ExtraLarge ` -ImageName $vmImageName ` -MediaLocation $vmVHDLocation ` -DiskLabel "OS" ` -AvailabilitySetName "WebAvailabilitySet" | Add-AzureProvisioningConfig ` -WindowsDomain ` -DisableAutomaticUpdates ` -DisableWinRMHttps ` -NoRDPEndpoint ` -Domain $domainName ` -JoinDomain $domainNameFQ ` -DomainPassword $domainAdminPassword ` -DomainUserName $domainAdminUserName ` -AdminUsername $vmAdminUserName ` -Password $vmAdminPassword | Set-AzureSubnet ` -SubnetNames "WebNet" | Add-AzureEndpoint ` -DefaultProbe ` -LBSetName "https Load Balancer" ` -LocalPort 443 ` -PublicPort 443 ` -Name "https" ` -Protocol tcp | New-AzureVM ` -ServiceName $cloudServiceName# Loop until Satus = ReadyRole...Write-Host "`tWaiting for Provisioning to Complete..."$VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceNameWhile ($VMStatus.InstanceStatus -ne "ReadyRole"){ write-host "`t`tWaiting...Current Status = " $VMStatus.InstanceStatus Start-Sleep -Seconds 15 $VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceName}ValidationThere are two ways to verify that the virtual machine was created:Portal – In the Windows Azure Management Portal, click Virtual Machines and then verify that the virtual machine exists (you might need to refresh the page).PowerShell – Run the following Windows PowerShell command (include the same variable script block used to run the command above). It should return the value True.((Get-AzureVM -name "BIPaper-WFE1" -ServiceName $cloudServiceName) -ne $NULL)Join SharePoint FarmTo join this machine to the SharePoint farm, run the following script from the target server using the on-box variable block defined earlier in this document (you will be prompted for the farm passphrase that you provided when you initially created the farm).# Variable block...$farmPassphraseSecure = Read-Host -AsSecureString -Prompt "Farm Passphrase"# Convert Passwords...$stringMarshal2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($farmPassphraseSecure)$farmPassphrase = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal2)# Configure SharePoint...C:CD "\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\BIN\".\psconfig.exe ` -cmd configdb -connect -server $dbServer -database 'SharePoint_Config' -passphrase $farmPassphrase ` -cmd helpcollections -installall ` -cmd secureresources ` -cmd services -install ` -cmd installfeatures ` -cmd applicationcontent -install ` -cmd quietValidationTo verify that this server was added to the farm successfully:Log in to the target server.Open a SharePoint 2013 Management Shell.Run the following command (it should return the value True).((Get-SPServer | Where {$_.Address -eq "BIPaper-WFE1"}) -ne $NULL)Import CertificateTo import the self-signed SSL certificate that was created in an earlier step, run the following command on the target server using the on-box variable block defined earlier in this document (you will be prompted for the certificate password that you used when the certificate was created). If you did not use the default name for the App-tier server, change the name in this script from “BIPaper-App1” to the server name that you used.Note: You will need to run this script in an elevated Windows PowerShell window because it needs access to a local machine resource.# Variable Block...$appServerName = "BIPaper-App1"# Import the Certificate...$certPassword = Read-Host -AsSecureString -Prompt "Certificate Password"Import-PfxCertificate –FilePath "\\$appServerName\C$\temp\$cloudServiceName..pfx" cert:\localMachine\my -Password $certPassword# Bind the Certificate...$cert = Get-ChildItem cert:\LocalMachine\My | Where {$_.Subject -eq "CN=$cloudServiceName."}# Create a new binding for the SharePoint site...New-WebBinding -Name "SharePoint - 80" -Protocol "https" -Port 443 -IPAddress "*"# Bind the certificate CD IIS:\SslBindings$cert | new-item 0.0.0.0!443ValidationTo verify that the certificate was loaded properly:Log in to the server.Start Internet Information Services (IIS) Manager.In the left-hand tree view, expand the server name, expand Sites, right-click SharePoint – 80, and then click Edit Bindings.In the Site Bindings dialog box, select https and then click Edit.Verify that the SSL certificate is the name of your cloud service’s public URL (<cloudservice>.).Deploy PowerPivot SolutionsTo deploy the PowerPivot solutions to this server, run the following script using the on-box variable block defined earlier in this document.Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"DeployFarmSolution $falseDeployWebAppSolution "http://$cloudServiceName." 2047 $falseValidationTo verify that this command worked, open Internet Explorer on your local workstation, and then navigate to . You will be warned that the certificate is invalid (because it is self-signed and not trusted); continue despite the certificate error. When you are prompted for credentials, use either the domain administrator or the farm service account (both are site collection administrators at this point). You should be directed to the home page of your site collection. Navigate to the PowerPivot gallery. If the PowerPivot gallery is displayed, the solution has been successfully deployed.Note: When your environment is behind a Windows Azure load balancer you do not know what server is rendering your page. To test against a specific server, verify that it is the only server active in the load balancer.Tip: To determine which server is serving a load-balanced page, make a slight edit to the Site Icon file (found at C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\TEMPLATE\IMAGES\SiteIcon.png) so that you can see which site a page is being loaded from. This is not a supported production solution, but it can be helpful for development, test, and POC scenarios.Configure Second SharePoint Web Front EndTo configure a second SharePoint Web Front End, use the same scripts that were used with the first VM, but replace WFE1 with WFE2.At this point, you have a SharePoint farm with a highly available Web tier. The only item remaining is to make the Application tier highly available.To test the load balancing, open the Windows Azure Management Portal and remove one server from the load balancer at a time to ensure that your site is still functional. To Overview of the deployment stepsStep 8: Deploy Additional SharePoint Application/Central Administration ServersAs of right now, we have high availability configured at every layer except for one—the SharePoint application tier. In this section, we will complete our environment by creating a second SharePoint application tier server that runs the same services as the first SharePoint application tier.When this section is complete, we will have the following:SharePoint App ServerServer Name – BIPaper-App2Storage Account – <your globally unique name>Domain/Forest Name – BIPaper.localNetwork Subnet – AppNetAvailability Set – AppAvailabilitySetJoined to SharePoint FarmPowerPivot Solutions DeployedReporting Services installed and runningPowerPivot Service installed and runningCentral Administration runningOther Non-Standard SharePoint Services RunningClaims to Windows Token ServiceExcel Calculation ServicesSecure Store ServiceIf you feel comfortable creating this environment on your own, you can do so – this is the last step in the creation process.Provision VMThis is the only off-box task within the scope of creating the second SharePoint application tier server. All other scripts will be run in a remote desktop session on the machine. The script consists of the following elements:Variable Block – This section gathers information (in addition to the standard variable block you provide as outlined earlier in the document).VM Creation – This section (starting with the comment “Creating the virtual machine…”) consists of the following Windows Azure commands:New-AzureVMConfig – This command begins the definition of the virtual machine. It sets the name, size, image, .vhd location and label, and availability set.Add-AzureProvisioningConfig – This command determines how Windows Azure should provision the VM defined in the last command. It tells Windows Azure that this will be a Windows machine, that automatic updates should be disabled (you can turn this back on if you want), that there should not be endpoints for RDP or Remote Windows PowerShell, and what the administrator user and password should be. Additionally, this command provides the information necessary to automatically join the machine to our domain.Set-AzureSubnet – This command defines what subnet the virtual machine should be deployed into.New-AzureVM – This command does the work of creating the virtual machine that was defined in the earlier commands. In addition to the information gathered from the earlier commands, it defines the cloud service that should be used. The script loops until creation of the VM is complete and writes a status to the screen every 15 seconds.To create the second SharePoint application server, run the following Windows Azure PowerShell command (use the variable/subscription block with the storage account defined).# Get the name for the VM...$vmName = "BIPaper-App2"$vmImageName = "BIPaper-SharePoint"# Get the admin user name for the VM...$vmAdminUserName = Read-Host -Prompt "Server Administrator User Name"# Ask for the password that should be used for the server and convert it to a format usable by the commands...$vmAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Server Administrator Password"$stringMarshal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($vmAdminPasswordSecure)$vmAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal)# Get the domain admin user name...$domainAdminUserName = Read-Host -Prompt "Domain Administrator User Name"# Ask for the domain admin password and convert it to a format usable by the commands...$domainAdminPasswordSecure = Read-Host -AsSecureString -Prompt "Domain Administrator Password"$stringMarshal2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($domainAdminPasswordSecure)$domainAdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal2)# Set the location of the .vhd files...$storageAccountContainer = "https://" + $storageAccountName + ".blob.core.vhds/"$vmVHDLocation = $storageAccountContainer + $vmName + ".vhd"# Create the virtual machine...Write-Host "Creating the VM..."New-AzureVMConfig ` -Name $vmName ` -InstanceSize ExtraLarge ` -ImageName $vmImageName ` -MediaLocation $vmVHDLocation ` -DiskLabel "OS" ` -AvailabilitySetName "AppAvailabilitySet" | Add-AzureProvisioningConfig ` -WindowsDomain ` -DisableAutomaticUpdates ` -DisableWinRMHttps ` -NoRDPEndpoint ` -Domain $domainName ` -JoinDomain $domainNameFQ ` -DomainPassword $domainAdminPassword ` -DomainUserName $domainAdminUserName ` -AdminUsername $vmAdminUserName ` -Password $vmAdminPassword | Set-AzureSubnet ` -SubnetNames "AppNet" | New-AzureVM ` -ServiceName $cloudServiceName# Loop until Satus = ReadyRole...Write-Host "`tWaiting for Provisioning to Complete..."$VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceNameWhile ($VMStatus.InstanceStatus -ne "ReadyRole"){ write-host "`t`tWaiting...Current Status = " $VMStatus.InstanceStatus Start-Sleep -Seconds 15 $VMStatus = Get-AzureVM -name $vmName -ServiceName $cloudServiceName}ValidationThere are two ways to verify that the virtual machine was created:Portal – In the Windows Azure Management Portal, click Virtual Machines and then verify that the virtual machine exists (you might need to refresh the page).PowerShell – Run the following Windows PowerShell command (include the same variable script block used to run the command listed earlier). It should return the value True.((Get-AzureVM -name "BIPaper-App2" -ServiceName $cloudServiceName) -ne $NULL)Join SharePoint FarmTo join this machine to the SharePoint farm, run the following script on the target server using the on-box variable block defined earlier in this document (you will be prompted for the farm passphrase that you provided when you initially created the farm).# Variable block...$farmPassphraseSecure = Read-Host -AsSecureString -Prompt "Farm Passphrase"# Convert Passwords...$stringMarshal2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($farmPassphraseSecure)$farmPassphrase = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($stringMarshal2)# Configure SharePoint...C:CD "\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\BIN\".\psconfig.exe ` -cmd configdb -connect -server $dbServer -database 'SharePoint_Config' -passphrase $farmPassphrase ` -cmd helpcollections -installall ` -cmd secureresources ` -cmd services -install ` -cmd installfeatures ` -cmd adminvs -provision -port 8080 -windowsauthprovider onlyusentlm ` -cmd applicationcontent -install ` -cmd quietValidationTo verify that this server was added to the farm successfully:Log in to the target server.Open a SharePoint 2013 Management Shell.Run the following command (it should return the value True).((Get-SPServer | Where {$_.Address -eq "BIPaper-App2"}) -ne $NULL)Configure Local Service InstancesTo configure and start the PowerPivot service on this machine, run the following script on the target server (a variable block is not required).Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"New-PowerPivotSystemServiceInstance -Provision:$trueValidationTo verify that the service was started successfully:Log in to the target server.Open a SharePoint 2013 Management Shell.Run the following command (it should return the value True).((Get-SPServiceInstance -Server "BIPaper-App2" | Where {$_.TypeName -eq "SQL Server PowerPivot System Service" -and $_.Status -eq "Online"}) -ne $NULL)Start the SharePoint ServicesTo start the non-standard SharePoint services, run the following script on the target server (a variable block is not required).Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"Start-SPServiceInstance -Identity (Get-SPServiceInstance -Server $env:COMPUTERNAME | where {$_.TypeName -eq "Claims to Windows Token Service"}).IdStart-SPServiceInstance -Identity (Get-SPServiceInstance -Server $env:COMPUTERNAME | where {$_.TypeName -eq "Excel Calculation Services"}).IdStart-SPServiceInstance -Identity (Get-SPServiceInstance -Server $env:COMPUTERNAME | where {$_.TypeName -eq "Secure Store Service"}).IdValidationTo verify that the services were started successfully:Log in to the target server.Open a SharePoint 2013 Management Shell.Run the following commands (each should return the value True).((Get-SPServiceInstance -Server "BIPaper-App2" | Where {$_.TypeName -eq "Claims to Windows Token Service" -and $_.Status -eq "Online"}) -ne $NULL)((Get-SPServiceInstance -Server "BIPaper-App2" | Where {$_.TypeName -eq "Excel Calculation Services" -and $_.Status -eq "Online"}) -ne $NULL)((Get-SPServiceInstance -Server "BIPaper-App2" | Where {$_.TypeName -eq "Secure Store Service" -and $_.Status -eq "Online"}) -ne $NULL)Deploy PowerPivot SolutionsTo deploy the PowerPivot solutions to this server, run the following script using the on-box variable block defined earlier in this document.Add-PSSnapin Microsoft.SharePoint.PowershellImport-Module "C:\Program Files\Microsoft SQL Server\110\Tools\PowerPivotTools\SPAddinConfiguration\Resources\ConfigurePowerPivot.ps1"DeployFarmSolution $falseDeployWebAppSolution "http://$cloudServiceName." 2047 $falseValidationTo verify that the solutions were deployed successfully:Log in to the target server.Open Internet Explorer. You will need to disable Internet Explorer Enhanced Security Configuration (ESC) for this to work.Navigate to (or the name of the server you chose if you changed it). You might get an unexpected error the first time you browse to the site—if you refresh the page it should work properly.Browse to the PowerPivot gallery.If the solutions were not deployed properly, you will receive a “File not found” error when you browse to the PowerPivot gallery.Install Reporting Services BitsThis step installs the SQL Server Reporting Services binaries onto the SharePoint application tier. This only needs to be run on servers that will act as report servers—Web Front End servers do not need to have these binaries installed.Note: This step requires installation media for SQL Server 2012 (to install Reporting Services). Place the information in the following directories on the VM:D:\SQL Server 2012\ – This should be the contents of the SQL Server installation media (use the media with SP1 slipstreamed). Do not just put the .iso file in this directory—it needs to be the contents of the media extracted.D:\SQL Server 2012 CU\ – This should be the .exe file that you would run to apply the CU. The CUs are delivered as executable .zip files, the contents of which are what we are looking for in this directory.To install Reporting Services, run the following script on the target server (no variable block is required, but you are prompted for your SQL Server license key).# Get the SQL Server license key...$sqlpid = Read-Host -Prompt "SQL Server License Key"# Install SQL Server...D:CD "\SQL Server 2012".\setup.exe ` /Action=Install ` /PID="$sqlpid" ` /IACCEPTSQLSERVERLICENSETERMS ` /ENU ` /UpdateEnabled=1 ` /UpdateSource="D:\SQL Server 2012 CU" ` /ErrorReporting=0 ` /Features=RS_SHP ` /IndicateProgress ` /QSYou now need to restart the server.ValidationTo verify that Reporting Services was installed properly:Log in to the server.Open Windows Explorer.Navigate to “C:\Program Files\Microsoft SQL Server\110\Setup Bootstrap\Log”, and then open the “Summary.txt” file.Verify that the Final result is Passed but reboot required, see logs for details.Verify that the Exit code (Decimal) is 3010.Enable Reporting ServicesTo enable the Reporting Services bits within SharePoint, run the following script on the target server (no variable block is required).Add-PSSnapin Microsoft.SharePoint.Powershell$RS = Get-SPServiceInstance -Server $env:COMPUTERNAME | Where {$_.TypeName -eq "SQL Server Reporting Services Service"}if ($RS -eq $NULL){ Install-SPRSService Install-SPRSServiceProxy}$RS = Get-SPServiceInstance -Server $env:COMPUTERNAME | Where {$_.TypeName -eq "SQL Server Reporting Services Service"}Start-SPServiceInstance -Identity $RS.Id.ToString()ValidationTo verify that Reporting Services was successfully enabled:Log in to the server.Open a SharePoint 2013 Management Shell.Run the following script (it should return the value True).(((Get-SPServiceInstance -Server $env:COMPUTERNAME | where {$_.TypeName -eq "SQL Server Reporting Services Service"}).Status -eq "Online") -ne $NULL) To Overview of the deployment stepsConclusionIn this paper, we built a full lab environment consisting of:A domainA database back-endA SharePoint farm with separate Web Front Ends, and PowerPivot installed and configured.High availability built in at each tierThe entire environment was deployed using Windows Azure Virtual Machines. You could easily modify these instructions to make a smaller or larger farm. That was our goal, to give you the information that you needed to move forward and build your own customized environment. The environment was built with only the SharePoint components that are required to get the BI environment working. You could add additional options (such as search) if your environment requires them.While all of the steps included a cloud component, the SharePoint installation and configuration used applies to on-premises installations as well, both on physical hardware and virtualized.If you want to work in a non-cloud environment, just start each section after the VM is provisioned (and change your machine/domain naming accordingly).You could even explore more of the Windows Azure Virtual Network options for on-prem connectivity and configure your environment to trust an on-prem domain or even join your cloud-based machines to an existing on-prem domain.For more information:SQL Server Business Intelligence in Windows Azure Virtual Machines: server sample scripts, see paper Server TechCenter: Server DevCenter: SQL Server Portal: this paper help you? Please give us your feedback. Tell us on a scale of 1 (poor) to 5 (excellent), how would you rate this paper and why have you given it this rating? For example:Are you rating it high due to having good examples, excellent screen shots, clear writing, or another reason? Are you rating it low due to poor examples, fuzzy screen shots, or unclear writing?This feedback will help us improve the quality of white papers we release. Send feedback. ................
................
In order to avoid copyright disputes, this page is only a partial summary.
To fulfill the demand for quickly locating and searching documents.
It is intelligent file search solution for home and business.
Related searches
- sql server data classification
- sql server data classification tool
- sql server data types
- azure sql server hyperscale
- sql server 2016 string functions
- sql server connection strings
- sql server localhost connection string
- azure sql server timezone
- azure sql server versions
- sql server sql syntax
- business intelligence in healthcare
- business intelligence vs business analytics