Merge pull request #50 from northtyphoon/master
Visual Studio 2013 Image remote provision/configure scripts
This commit is contained in:
Коммит
b40fd79180
|
@ -0,0 +1,547 @@
|
|||
<#
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
This code is licensed as sample-code under the Visual Studio 2013 license terms.
|
||||
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
#>
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a new Virtual Machine with Active Directory Domain Services.
|
||||
.DESCRIPTION
|
||||
Create a new Virtual Machine with Active Directory Domain Services. It's based on the Windows Server 2012 image.
|
||||
|
||||
The script must be executed with elevated privileges.
|
||||
.EXAMPLE
|
||||
.\CreateNewADDSForest.ps1 -ws2012iImageName "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-201309.01-en.us-127GB.vhd" -azurePublishSettingsFile "C:\Sample\Sample.publishsettings" -subscriptionName "SampleSub" -storageAccountName "samplestorage" -vmName "sampleadds" -vmSize "Medium" -adminUserName "SampleUser1" -adminUserPassword "Pass@word1" -domainName "sample.contoso.com" -safeModeAdminPassword "Pass@word1" -domainSPFarmAccountName "sp_farm" -domainSPFarmAccountPassword "Pass@word1" -vnetName "VNet1" -subnetNames "Subnet1"
|
||||
#>
|
||||
|
||||
Param(
|
||||
# The name of the Windows Server 2012 image
|
||||
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$false)]
|
||||
[string]$ws2012iImageName,
|
||||
|
||||
# The path of the Azure Publish Settings file
|
||||
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false)]
|
||||
[string]$azurePublishSettingsFile,
|
||||
|
||||
# The name of the subscription
|
||||
[Parameter(Mandatory=$true, Position=2, ValueFromPipeline=$false)]
|
||||
[string]$subscriptionName,
|
||||
|
||||
# The name of the Storage Account which will be used to store the Virtual Machine. Please note the script will not create a storage account.
|
||||
[Parameter(Mandatory=$true, Position=3, ValueFromPipeline=$false)]
|
||||
[string]$storageAccountName,
|
||||
|
||||
# The name of the Virtual Machine. The name will also be used as the Cloud Service name that will be created. If the name is taken, the script will automatically clean up the existing deployments or virtual machines in the service.
|
||||
[Parameter(Mandatory=$true, Position=4, ValueFromPipeline=$false)]
|
||||
[string]$vmName,
|
||||
|
||||
# The size of the Virtual Machine
|
||||
[Parameter(Mandatory=$true, Position=5, ValueFromPipeline=$false)]
|
||||
[string]$vmSize,
|
||||
|
||||
# The name of the admin account that you will use to connect to the machine. After Active Directory is configured, the account will be turned into domain admin user. You need to connect to the machine using “domainName\adminUserName”. If you don’t want to create a new domain user, you can use this account as domain users in CreateSharePointDeveloperMachineInDomain.ps1
|
||||
[Parameter(Mandatory=$true, Position=6, ValueFromPipeline=$false)]
|
||||
[string]$adminUserName,
|
||||
|
||||
# The password of the admin account
|
||||
[Parameter(Mandatory=$true, Position=7, ValueFromPipeline=$false)]
|
||||
[string]$adminUserPassword,
|
||||
|
||||
# The fully qualified domain name (FQDN) for the root (first) domain in the forest. For more information see: http://technet.microsoft.com/en-us/library/hh974720(v=wps.620).aspx
|
||||
[Parameter(Mandatory=$true, Position=8, ValueFromPipeline=$false)]
|
||||
[string]$domainName,
|
||||
|
||||
# The password for the administrator account when the computer is started in Safe Mode or a variant of Safe Mode, such as Directory Services Restore Mode. You must supply a password that meets the password complexity rules of the domain and the password cannot be blank. For more information see: http://technet.microsoft.com/en-us/library/hh974720(v=wps.620).aspx
|
||||
[Parameter(Mandatory=$true, Position=9, ValueFromPipeline=$false)]
|
||||
[string]$safeModeAdminPassword,
|
||||
|
||||
# The name of the SharePoint farm domain account
|
||||
[Parameter(Mandatory=$true, Position=10, ValueFromPipeline=$false)]
|
||||
[string]$domainSPFarmAccountName,
|
||||
|
||||
# The password of the SharePoint farm domain account
|
||||
[Parameter(Mandatory=$true, Position=11, ValueFromPipeline=$false)]
|
||||
[string]$domainSPFarmAccountPassword,
|
||||
|
||||
# The name of the Virtual Network the Virtual Machine should be provisioned into. The Virtual Network needs to be in the same location as the storage account. Please note that this will not create a Virtual Network
|
||||
[Parameter(Mandatory=$true, Position=12, ValueFromPipeline=$false)]
|
||||
[string]$vnetName,
|
||||
|
||||
# The subnet names of the Virtual Network the Virtual Machine should be provisioned into
|
||||
[Parameter(Mandatory=$false, Position=13, ValueFromPipeline=$false)]
|
||||
[string[]]$subnetNames
|
||||
)
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Remove the specified Cloud Service and clean up the deployments under it.
|
||||
.DESCRIPTION
|
||||
Remove the specified Cloud Service and clean up the deployments under it.
|
||||
.INPUTS
|
||||
$serviceName - The Cloud Service name.
|
||||
.OUTPUTS
|
||||
None.
|
||||
#>
|
||||
|
||||
function CleanupCloudService
|
||||
{
|
||||
param(
|
||||
# The Cloud Service Name
|
||||
[string]$serviceName
|
||||
)
|
||||
|
||||
$slots = @("Staging", "Production")
|
||||
|
||||
foreach($slot in $slots)
|
||||
{
|
||||
$deployment = Get-AzureDeployment -Slot $slot -ServiceName $serviceName -ErrorAction Ignore
|
||||
|
||||
if($deployment -ne $null)
|
||||
{
|
||||
$machines = Get-AzureVM -ServiceName $serviceName -ErrorAction Ignore
|
||||
|
||||
if($machines -ne $null)
|
||||
{
|
||||
foreach($machine in $machines)
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to remove virtual machine $($machine.Name)."
|
||||
Remove-AzureVM -Name $machine.Name -ServiceName $serviceName
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to remove deployment $($deployment.Name)."
|
||||
Remove-AzureDeployment -ServiceName $serviceName -Slot $slot -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): Start to remove cloud service $serviceName."
|
||||
Remove-AzureService -ServiceName $serviceName -Force
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a new Virtual Machine.
|
||||
.DESCRIPTION
|
||||
Create a new Virtual Machine. If there exits a Cloud Service with the same name, it will be removed along with its deployments.
|
||||
.INPUTS
|
||||
$imageName - The name of the base Virtual Machine image.
|
||||
$storageAccountName - The name of the Storage Account which will be used to store the Virtual Machine.
|
||||
$serviceName - The name of the Cloud Service for the Virtual Machine.
|
||||
$vmName - The name of the Virtual Machine.
|
||||
$vmSize - The size of the Virtual Machine.
|
||||
$adminUserName - The name of the admin account.
|
||||
$adminUserPassword - The password of the admin account.
|
||||
$vnetName - The name of the Virtual Network.
|
||||
$subnetNames - The subnet names of the Virtual Network.
|
||||
.OUTPUTS
|
||||
None.
|
||||
#>
|
||||
|
||||
function CreateVirtualMachine
|
||||
{
|
||||
param(
|
||||
# The name of the base Virtual Machine image
|
||||
[string]$imageName,
|
||||
|
||||
# The name of the Storage Account which will be used to store the Virtual Machine
|
||||
[string]$storageAccountName,
|
||||
|
||||
# The name of the Cloud Service for the Virtual Machine
|
||||
[string]$serviceName,
|
||||
|
||||
# The name of the Virtual Machine
|
||||
[string]$vmName,
|
||||
|
||||
# The size of the Virtual Machine
|
||||
[string]$vmSize,
|
||||
|
||||
# The name of the admin account
|
||||
[string]$adminUserName,
|
||||
|
||||
# The password of the admin account
|
||||
[string]$adminUserPassword,
|
||||
|
||||
# The name of the Virtual Network
|
||||
[string]$vnetName,
|
||||
|
||||
# The subnet names of the Virtual Network
|
||||
[string[]]$subnetNames
|
||||
)
|
||||
|
||||
# Check if the image exists
|
||||
$image = Get-AzureVMImage -ImageName $imageName
|
||||
if(!$image)
|
||||
{
|
||||
Write-Host "$(Get-Date): $imageName doesn't exist."
|
||||
return
|
||||
}
|
||||
|
||||
$storageAccount = Get-AzureStorageAccount -StorageAccountName $storageAccountName
|
||||
if(!$storageAccount)
|
||||
{
|
||||
Write-Host "$(Get-Date): $storageAccountName doesn't exist. You can run New-AzureStorageAccount to create a new one."
|
||||
return
|
||||
}
|
||||
|
||||
$vnetSite = $null
|
||||
if(![string]::IsNullOrEmpty($vnetName))
|
||||
{
|
||||
$vnetSite = Get-AzureVNetSite -VNetName $vnetName
|
||||
if(!$vnetSite)
|
||||
{
|
||||
Write-Host "$(Get-Date): $vnetName doesn't exist."
|
||||
return
|
||||
}
|
||||
|
||||
$vnetLocation = (Get-AzureAffinityGroup -Name $vnetSite.AffinityGroup).Location
|
||||
$storageAccountLocation = $storageAccount.Location
|
||||
if(!$storageAccountLocation)
|
||||
{
|
||||
$storageAccountLocation = (Get-AzureAffinityGroup -Name $storageAccount.AffinityGroup).Location
|
||||
}
|
||||
|
||||
if($vnetLocation -ne $storageAccountLocation)
|
||||
{
|
||||
Write-Host "$(Get-Date): $vnetName should be in the same location as $storageAccountName."
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
$cloudService = Get-AzureService -ServiceName $serviceName -ErrorAction Ignore
|
||||
|
||||
if($cloudService -ne $null)
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to clean up existing cloud service $serviceName."
|
||||
CleanupCloudService $serviceName
|
||||
}
|
||||
|
||||
$vmConfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmSize -ImageName $imageName |
|
||||
Add-AzureProvisioningConfig -Windows -EnableWinRMHttp -AdminUsername $adminUserName -Password $adminUserPassword
|
||||
|
||||
Write-Host "$(Get-Date): Start to create virtual machine: $vmName."
|
||||
|
||||
if(!$vnetSite)
|
||||
{
|
||||
if(!$storageAccount.Location)
|
||||
{
|
||||
New-AzureVM -VMs $vmConfig -AffinityGroup $storageAccount.AffinityGroup -ServiceName $serviceName -WaitForBoot
|
||||
}
|
||||
else
|
||||
{
|
||||
New-AzureVM -VMs $vmConfig -Location $storageAccount.Location -ServiceName $serviceName -WaitForBoot
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($subnetNames -ne $null)
|
||||
{
|
||||
$vmConfig = Set-AzureSubnet -VM $vmConfig -SubnetNames $subnetNames
|
||||
}
|
||||
|
||||
New-AzureVM -VMs $vmConfig -VNetName $vnetName -AffinityGroup $vnetSite.AffinityGroup -ServiceName $serviceName -WaitForBoot
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
Download and install a WinRm certificate to the certficate store
|
||||
.DESCRIPTION
|
||||
Gets the WinRM certificate from the specified Virtual Machine, and install it on the LocalMachine store.
|
||||
.INPUTS
|
||||
$serviceName - The name of the Cloud Service.
|
||||
$vmName - The name of the Virtual Machine.
|
||||
.OUTPUTS
|
||||
NONE
|
||||
#>
|
||||
|
||||
function DownloadAndInstallWinRMCert
|
||||
{
|
||||
param(
|
||||
# The name of the Cloud Service
|
||||
[string]$serviceName,
|
||||
|
||||
# The name of the Virtual Machine
|
||||
[string]$vmName
|
||||
)
|
||||
|
||||
$winRMCert = (Get-AzureVM -ServiceName $serviceName -Name $vmname | select -ExpandProperty vm).DefaultWinRMCertificateThumbprint
|
||||
|
||||
$AzureX509cert = Get-AzureCertificate -ServiceName $serviceName -Thumbprint $winRMCert -ThumbprintAlgorithm sha1
|
||||
|
||||
$certTempFile = [IO.Path]::GetTempFileName()
|
||||
|
||||
$AzureX509cert.Data | Out-File $certTempFile
|
||||
|
||||
$certToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $certTempFile
|
||||
|
||||
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "LocalMachine"
|
||||
|
||||
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
|
||||
|
||||
$exists = $false
|
||||
foreach($certificate in $store.Certificates)
|
||||
{
|
||||
if($certificate.Thumbprint -eq $certToImport.Thumbprint)
|
||||
{
|
||||
$exists = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if(!$exists)
|
||||
{
|
||||
$store.Add($certToImport)
|
||||
}
|
||||
|
||||
$store.Close()
|
||||
|
||||
Remove-Item $certTempFile
|
||||
}
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
Add a Virtual Machine to the DNS servers of the specified Virtual Network.
|
||||
.DESCRIPTION
|
||||
Add a Virtual Machine to the DNS servers of the specified Virtual Network.
|
||||
.INPUTS
|
||||
$vnetName - The name of the Virtual Network.
|
||||
$serviceName - The name of the Cloud Service.
|
||||
$vmName - The name of the Virtual Machine.
|
||||
.OUTPUTS
|
||||
NONE
|
||||
#>
|
||||
|
||||
function AddVNetDNSEntry
|
||||
{
|
||||
param(
|
||||
# The name of the Virtual Network
|
||||
[string] $vnetName,
|
||||
|
||||
# The name of the Cloud Service
|
||||
[string] $serviceName,
|
||||
|
||||
#
|
||||
[string] $vmName
|
||||
)
|
||||
|
||||
$error.Clear()
|
||||
|
||||
$dnsName = $vmName
|
||||
$dnsIPAddress = (Get-AzureVM -ServiceName $serviceName -Name $vmName).IpAddress
|
||||
|
||||
# Export existing Azure VNet Config
|
||||
|
||||
$vnetConfig = [xml] (Get-AzureVNetConfig).XMLConfiguration
|
||||
|
||||
# Read the configuration file into memory
|
||||
$namespace = "http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration"
|
||||
|
||||
if($vnetConfig.NetworkConfiguration.VirtualNetworkConfiguration.Dns.DnsServers -eq $null)
|
||||
{
|
||||
# Add DNS Server node
|
||||
$dnsServersNode = $vnetConfig.CreateElement("DnsServers", $namespace)
|
||||
$dnsServerNode = $vnetConfig.CreateElement("DnsServer", $namespace)
|
||||
$dnsServerNode.SetAttribute('name', $dnsName) | Out-Null
|
||||
$dnsServerNode.SetAttribute('IPAddress', $dnsIPAddress) | Out-Null
|
||||
$dnsServersNode.AppendChild($dnsServerNode) | Out-Null
|
||||
$vnetConfig.NetworkConfiguration.VirtualNetworkConfiguration.GetElementsByTagName('Dns')[0].AppendChild($dnsServersNode) | Out-Null
|
||||
}
|
||||
else
|
||||
{
|
||||
# Update existing DNS Server node
|
||||
$dnsServerNode = $vnetConfig.NetworkConfiguration.VirtualNetworkConfiguration.Dns.DnsServers.SelectSingleNode("descendant::*[name()='DnsServer'][@name='" + $dnsName +"']")
|
||||
if($dnsServerNode -eq $null)
|
||||
{
|
||||
$dnsServerNode = $vnetConfig.CreateElement("DnsServer", $namespace)
|
||||
$dnsServerNode.SetAttribute('name', $dnsName) | Out-Null
|
||||
$dnsServerNode.SetAttribute('IPAddress',$dnsIPAddress) | Out-Null
|
||||
$vnetConfig.NetworkConfiguration.VirtualNetworkConfiguration.Dns.DnsServers.AppendChild($dnsServerNode) | Out-Null
|
||||
}
|
||||
else
|
||||
{
|
||||
$dnsServerNode.SetAttribute('IPAddress',$dnsIPAddress) | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$vnetSite = $vnetConfig.SelectSingleNode("/*/*/*[name()='VirtualNetworkSites']/*[name()='VirtualNetworkSite'][@name='" + $vnetName + "']")
|
||||
if($vnetSite.DnsServersRef -eq $null)
|
||||
{
|
||||
# Add DNS Servers Ref node
|
||||
$dnsServersRefNode = $vnetConfig.CreateElement("DnsServersRef", $namespace)
|
||||
$dnsServerRefNode = $vnetConfig.CreateElement("DnsServerRef", $namespace)
|
||||
$dnsServerRefNode.SetAttribute('name', $dnsName) | Out-Null
|
||||
$dnsServersRefNode.AppendChild($dnsServerRefNode) | Out-Null
|
||||
$vnetSite.AppendChild($dnsServersRefNode) | Out-Null
|
||||
}
|
||||
else
|
||||
{
|
||||
# Update existing DNS Servers Ref node
|
||||
$dnsServerRefNode = $vnetSite.DnsServersRef.SelectSingleNode("descendant::*[name()='DnsServerRef'][@name='" + $dnsName +"']")
|
||||
if($dnsServerRefNode -eq $null)
|
||||
{
|
||||
$dnsServerRefNode = $vnetConfig.CreateElement("DnsServerRef", $namespace)
|
||||
$dnsServerRefNode.SetAttribute('name', $dnsName) | Out-Null
|
||||
$vnetSite.DnsServersRef.AppendChild($dnsServerRefNode) | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
$vnetConfigurationPath = Join-Path -Path $env:temp -ChildPath "vnet.xml"
|
||||
$vnetConfig.Save($vnetConfigurationPath)
|
||||
|
||||
Write-Host "$(Get-Date): Start to update VNet config with new DNS Server entry."
|
||||
Set-AzureVNetConfig -ConfigurationPath $vnetConfigurationPath | Out-Null
|
||||
|
||||
if(!$error)
|
||||
{
|
||||
Write-Host "$(Get-Date): VNet config has been successfully updated."
|
||||
}
|
||||
}
|
||||
|
||||
# Prepare azure environment
|
||||
|
||||
Import-AzurePublishSettingsFile -PublishSettingsFile $azurePublishSettingsFile -ErrorAction Stop
|
||||
Select-AzureSubscription -SubscriptionName $subscriptionName -ErrorAction Stop
|
||||
Set-AzureSubscription -SubscriptionName $subscriptionName -CurrentStorageAccount $storageAccountName -ErrorAction Stop
|
||||
|
||||
# Use vmName as serviceName. Clean up the existing one before creation.
|
||||
|
||||
$serviceName = $vmName
|
||||
CreateVirtualMachine $ws2012iImageName $storageAccountName $serviceName $vmName $vmSize $adminUserName $adminUserPassword $vnetName $subnetNames
|
||||
|
||||
Write-Host "$(Get-Date): Start to download and install the remoting cert (self-signed) to local machine trusted root."
|
||||
DownloadAndInstallWinRMCert $serviceName $vmName
|
||||
|
||||
$remotingUri = (Get-AzureWinRMUri -ServiceName $serviceName -Name $vmName).AbsoluteUri
|
||||
$remotingCredential = New-Object System.Management.Automation.PSCredential "$vmName\$adminUserName", (ConvertTo-SecureString -String $adminUserPassword -AsPlainText -Force)
|
||||
|
||||
Write-Host "$(Get-Date): Start to configure Active Directory Forest via powershell remoting uri: $remotingUri."
|
||||
$configureADDSForestScript =
|
||||
{
|
||||
Param(
|
||||
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$false)]
|
||||
[string]$domainName,
|
||||
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false)]
|
||||
[string]$safeModeAdminPassword
|
||||
)
|
||||
|
||||
$isWS2012 = [Environment]::OSVersion.Version -ge (new-object 'Version' 6,2,9200,0)
|
||||
|
||||
if(!$isWS2012)
|
||||
{
|
||||
Write-Host "(VM) $(Get-Date): Current version only supports Windows Server 2012"
|
||||
return 1
|
||||
}
|
||||
|
||||
$databasePath = Join-Path -Path $env:SystemDrive -ChildPath "NTDS"
|
||||
$sysvolPath = Join-Path -Path $env:SystemDrive -ChildPath "SysvolPath"
|
||||
$logPath = Join-Path -Path $env:SystemDrive -ChildPath "Logs"
|
||||
|
||||
New-Item -Path $databasePath -ItemType directory | Out-Null
|
||||
New-Item -Path $sysvolPath -ItemType directory | Out-Null
|
||||
New-Item -Path $logPath -ItemType directory | Out-Null
|
||||
|
||||
Write-Host "(VM) $(Get-Date): Start to install AD-Domain-Service feature."
|
||||
|
||||
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools | Out-Null
|
||||
|
||||
Write-Host "(VM) $(Get-Date): Start to install ADDSForest."
|
||||
|
||||
Install-ADDSForest -DomainName $domainName -DomainMode Win2012 -ForestMode Win2012 -Force -SafeModeAdministratorPassword (ConvertTo-SecureString -String $safeModeAdminPassword -AsPlainText -force) -DatabasePath $databasePath -SYSVOLPath $sysvolPath -LogPath $logPath -NoRebootOnCompletion | Out-Null
|
||||
|
||||
Import-Module -Name DnsServer
|
||||
|
||||
$externalPublicDnsServiceAddress = "8.8.8.8"
|
||||
|
||||
Write-Host "(VM) $(Get-Date): Start to add DNS conditional forward zones for external domains."
|
||||
|
||||
Add-DnsServerConditionalForwarderZone -Name 'com' -MasterServers $externalPublicDnsServiceAddress
|
||||
Add-DnsServerConditionalForwarderZone -Name 'net' -MasterServers $externalPublicDnsServiceAddress
|
||||
Add-DnsServerConditionalForwarderZone -Name 'ms' -MasterServers $externalPublicDnsServiceAddress
|
||||
|
||||
return 0
|
||||
}
|
||||
$result = Invoke-Command -ConnectionUri $remotingUri -Credential $remotingCredential -ScriptBlock $configureADDSForestScript -ArgumentList @($domainName, $safeModeAdminPassword)
|
||||
|
||||
if($result -ne 0)
|
||||
{
|
||||
Write-Host "$(Get-Date): Failed to configure Active Directory Forest."
|
||||
exit
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "$(Get-Date): Active Directory Forest has been configured successfully. $domainName\$adminUserName is the domain admin user."
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): Start to reboot virtual machine: $vmName."
|
||||
Restart-AzureVM -ServiceName $serviceName -Name $vmName
|
||||
|
||||
Write-Host "$(Get-Date): Start to update VNet DNS entry."
|
||||
AddVNetDNSEntry $vnetName $serviceName $vmName
|
||||
|
||||
Write-Host "$(Get-Date): Start to add SPFarm domain user."
|
||||
$remotingCredential = New-Object System.Management.Automation.PSCredential "$domainName\$adminUserName", (ConvertTo-SecureString -String $adminUserPassword -AsPlainText -Force)
|
||||
$addDomainUserScript =
|
||||
{
|
||||
Param(
|
||||
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$false)]
|
||||
[string]$ouName,
|
||||
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false)]
|
||||
[string]$userName,
|
||||
[Parameter(Mandatory=$true, Position=2, ValueFromPipeline=$false)]
|
||||
[string]$displayName,
|
||||
[Parameter(Mandatory=$true, Position=3, ValueFromPipeline=$false)]
|
||||
[string]$password
|
||||
)
|
||||
|
||||
$Error.Clear()
|
||||
|
||||
Start-Service -Name "ADWS"
|
||||
|
||||
$maxTry = 10
|
||||
while (((Get-Service -Name "ADWS").Status -ne "Running") -and ($maxTry -gt 0))
|
||||
{
|
||||
Write-Host "(VM) $(Get-Date): Wait 10 seconds for Active Directory Web Services running."
|
||||
Start-Sleep -Seconds 10
|
||||
$maxTry--
|
||||
}
|
||||
|
||||
$domainName = (Get-ADDomain).DistinguishedName
|
||||
|
||||
$ouDN = "OU=$ouName, $domainName"
|
||||
|
||||
$ou = Get-ADOrganizationalUnit -Filter { name -eq $ouName }
|
||||
|
||||
if(!$ou)
|
||||
{
|
||||
New-ADOrganizationalUnit -Name $ouName -Path $domainName | Out-Null
|
||||
}
|
||||
|
||||
New-ADUser -Name $userName -SamAccountName $userName -DisplayName $displayName -Path $ouDN -Enabled $true -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString $password -AsPlainText -force) -PassThru | Out-NULL
|
||||
|
||||
if(!$Error)
|
||||
{
|
||||
return 0
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1
|
||||
}
|
||||
}
|
||||
$result = Invoke-Command -ConnectionUri $remotingUri -Credential $remotingCredential -ScriptBlock $addDomainUserScript -ArgumentList @("SharePoint", $domainSPFarmAccountName, "SharePoint Farm Domain Account", $domainSPFarmAccountPassword)
|
||||
|
||||
if($result -ne 0)
|
||||
{
|
||||
Write-Host "$(Get-Date): Failed to add SPFarm domain user."
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): New ADDS Forest has been created successfully. Please run Get-AzureRemoteDesktopFile to connect the machine and login as $domainName\$adminUserName."
|
||||
|
||||
|
|
@ -0,0 +1,347 @@
|
|||
<#
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
This code is licensed as sample-code under the Visual Studio 2013 license terms.
|
||||
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
#>
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a new Virtual Machine for SharePoint development.
|
||||
.DESCRIPTION
|
||||
Create a new Virtual Machine for SharePoint development based on Visual Studio 2013 image.
|
||||
The script configures SQL Server Database Engine, Reporting Service, Analysis Service, Integration Service, Agent Service and create a defulat instance (MSSQLSERVER).
|
||||
The script also configures the following SharePoint environment in the Virtual Machine.
|
||||
- SharePoint configuration database: "SP2013_Configuration".
|
||||
- SharePoint Central Administration content database: "SP2013_Content_CentralAdministration" Central Administration Port: 11111 Central Administration Authentication: NTLM.
|
||||
- Web Application "Developer Test Site" on port 80 with default authentication provider. Using default app pool running under –localSPFarmAccountName identity.
|
||||
- Root site collection "Developer Test Site Collection" Based on team site template. Primary site collection owner is the logged on user.
|
||||
|
||||
The script must be executed with elevated privileges.
|
||||
.EXAMPLE
|
||||
.\CreateSharePointDeveloperMachine.ps1 -imageName "03f55de797f546a1b29d1b8d66be687a__Visual-Studio-2013-Ultimate-12.0.21005.1-AzureSDK-2.2" -azurePublishSettingsFile "C:\Sample\Sample.publishsettings" -subscriptionName "SampleSub" -storageAccountName "samplestorage" -vmName “samplespdev" -vmSize "ExtraLarge" -adminUserName "SampleUser1" -adminUserPassword "Pass@word1" -localSPFarmAccountName "sp_farm" -localSPFarmAccountPassword "Pass@word1"
|
||||
.\CreateSharePointDeveloperMachine.ps1 -imageName "03f55de797f546a1b29d1b8d66be687a__Visual-Studio-2013-Ultimate-12.0.21005.1-AzureSDK-2.2" -azurePublishSettingsFile "C:\Sample\Sample.publishsettings" -subscriptionName "SampleSub" -storageAccountName "samplestorage" -vmName “samplespdev" -vmSize "ExtraLarge" -adminUserName "SampleUser1" -adminUserPassword "Pass@word1" -localSPFarmAccountName "sp_farm" -localSPFarmAccountPassword "Pass@word1" -vnetName "VNet1" -subnetNames "Subnet1"
|
||||
#>
|
||||
|
||||
Param(
|
||||
# The name of the Visual Studio 2013 image
|
||||
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$false)]
|
||||
[string]$imageName,
|
||||
|
||||
# The path of the Azure Publish Settings file
|
||||
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false)]
|
||||
[string]$azurePublishSettingsFile,
|
||||
|
||||
# The name of the subscription
|
||||
[Parameter(Mandatory=$true, Position=2, ValueFromPipeline=$false)]
|
||||
[string]$subscriptionName,
|
||||
|
||||
# The name of the Storage Account which will be used to store the Virtual Machine. Please note the script will not create a storage account
|
||||
[Parameter(Mandatory=$true, Position=3, ValueFromPipeline=$false)]
|
||||
[string]$storageAccountName,
|
||||
|
||||
# The name of the Virtual Machine. The name will also be used as the Cloud Service name that will be created
|
||||
[Parameter(Mandatory=$true, Position=4, ValueFromPipeline=$false)]
|
||||
[string]$vmName,
|
||||
|
||||
# The size of the Virtual Machine
|
||||
[Parameter(Mandatory=$true, Position=5, ValueFromPipeline=$false)]
|
||||
[string]$vmSize,
|
||||
|
||||
# The name of the admin account that you will use to connect to the machine
|
||||
[Parameter(Mandatory=$true, Position=6, ValueFromPipeline=$false)]
|
||||
[string]$adminUserName,
|
||||
|
||||
# The password of the admin account
|
||||
[Parameter(Mandatory=$true, Position=7, ValueFromPipeline=$false)]
|
||||
[string]$adminUserPassword,
|
||||
|
||||
# The name of the SharePoint Farm local account
|
||||
[Parameter(Mandatory=$true, Position=8, ValueFromPipeline=$false)]
|
||||
[string]$localSPFarmAccountName,
|
||||
|
||||
# The password of the SharePoint Farm local account
|
||||
[Parameter(Mandatory=$true, Position=9, ValueFromPipeline=$false)]
|
||||
[string]$localSPFarmAccountPassword,
|
||||
|
||||
# The name of the Virtual Network the Virtual Machine should be provisioned into. The Virtual Network needs to be in the same location as the storage account. Please note that this will not create a Virtual Network
|
||||
[Parameter(Mandatory=$false, Position=10, ValueFromPipeline=$false)]
|
||||
[string]$vnetName,
|
||||
|
||||
# The subnet names of the Virtual Network the Virtual Machine should be provisioned into
|
||||
[Parameter(Mandatory=$false, Position=11, ValueFromPipeline=$false)]
|
||||
[string[]]$subnetNames
|
||||
)
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Remove the specified Cloud Service and clean up the deployments under it.
|
||||
.DESCRIPTION
|
||||
Remove the specified Cloud Service and clean up the deployments under it.
|
||||
.INPUTS
|
||||
$serviceName - The Cloud Service name.
|
||||
.OUTPUTS
|
||||
None.
|
||||
#>
|
||||
|
||||
function CleanupCloudService
|
||||
{
|
||||
param(
|
||||
# The Cloud Service Name
|
||||
[string]$serviceName
|
||||
)
|
||||
|
||||
$slots = @("Staging", "Production")
|
||||
|
||||
foreach($slot in $slots)
|
||||
{
|
||||
$deployment = Get-AzureDeployment -Slot $slot -ServiceName $serviceName -ErrorAction Ignore
|
||||
|
||||
if($deployment -ne $null)
|
||||
{
|
||||
$machines = Get-AzureVM -ServiceName $serviceName -ErrorAction Ignore
|
||||
|
||||
if($machines -ne $null)
|
||||
{
|
||||
foreach($machine in $machines)
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to remove virtual machine $($machine.Name)."
|
||||
Remove-AzureVM -Name $machine.Name -ServiceName $serviceName
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to remove deployment $($deployment.Name)."
|
||||
Remove-AzureDeployment -ServiceName $serviceName -Slot $slot -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): Start to remove cloud service $serviceName."
|
||||
Remove-AzureService -ServiceName $serviceName -Force
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a new Virtual Machine.
|
||||
.DESCRIPTION
|
||||
Create a new Virtual Machine. If there exits a Cloud Service with the same name, it will be removed along with its deployments.
|
||||
.INPUTS
|
||||
$imageName - The name of the base Virtual Machine image.
|
||||
$storageAccountName - The name of the Storage Account which will be used to store the Virtual Machine.
|
||||
$serviceName - The name of the Cloud Service for the Virtual Machine.
|
||||
$vmName - The name of the Virtual Machine.
|
||||
$vmSize - The size of the Virtual Machine.
|
||||
$adminUserName - The name of the admin account.
|
||||
$adminUserPassword - The password of the admin account.
|
||||
$vnetName - The name of the Virtual Network.
|
||||
$subnetNames - The subnet names of the Virtual Network.
|
||||
.OUTPUTS
|
||||
None.
|
||||
#>
|
||||
|
||||
function CreateVirtualMachine
|
||||
{
|
||||
param(
|
||||
# The name of the base Virtual Machine image
|
||||
[string]$imageName,
|
||||
|
||||
# The name of the Storage Account which will be used to store the Virtual Machine
|
||||
[string]$storageAccountName,
|
||||
|
||||
# The name of the Cloud Service for the Virtual Machine
|
||||
[string]$serviceName,
|
||||
|
||||
# The name of the Virtual Machine
|
||||
[string]$vmName,
|
||||
|
||||
# The size of the Virtual Machine
|
||||
[string]$vmSize,
|
||||
|
||||
# The name of the admin account
|
||||
[string]$adminUserName,
|
||||
|
||||
# The password of the admin account
|
||||
[string]$adminUserPassword,
|
||||
|
||||
# The name of the Virtual Network
|
||||
[string]$vnetName,
|
||||
|
||||
# The subnet names of the Virtual Network
|
||||
[string[]]$subnetNames
|
||||
)
|
||||
|
||||
# Check if the image exists
|
||||
$image = Get-AzureVMImage -ImageName $imageName
|
||||
if(!$image)
|
||||
{
|
||||
Write-Host "$(Get-Date): $imageName doesn't exist."
|
||||
return
|
||||
}
|
||||
|
||||
$storageAccount = Get-AzureStorageAccount -StorageAccountName $storageAccountName
|
||||
if(!$storageAccount)
|
||||
{
|
||||
Write-Host "$(Get-Date): $storageAccountName doesn't exist. You can run New-AzureStorageAccount to create a new one."
|
||||
return
|
||||
}
|
||||
|
||||
$vnetSite = $null
|
||||
if(![string]::IsNullOrEmpty($vnetName))
|
||||
{
|
||||
$vnetSite = Get-AzureVNetSite -VNetName $vnetName
|
||||
if(!$vnetSite)
|
||||
{
|
||||
Write-Host "$(Get-Date): $vnetName doesn't exist."
|
||||
return
|
||||
}
|
||||
|
||||
$vnetLocation = (Get-AzureAffinityGroup -Name $vnetSite.AffinityGroup).Location
|
||||
$storageAccountLocation = $storageAccount.Location
|
||||
if(!$storageAccountLocation)
|
||||
{
|
||||
$storageAccountLocation = (Get-AzureAffinityGroup -Name $storageAccount.AffinityGroup).Location
|
||||
}
|
||||
|
||||
if($vnetLocation -ne $storageAccountLocation)
|
||||
{
|
||||
Write-Host "$(Get-Date): $vnetName should be in the same location as $storageAccountName."
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
$cloudService = Get-AzureService -ServiceName $serviceName -ErrorAction Ignore
|
||||
|
||||
if($cloudService -ne $null)
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to clean up existing cloud service $serviceName."
|
||||
CleanupCloudService $serviceName
|
||||
}
|
||||
|
||||
$vmConfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmSize -ImageName $imageName |
|
||||
Add-AzureProvisioningConfig -Windows -EnableWinRMHttp -AdminUsername $adminUserName -Password $adminUserPassword
|
||||
|
||||
Write-Host "$(Get-Date): Start to create virtual machine: $vmName."
|
||||
|
||||
if(!$vnetSite)
|
||||
{
|
||||
if(!$storageAccount.Location)
|
||||
{
|
||||
New-AzureVM -VMs $vmConfig -AffinityGroup $storageAccount.AffinityGroup -ServiceName $serviceName -WaitForBoot
|
||||
}
|
||||
else
|
||||
{
|
||||
New-AzureVM -VMs $vmConfig -Location $storageAccount.Location -ServiceName $serviceName -WaitForBoot
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($subnetNames -ne $null)
|
||||
{
|
||||
$vmConfig = Set-AzureSubnet -VM $vmConfig -SubnetNames $subnetNames
|
||||
}
|
||||
|
||||
New-AzureVM -VMs $vmConfig -VNetName $vnetName -AffinityGroup $vnetSite.AffinityGroup -ServiceName $serviceName -WaitForBoot
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
Download and install a WinRm certificate to the certficate store
|
||||
.DESCRIPTION
|
||||
Gets the WinRM certificate from the specified Virtual Machine, and install it on the LocalMachine store.
|
||||
.INPUTS
|
||||
$serviceName - The name of the Cloud Service.
|
||||
$vmName - The name of the Virtual Machine.
|
||||
.OUTPUTS
|
||||
NONE
|
||||
#>
|
||||
|
||||
function DownloadAndInstallWinRMCert
|
||||
{
|
||||
param(
|
||||
# The name of the Cloud Service
|
||||
[string]$serviceName,
|
||||
|
||||
# The name of the Virtual Machine
|
||||
[string]$vmName
|
||||
)
|
||||
|
||||
$winRMCert = (Get-AzureVM -ServiceName $serviceName -Name $vmname | select -ExpandProperty vm).DefaultWinRMCertificateThumbprint
|
||||
|
||||
$AzureX509cert = Get-AzureCertificate -ServiceName $serviceName -Thumbprint $winRMCert -ThumbprintAlgorithm sha1
|
||||
|
||||
$certTempFile = [IO.Path]::GetTempFileName()
|
||||
|
||||
$AzureX509cert.Data | Out-File $certTempFile
|
||||
|
||||
$certToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $certTempFile
|
||||
|
||||
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "LocalMachine"
|
||||
|
||||
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
|
||||
|
||||
$exists = $false
|
||||
foreach($certificate in $store.Certificates)
|
||||
{
|
||||
if($certificate.Thumbprint -eq $certToImport.Thumbprint)
|
||||
{
|
||||
$exists = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if(!$exists)
|
||||
{
|
||||
$store.Add($certToImport)
|
||||
}
|
||||
|
||||
$store.Close()
|
||||
|
||||
Remove-Item $certTempFile
|
||||
}
|
||||
|
||||
# Prepare azure environement
|
||||
|
||||
Import-AzurePublishSettingsFile -PublishSettingsFile $azurePublishSettingsFile -ErrorAction Stop
|
||||
Select-AzureSubscription -SubscriptionName $subscriptionName -ErrorAction Stop
|
||||
Set-AzureSubscription -SubscriptionName $subscriptionName -CurrentStorageAccount $storageAccountName -ErrorAction Stop
|
||||
|
||||
# Use vmName as serviceName. Clean up the existing one before creation.
|
||||
$serviceName = $vmName
|
||||
CreateVirtualMachine $imageName $storageAccountName $serviceName $vmName $vmSize $adminUserName $adminUserPassword $vnetName $subnetNames
|
||||
|
||||
Write-Host "$(Get-Date): Start to download and install the remoting cert (self-signed) to local machine trusted root"
|
||||
DownloadAndInstallWinRMCert $serviceName $vmName
|
||||
|
||||
$remotingUri = (Get-AzureWinRMUri -ServiceName $serviceName -Name $vmName).AbsoluteUri
|
||||
$remotingCredential = New-Object System.Management.Automation.PSCredential "$vmName\$adminUserName", (ConvertTo-SecureString -String $adminUserPassword -AsPlainText -Force)
|
||||
|
||||
Write-Host "$(Get-Date): Start to configure SharePoint Farm via powershell remoting uri: $remotingUri"
|
||||
|
||||
$configureSPFarmScript =
|
||||
{
|
||||
Param(
|
||||
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$false)]
|
||||
[string]$localSPFarmAccountName,
|
||||
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false)]
|
||||
[string]$localSPFarmAccountPassword
|
||||
)
|
||||
|
||||
$configureSharePointFarmScript = Join-Path -Path $env:SystemDrive -ChildPath "ConfigureDeveloperDesktop\Scripts\ConfigureSharePointFarm.ps1"
|
||||
|
||||
$result = & $configureSharePointFarmScript -localSPFarmAccountName $localSPFarmAccountName -localSPFarmAccountPassword $localSPFarmAccountPassword
|
||||
|
||||
return $result
|
||||
}
|
||||
$result = Invoke-Command -ConnectionUri $remotingUri -Credential $remotingCredential -ScriptBlock $configureSPFarmScript -ArgumentList @($localSPFarmAccountName, $localSPFarmAccountPassword)
|
||||
|
||||
if($result -ne 0)
|
||||
{
|
||||
Write-Host "$(Get-Date): Failed to configure SharePoint Farm."
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): Please run Get-AzureRemoteDesktopFile to connect the machine and login as $vmName\$adminUserName"
|
|
@ -0,0 +1,435 @@
|
|||
<#
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
This code is licensed as sample-code under the Visual Studio 2013 license terms.
|
||||
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
#>
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a new Virtual Machine for SharePoint development in the in the specified domain
|
||||
.DESCRIPTION
|
||||
Create a new Virtual Machine for SharePoint development in the specified domain based on Visual Studio 2013 image.
|
||||
The script configures SQL Server Database Engine, Reporting Service, Analysis Service, Integration Service, Agent Service and create a defulat instance (MSSQLSERVER).
|
||||
The script also configures the following SharePoint environment in the Virtual Machine.
|
||||
- SharePoint configuration database: "SP2013_Configuration".
|
||||
- SharePoint Central Administration content database: "SP2013_Content_CentralAdministration" Central Administration Port: 11111 Central Administration Authentication: NTLM.
|
||||
- Web Application "Developer Test Site" on port 80 with default authentication provider. Using default app pool running under –localSPFarmAccountName identity.
|
||||
- Root site collection "Developer Test Site Collection" Based on team site template. Primary site collection owner is the logged on user.
|
||||
|
||||
Before executing, follow the steps to enable CredSSP on the client machine for delegation.
|
||||
- Run Set-WSManQuickConfig to make sure WinRM service is running.
|
||||
- Run Enable-WSManCredSSP -Role Client -DelegateComputer "*.cloudapp.net" Note: This command will fail if your client machine is connected to any networks defined as "Public network" in "Network and Sharing Center."
|
||||
- Enable delegating of fresh credentials using group policy editor on your client machine. Run gpedit.msc -> Computer Configuration -> Administrative Templates -> System -> Credentials Delegation and then change the state of "Allow Delegating Fresh Credentials with NTLM-only server authentication" to "Enabled."(Its default state will say, "Not configured.") In the Add Servers sections add : WSMAN/*.cloudapp.net. Click here for more details on enabling CredSSP.
|
||||
|
||||
The script must be executed with elevated privileges.
|
||||
.EXAMPLE
|
||||
.\CreateSharePointDeveloperMachineInDomain.ps1 -imageName "03f55de797f546a1b29d1b8d66be687a__Visual-Studio-2013-Ultimate-12.0.21005.1-AzureSDK-2.2" -azurePublishSettingsFile "C:\Sample\Sample.publishsettings" -subscriptionName " SampleSub" -storageAccountName "samplestorage" -vmName "samplespdev" -vmSize "ExtraLarge" -adminUserName "SampleUser2" -adminUserPassword "Pass@word1" -domainDnsName "sample.contoso.com" -domainName "sample" -domainUserName "SampleUser1" -domainUserPassword "Pass@word1" -domainSPFarmAccountName "sp_farm" -domainSPFarmAccountPassword "Pass@word1" -vnetName "VNet1" -subnetNames "Subnet1"
|
||||
#>
|
||||
|
||||
Param(
|
||||
# The name of the Visual Studio 2013 image
|
||||
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$false)]
|
||||
[string]$imageName,
|
||||
|
||||
# The path of the Azure Publish Settings file
|
||||
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false)]
|
||||
[string]$azurePublishSettingsFile,
|
||||
|
||||
# The name of the subscription
|
||||
[Parameter(Mandatory=$true, Position=2, ValueFromPipeline=$false)]
|
||||
[string]$subscriptionName,
|
||||
|
||||
# The name of the Storage Account which will be used to store the Virtual Machine. Please note the script will not create a storage account
|
||||
[Parameter(Mandatory=$true, Position=3, ValueFromPipeline=$false)]
|
||||
[string]$storageAccountName,
|
||||
|
||||
# The name of the Virtual Machine. The name will also be used as the Cloud Service name that will be created
|
||||
[Parameter(Mandatory=$true, Position=4, ValueFromPipeline=$false)]
|
||||
[string]$vmName,
|
||||
|
||||
# The size of the Virtual Machine
|
||||
[Parameter(Mandatory=$true, Position=5, ValueFromPipeline=$false)]
|
||||
[string]$vmSize,
|
||||
|
||||
# The name of the admin account that you will use to connect to the machine
|
||||
[Parameter(Mandatory=$true, Position=6, ValueFromPipeline=$false)]
|
||||
[string]$adminUserName,
|
||||
|
||||
# The password of the admin account
|
||||
[Parameter(Mandatory=$true, Position=7, ValueFromPipeline=$false)]
|
||||
[string]$adminUserPassword,
|
||||
|
||||
# The fully qualified domain name (FQDN) of the Windows domain to join
|
||||
[Parameter(Mandatory=$true, Position=8, ValueFromPipeline=$false)]
|
||||
[string]$domainDnsName,
|
||||
|
||||
# The domain name of the domain user account that has permission to add the computer to a domain
|
||||
[Parameter(Mandatory=$true, Position=9, ValueFromPipeline=$false)]
|
||||
[string]$domainName,
|
||||
|
||||
# The name of the domain user account that has permission to add the computer to a domain. The user will be added to the administrator group of the virtual machine. The user will also be added as the primary site collection owner for the demo site collection. After the setup, you will use this account to connect to the machine.
|
||||
[Parameter(Mandatory=$true, Position=10, ValueFromPipeline=$false)]
|
||||
[string]$domainUserName,
|
||||
|
||||
# The password of the domain user account that has permission to add the computer to a domain
|
||||
[Parameter(Mandatory=$true, Position=11, ValueFromPipeline=$false)]
|
||||
[string]$domainUserPassword,
|
||||
|
||||
# The name of the SharePoint Farm domain account
|
||||
[Parameter(Mandatory=$true, Position=12, ValueFromPipeline=$false)]
|
||||
[string]$domainSPFarmAccountName,
|
||||
|
||||
# The password of the SharePoint Farm domain account
|
||||
[Parameter(Mandatory=$true, Position=13, ValueFromPipeline=$false)]
|
||||
[string]$domainSPFarmAccountPassword,
|
||||
|
||||
# The name of the Virtual Network the Virtual Machine should be provisioned into. The Virtual Network needs to be in the same location as the storage account. Please note that this will not create a Virtual Network
|
||||
[Parameter(Mandatory=$true, Position=14, ValueFromPipeline=$false)]
|
||||
[string]$vnetName,
|
||||
|
||||
# The subnet names of the Virtual Network the Virtual Machine should be provisioned into
|
||||
[Parameter(Mandatory=$false, Position=15, ValueFromPipeline=$false)]
|
||||
[string[]]$subnetNames
|
||||
)
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Remove the specified Cloud Service and clean up the deployments under it.
|
||||
.DESCRIPTION
|
||||
Remove the specified Cloud Service and clean up the deployments under it.
|
||||
.INPUTS
|
||||
$serviceName - The Cloud Service name.
|
||||
.OUTPUTS
|
||||
None.
|
||||
#>
|
||||
|
||||
function CleanupCloudService
|
||||
{
|
||||
param(
|
||||
# The Cloud Service Name
|
||||
[string]$serviceName
|
||||
)
|
||||
|
||||
$slots = @("Staging", "Production")
|
||||
|
||||
foreach($slot in $slots)
|
||||
{
|
||||
$deployment = Get-AzureDeployment -Slot $slot -ServiceName $serviceName -ErrorAction Ignore
|
||||
|
||||
if($deployment -ne $null)
|
||||
{
|
||||
$machines = Get-AzureVM -ServiceName $serviceName -ErrorAction Ignore
|
||||
|
||||
if($machines -ne $null)
|
||||
{
|
||||
foreach($machine in $machines)
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to remove virtual machine $($machine.Name)."
|
||||
Remove-AzureVM -Name $machine.Name -ServiceName $serviceName
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to remove deployment $($deployment.Name)."
|
||||
Remove-AzureDeployment -ServiceName $serviceName -Slot $slot -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): Start to remove cloud service $serviceName."
|
||||
Remove-AzureService -ServiceName $serviceName -Force
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a new Virtual Machine in the specified domain
|
||||
.DESCRIPTION
|
||||
Create a new Virtual Machine in the specified domain. If there exits a Cloud Service with the same name, it will be removed along with its deployments.
|
||||
.INPUTS
|
||||
$imageName - The name of the base Virtual Machine image.
|
||||
$storageAccountName - The name of the Storage Account which will be used to store the Virtual Machine.
|
||||
$serviceName - The name of the Cloud Service for the Virtual Machine.
|
||||
$vmName - The name of the Virtual Machine.
|
||||
$vmSize - The size of the Virtual Machine.
|
||||
$adminUserName - The name of the admin account.
|
||||
$adminUserPassword - The password of the admin account.
|
||||
$domainDnsName - The fully qualified domain name (FQDN) of the Windows domain to join.
|
||||
$domainName - The domain name of the domain user account that has permission to add the computer to a domain.
|
||||
$domainUserName - The name of the domain user account that has permission to add the computer to a domain.
|
||||
$domainPassword - The name of the domain user account that has permission to add the computer to a domain.
|
||||
$vnetName - The name of the Virtual Network.
|
||||
$subnetNames - The subnet names of the Virtual Network.
|
||||
.OUTPUTS
|
||||
None.
|
||||
#>
|
||||
|
||||
function CreateVirtualMachineInDomain
|
||||
{
|
||||
param(
|
||||
# The name of the base Virtual Machine image
|
||||
[string]$imageName,
|
||||
|
||||
# The name of the Storage Account which will be used to store the Virtual Machine
|
||||
[string]$storageAccountName,
|
||||
|
||||
# The name of the Cloud Service for the Virtual Machine
|
||||
[string]$serviceName,
|
||||
|
||||
# The name of the Virtual Machine
|
||||
[string]$vmName,
|
||||
|
||||
# The size of the Virtual Machine
|
||||
[string]$vmSize,
|
||||
|
||||
# The name of the admin account
|
||||
[string]$adminUserName,
|
||||
|
||||
# The password of the admin account
|
||||
[string]$adminUserPassword,
|
||||
|
||||
# The fully qualified domain name (FQDN) of the Windows domain to join
|
||||
[string]$domainDnsName,
|
||||
|
||||
# The domain name of the domain user account that has permission to add the computer to a domain
|
||||
[string]$domainName,
|
||||
|
||||
# The name of the domain user account that has permission to add the computer to a domain
|
||||
[string]$domainUserName,
|
||||
|
||||
# The password of the SharePoint Farm domain account
|
||||
[string]$domainPassword,
|
||||
|
||||
# The name of the Virtual Network
|
||||
[string]$vnetName,
|
||||
|
||||
# The subnet names of the Virtual Network
|
||||
[string[]]$subnetNames
|
||||
)
|
||||
|
||||
# Check if the image exists
|
||||
$image = Get-AzureVMImage -ImageName $imageName
|
||||
if(!$image)
|
||||
{
|
||||
Write-Host "$(Get-Date): $imageName doesn't exist."
|
||||
return 1
|
||||
}
|
||||
|
||||
$storageAccount = Get-AzureStorageAccount -StorageAccountName $storageAccountName
|
||||
if(!$storageAccount)
|
||||
{
|
||||
Write-Host "$(Get-Date): $storageAccountName doesn't exist. You can run New-AzureStorageAccount to create a new one."
|
||||
return 1
|
||||
}
|
||||
|
||||
$vnetSite = Get-AzureVNetSite -VNetName $vnetName
|
||||
if(!$vnetSite)
|
||||
{
|
||||
Write-Host "$(Get-Date): $vnetName doesn't exist."
|
||||
return 1
|
||||
}
|
||||
|
||||
$vnetLocation = (Get-AzureAffinityGroup -Name $vnetSite.AffinityGroup).Location
|
||||
$storageAccountLocation = $storageAccount.Location
|
||||
if(!$storageAccountLocation)
|
||||
{
|
||||
$storageAccountLocation = (Get-AzureAffinityGroup -Name $storageAccount.AffinityGroup).Location
|
||||
}
|
||||
|
||||
if($vnetLocation -ne $storageAccountLocation)
|
||||
{
|
||||
Write-Host "$(Get-Date): $vnetName should be in the same location as $storageAccountName."
|
||||
return 1
|
||||
}
|
||||
|
||||
$cloudService = Get-AzureService -ServiceName $serviceName -ErrorAction Ignore
|
||||
|
||||
if($cloudService -ne $null)
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to clean up existing cloud service $serviceName."
|
||||
CleanupCloudService $serviceName
|
||||
}
|
||||
|
||||
$vmConfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmSize -ImageName $imageName |
|
||||
Add-AzureProvisioningConfig -WindowsDomain -EnableWinRMHttp -AdminUsername $adminUserName -Password $adminUserPassword -JoinDomain $domainDnsName -Domain $domainName -DomainUserName $domainUserName -DomainPassword $domainPassword
|
||||
|
||||
if($subnetNames -ne $null)
|
||||
{
|
||||
$vmConfig = Set-AzureSubnet -VM $vmConfig -SubnetNames $subnetNames
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): Start to create virtual machine: $vmName."
|
||||
|
||||
New-AzureVM -VMs $vmConfig -VNetName $vnetName -AffinityGroup $vnetSite.AffinityGroup -ServiceName $serviceName -WaitForBoot
|
||||
}
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
Download and install a WinRm certificate to the certficate store
|
||||
.DESCRIPTION
|
||||
Gets the WinRM certificate from the specified Virtual Machine, and install it on the LocalMachine store.
|
||||
.INPUTS
|
||||
$serviceName - The name of the Cloud Service.
|
||||
$vmName - The name of the Virtual Machine.
|
||||
.OUTPUTS
|
||||
NONE
|
||||
#>
|
||||
|
||||
function DownloadAndInstallWinRMCert
|
||||
{
|
||||
param(
|
||||
# The name of the Cloud Service
|
||||
[string]$serviceName,
|
||||
|
||||
# The name of the Virtual Machine
|
||||
[string]$vmName
|
||||
)
|
||||
|
||||
$winRMCert = (Get-AzureVM -ServiceName $serviceName -Name $vmname | select -ExpandProperty vm).DefaultWinRMCertificateThumbprint
|
||||
|
||||
$AzureX509cert = Get-AzureCertificate -ServiceName $serviceName -Thumbprint $winRMCert -ThumbprintAlgorithm sha1
|
||||
|
||||
$certTempFile = [IO.Path]::GetTempFileName()
|
||||
|
||||
$AzureX509cert.Data | Out-File $certTempFile
|
||||
|
||||
$certToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $certTempFile
|
||||
|
||||
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "LocalMachine"
|
||||
|
||||
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
|
||||
|
||||
$exists = $false
|
||||
foreach($certificate in $store.Certificates)
|
||||
{
|
||||
if($certificate.Thumbprint -eq $certToImport.Thumbprint)
|
||||
{
|
||||
$exists = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if(!$exists)
|
||||
{
|
||||
$store.Add($certToImport)
|
||||
}
|
||||
|
||||
$store.Close()
|
||||
|
||||
Remove-Item $certTempFile
|
||||
}
|
||||
|
||||
# Prepare azure environement
|
||||
|
||||
Import-AzurePublishSettingsFile -PublishSettingsFile $azurePublishSettingsFile -ErrorAction Stop
|
||||
Select-AzureSubscription -SubscriptionName $subscriptionName -ErrorAction Stop
|
||||
Set-AzureSubscription -SubscriptionName $subscriptionName -CurrentStorageAccount $storageAccountName -ErrorAction Stop
|
||||
|
||||
# Use vmName as serviceName. Clean up the existing one before creation.
|
||||
$serviceName = $vmName
|
||||
CreateVirtualMachineInDomain $imageName $storageAccountName $serviceName $vmName $vmSize $adminUserName $adminUserPassword $domainDnsName $domainName $domainUserName $domainUserPassword $vnetName $subnetNames
|
||||
|
||||
Write-Host "$(Get-Date): Start to download and install the remoting cert (self-signed) to local machine trusted root."
|
||||
DownloadAndInstallWinRMCert $serviceName $vmName
|
||||
|
||||
$remotingUri = (Get-AzureWinRMUri -ServiceName $serviceName -Name $vmName).AbsoluteUri
|
||||
$remotingCredential = New-Object System.Management.Automation.PSCredential "$vmName\$adminUserName", (ConvertTo-SecureString -String $adminUserPassword -AsPlainText -Force)
|
||||
|
||||
Write-Host "$(Get-Date): Start to add domain user to local admin group via powershell remoting uri: $remotingUri."
|
||||
$addDomainUserToLocalGroupScript =
|
||||
{
|
||||
Param(
|
||||
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$false)]
|
||||
[string]$domainName,
|
||||
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false)]
|
||||
[string]$domainUserName,
|
||||
[Parameter(Mandatory=$true, Position=2, ValueFromPipeline=$false)]
|
||||
[string]$groupName
|
||||
)
|
||||
|
||||
$Error.Clear()
|
||||
|
||||
([ADSI]"WinNT://$env:COMPUTERNAME/$groupName,group").Add("WinNT://$domainName/$domainUserName")
|
||||
|
||||
if(!$Error)
|
||||
{
|
||||
return 0
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1
|
||||
}
|
||||
}
|
||||
$result = Invoke-Command -ConnectionUri $remotingUri -Credential $remotingCredential -ScriptBlock $addDomainUserToLocalGroupScript -ArgumentList @($domainName, $domainUserName, "Administrators")
|
||||
|
||||
if($result -ne 0)
|
||||
{
|
||||
Write-Host "$(Get-Date): Failed to add domain user to local admin group."
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): Start to enable CredSSP via powershell remoting uri: $remotingUri."
|
||||
$enableCredSSPScript =
|
||||
{
|
||||
Param()
|
||||
|
||||
$Error.Clear()
|
||||
|
||||
$credSSP = winrm g winrm/config/service/auth | Where-Object {$_.Contains('CredSSP = true')}
|
||||
|
||||
if(!$credSSP)
|
||||
{
|
||||
Write-Host "(VM) $(Get-Date): Start to enable CredSSP."
|
||||
|
||||
winrm s winrm/config/service/auth '@{CredSSP="true"}' | Out-Null
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "(VM) $(Get-Date): CredSSP is already enabled."
|
||||
}
|
||||
|
||||
if(!$Error)
|
||||
{
|
||||
return 0
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1
|
||||
}
|
||||
}
|
||||
$result = Invoke-Command -ConnectionUri $remotingUri -Credential $remotingCredential -ScriptBlock $enableCredSSPScript
|
||||
|
||||
if($result -ne 0)
|
||||
{
|
||||
Write-Host "$(Get-Date): Failed to enable CredSSP."
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): Start to configure SharePoint Farm in domain via powershell remoting uri: $remotingUri."
|
||||
$remotingCredential = New-Object System.Management.Automation.PSCredential "$domainName\$domainUserName", (ConvertTo-SecureString -String $domainUserPassword -AsPlainText -Force)
|
||||
$configureSPFarmInDomainScript =
|
||||
{
|
||||
Param(
|
||||
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$false)]
|
||||
[string]$domainSPFarmAccountName,
|
||||
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false)]
|
||||
[string]$domainSPFarmAccountPassword
|
||||
)
|
||||
|
||||
$configureSharePointFarmInDomainScript = Join-Path -Path $env:SystemDrive -ChildPath "ConfigureDeveloperDesktop\Scripts\ConfigureSharePointFarmInDomain.ps1"
|
||||
|
||||
$result = & $configureSharePointFarmInDomainScript -domainSPFarmAccountName $domainSPFarmAccountName -domainSPFarmAccountPassword $domainSPFarmAccountPassword
|
||||
|
||||
return $result
|
||||
}
|
||||
$result = Invoke-Command -ConnectionUri $remotingUri -Credential $remotingCredential -Authentication Credssp -ScriptBlock $configureSPFarmInDomainScript -ArgumentList @($domainSPFarmAccountName, $domainSPFarmAccountPassword)
|
||||
|
||||
if($result -ne 0)
|
||||
{
|
||||
Write-Host "$(Get-Date): Failed to configure SharePoint Farm in domain."
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): Please run Get-AzureRemoteDesktopFile to connect the machine and login as $domainName\$domainUserName."
|
|
@ -0,0 +1,233 @@
|
|||
<#
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
This code is licensed as sample-code under the Visual Studio 2013 license terms.
|
||||
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
#>
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a Virtual Network.
|
||||
.DESCRIPTION
|
||||
Create a Virtual Network using the settings from the Virtual Network configuration file.
|
||||
|
||||
The configuration file follows the schema definition which can be found in http://msdn.microsoft.com/en-us/library/windowsazure/jj157100.aspx.
|
||||
Here is an example:
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<NetworkConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration">
|
||||
<VirtualNetworkConfiguration>
|
||||
<VirtualNetworkSites>
|
||||
<VirtualNetworkSite name="VNet1" AffinityGroup="AffinityGroup1">
|
||||
<AddressSpace>
|
||||
<AddressPrefix>10.0.0.0/20</AddressPrefix>
|
||||
</AddressSpace>
|
||||
<Subnets>
|
||||
<Subnet name="Subnet1">
|
||||
<AddressPrefix>10.0.0.0/28</AddressPrefix>
|
||||
</Subnet>
|
||||
</Subnets>
|
||||
</VirtualNetworkSite>
|
||||
</VirtualNetworkSites>
|
||||
</VirtualNetworkConfiguration>
|
||||
</NetworkConfiguration>
|
||||
.EXAMPLE
|
||||
.\CreateVNet.ps1 -azurePublishSettingsFile "C:\Sample\Sample.publishsettings" -subscriptionName "SampleSub" -vnetConfigurationPath "C:\Sample\vnet.xml" -affinityGroupName "AffinityGroup1" -affinityGroupLocation "West US"
|
||||
#>
|
||||
|
||||
Param(
|
||||
# The path of the Azure Publish Settings file
|
||||
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$false)]
|
||||
[string]$azurePublishSettingsFile,
|
||||
|
||||
# The name of the subscription
|
||||
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false)]
|
||||
[string]$subscriptionName,
|
||||
|
||||
# The path of the configuration file
|
||||
[Parameter(Mandatory=$true, Position=2, ValueFromPipeline=$false)]
|
||||
[string]$vnetConfigurationPath,
|
||||
|
||||
# The name of the Affinity Group that Virtual Netwokr will be associated with
|
||||
[Parameter(Mandatory=$true, Position=3, ValueFromPipeline=$false)]
|
||||
[string]$affinityGroupName,
|
||||
|
||||
# The location of the Affinity Group
|
||||
[Parameter(Mandatory=$true, Position=4, ValueFromPipeline=$false)]
|
||||
[string]$affinityGroupLocation
|
||||
)
|
||||
|
||||
if(!(Test-Path $vnetConfigurationPath))
|
||||
{
|
||||
Write-Host "$(Get-Date): $vnetConfigurationPath doesn't exist."
|
||||
exit
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Add a new Virtual Network configuration to the existing configuration.
|
||||
.DESCRIPTION
|
||||
Add a new Virtual Network configuration to the existing configuration.
|
||||
.INPUTS
|
||||
vnetConfigurationPath - Path to the configuration file
|
||||
.OUTPUTS
|
||||
None
|
||||
#>
|
||||
|
||||
function AddVNet
|
||||
{
|
||||
Param(
|
||||
# Path to the configuration file
|
||||
[string] $vnetConfigurationPath
|
||||
)
|
||||
|
||||
$error.Clear()
|
||||
|
||||
$inputVNetConfig = [xml] (Get-Content $vnetConfigurationPath)
|
||||
$currentVNetConfig = [xml] (Get-AzureVNetConfig).XMLConfiguration
|
||||
$combinedVNetConfig = $null
|
||||
|
||||
#If no configuration found just use the new configuration
|
||||
if(!$currentVNetConfig.NetworkConfiguration)
|
||||
{
|
||||
$combinedVNetConfig = $inputVNetConfig
|
||||
}
|
||||
else
|
||||
{
|
||||
# If VNet already exists and identical do nothing
|
||||
$inputVNetSite = $inputVNetConfig.SelectSingleNode("/*/*/*[name()='VirtualNetworkSites']/*[name()='VirtualNetworkSite']")
|
||||
$existingVNetSite = $currentVNetConfig.SelectSingleNode("/*/*/*[name()='VirtualNetworkSites']/*[name()='VirtualNetworkSite'][@name='" + $inputVNetSite.name + "']")
|
||||
if($existingVNetSite -ne $null -and $existingVNetSite.AddressSpace.OuterXml.Equals($inputVNetSite.AddressSpace.OuterXml) -and $existingVNetSite.Subnets.OuterXml.Equals($inputVNetSite.Subnets.OuterXml))
|
||||
{
|
||||
Write-Host "$(Get-Date): A VNet with name $($inputVNetSite.name) and identical configuration already exists."
|
||||
return
|
||||
}
|
||||
|
||||
$combinedVNetConfig = $currentVNetConfig
|
||||
|
||||
# Combine DNS Servers
|
||||
$dnsNode = $combinedVNetConfig.NetworkConfiguration.VirtualNetworkConfiguration.Dns
|
||||
if($dnsNode -ne $null)
|
||||
{
|
||||
$inputDnsServers = $inputVNetConfig.NetworkConfiguration.VirtualNetworkConfiguration.Dns.DnsServers
|
||||
$newDnsServers = MergeXmlChildren $dnsNode.DnsServers $inputDnsServers "name"
|
||||
$dnsNode.ReplaceChild($newDnsServers, $dnsNode.DnsServers) | Out-Null
|
||||
}
|
||||
elseif($currentVNetConfig.NetworkConfiguration.VirtualNetworkConfiguration.Dns -ne $null)
|
||||
{
|
||||
$combinedVNetConfig.NetworkConfiguration.VirtualNetworkConfiguration.InsertBefore($currentVNetConfig.NetworkConfiguration.VirtualNetworkConfiguration.Dns,
|
||||
$combinedVNetConfig.NetworkConfiguration.VirtualNetworkConfiguration.VirtualNetworkSites) | Out-Null
|
||||
}
|
||||
|
||||
# Combine Virtual Network Sites
|
||||
$virtualNetworkConfigurationNode = $combinedVNetConfig.NetworkConfiguration.VirtualNetworkConfiguration
|
||||
if($virtualNetworkConfigurationNode.VirtualNetworkSites -ne $null)
|
||||
{
|
||||
$inputVirtualNetworkSites = $inputVNetConfig.NetworkConfiguration.VirtualNetworkConfiguration.VirtualNetworkSites
|
||||
$newVirtualNetworkSites = MergeXmlChildren $virtualNetworkConfigurationNode.VirtualNetworkSites $inputVirtualNetworkSites "name"
|
||||
$virtualNetworkConfigurationNode.ReplaceChild($newVirtualNetworkSites, $virtualNetworkConfigurationNode.VirtualNetworkSites) | Out-Null
|
||||
}
|
||||
elseif($inputVNetConfig.NetworkConfiguration.VirtualNetworkConfiguration.VirtualNetworkSites -ne $null)
|
||||
{
|
||||
$inputVirtualNetworkSites = $inputVNetConfig.NetworkConfiguration.VirtualNetworkConfiguration.VirtualNetworkSites
|
||||
$vns = $combinedVNetConfig.CreateElement("VirtualNetworkSites", $combinedVNetConfig.DocumentElement.NamespaceURI)
|
||||
$vns.InnerXML = $inputVirtualNetworkSites.InnerXml
|
||||
$combinedVNetConfig.NetworkConfiguration.VirtualNetworkConfiguration.AppendChild($vns) | Out-Null
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "$(Get-Date): VirtualNetworkSites are missing from $vnetConfigurationPath."
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
$combinedVNetConfigurationPath = Join-Path -Path $env:temp -ChildPath "vnet.xml"
|
||||
$combinedVNetConfig.Save($combinedVNetConfigurationPath)
|
||||
|
||||
Write-Host "$(Get-Date): Start to update VNet config."
|
||||
Set-AzureVNetConfig -ConfigurationPath $combinedVNetConfigurationPath | Out-Null
|
||||
|
||||
if(!$error)
|
||||
{
|
||||
Write-Host "$(Get-Date): VNet config has been successfully updated."
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Merge the child nodes of two xml elements which have the same schema.
|
||||
.DESCRIPTION
|
||||
Merge the child nodes of two xml elmenets which have the same schema.
|
||||
Use the target attribute value as the key to identify the node. If there exits any key confilction, return $null.
|
||||
.INPUTS
|
||||
$elem1 - The first xml element.
|
||||
$elem2 - The second xml element.
|
||||
$keyAttributeName - The name of the attribute used as the key.
|
||||
.OUTPUTS
|
||||
The combined xml element.
|
||||
#>
|
||||
|
||||
function MergeXmlChildren
|
||||
{
|
||||
Param(
|
||||
# The first xml element
|
||||
[System.Xml.XmlElement] $elem1,
|
||||
|
||||
# The second xml element
|
||||
[System.Xml.XmlElement] $elem2,
|
||||
|
||||
# The name of the attribute used as the key
|
||||
[string] $keyAttributeName
|
||||
)
|
||||
|
||||
$elemCombined = $elem1
|
||||
|
||||
# Get key values from $elem1
|
||||
$childNodeHash = @{}
|
||||
foreach($childNode in $elem1.ChildNodes)
|
||||
{
|
||||
$childNodeHash.Add($childNode.$keyAttributeName, $childNode)
|
||||
}
|
||||
|
||||
foreach($childNode in $elem2.ChildNodes)
|
||||
{
|
||||
if(!($childNodeHash.Keys -contains $childNode.$keyAttributeName))
|
||||
{
|
||||
# Append children from $elem2 if there is no key conflict
|
||||
$importedNode = $elemCombined.AppendChild($elemCombined.OwnerDocument.ImportNode($childNode, $true))
|
||||
}
|
||||
elseif(!$childNodeHash.Item($childNode.$keyAttributeName).OuterXml.Equals($childNode.OuterXml))
|
||||
{
|
||||
# Otherwise return $null
|
||||
Write-Host "$(Get-Date): Failed to merge XML element $($elem1.Name) because non-identical child elements with the same $keyAttributeName are found."
|
||||
return $null
|
||||
}
|
||||
}
|
||||
|
||||
return $elemCombined
|
||||
}
|
||||
|
||||
# Prepare Azure environment
|
||||
|
||||
Import-AzurePublishSettingsFile -PublishSettingsFile $azurePublishSettingsFile -ErrorAction Stop
|
||||
Select-AzureSubscription -SubscriptionName $subscriptionName -ErrorAction Stop
|
||||
|
||||
$affinityGroup = Get-AzureAffinityGroup -Name $affinityGroupName -ErrorAction Ignore
|
||||
if(!$affinityGroup)
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to create affinity group $affinityGroupName located in $affinityGroupLocation."
|
||||
New-AzureAffinityGroup -Name $affinityGroupName -Location $affinityGroupLocation
|
||||
}
|
||||
else
|
||||
{
|
||||
# Check if the existing affinity group matches the location
|
||||
if ($affinityGroup.Location -ne $affinityGroupLocation)
|
||||
{
|
||||
Write-Host "$(Get-Date): Affinty group $affinityGroupName already exists but is not located in $affinityGroupLocation."
|
||||
exit
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): Start to add VNet."
|
||||
AddVNet $vnetConfigurationPath
|
|
@ -0,0 +1,327 @@
|
|||
<#
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
This code is licensed as sample-code under the Visual Studio 2013 license terms.
|
||||
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
#>
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a new Virtual Machine for Web and SQL development.
|
||||
.DESCRIPTION
|
||||
Create a new Virtual Machine for Web and SQL development based on Visual Studio 2013 image.
|
||||
The script configures SQL Server Database Engine, Reporting Service, Analysis Service, Integration Service, Agent Service and create a defulat instance (MSSQLSERVER).
|
||||
|
||||
The script must be executed with elevated privileges.
|
||||
.EXAMPLE
|
||||
.\CreateWebSQLDeveloperMachine.ps1 -imageName "03f55de797f546a1b29d1b8d66be687a__Visual-Studio-2013-Ultimate-12.0.21005.1-AzureSDK-2.2" -azurePublishSettingsFile "C:\Sample\Sample.publishsettings" -subscriptionName "SampleSub" -storageAccountName "samplestorage" -vmName “samplewebdev" -vmSize "Large" -adminUserName "SampleUser1" -adminUserPassword "Pass@word1"
|
||||
.\CreateWebSQLDeveloperMachine.ps1 -imageName "03f55de797f546a1b29d1b8d66be687a__Visual-Studio-2013-Ultimate-12.0.21005.1-AzureSDK-2.2" -azurePublishSettingsFile "C:\Sample\Sample.publishsettings" -subscriptionName "SampleSub" -storageAccountName "samplestorage" -vmName “samplewebdev" -vmSize "Large" -adminUserName "SampleUser1" -adminUserPassword "Pass@word1" -vnetName "VNet1" -subnetNames "Subnet1"
|
||||
#>
|
||||
|
||||
Param(
|
||||
# The name of the Visual Studio 2013 image
|
||||
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$false)]
|
||||
[string]$imageName,
|
||||
|
||||
# The path of the Azure Publish Settings file
|
||||
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false)]
|
||||
[string]$azurePublishSettingsFile,
|
||||
|
||||
# The name of the subscription
|
||||
[Parameter(Mandatory=$true, Position=2, ValueFromPipeline=$false)]
|
||||
[string]$subscriptionName,
|
||||
|
||||
# The name of the Storage Account which will be used to store the Virtual Machine. Please note the script will not create a storage account
|
||||
[Parameter(Mandatory=$true, Position=3, ValueFromPipeline=$false)]
|
||||
[string]$storageAccountName,
|
||||
|
||||
# The name of the Virtual Machine. The name will also be used as the Cloud Service name that will be created
|
||||
[Parameter(Mandatory=$true, Position=4, ValueFromPipeline=$false)]
|
||||
[string]$vmName,
|
||||
|
||||
# The size of the Virtual Machine
|
||||
[Parameter(Mandatory=$true, Position=5, ValueFromPipeline=$false)]
|
||||
[string]$vmSize,
|
||||
|
||||
# The name of the admin account that you will use to connect to the machine
|
||||
[Parameter(Mandatory=$true, Position=6, ValueFromPipeline=$false)]
|
||||
[string]$adminUserName,
|
||||
|
||||
# The password of the admin account
|
||||
[Parameter(Mandatory=$true, Position=7, ValueFromPipeline=$false)]
|
||||
[string]$adminUserPassword,
|
||||
|
||||
# The name of the Virtual Network the Virtual Machine should be provisioned into. The Virtual Network needs to be in the same location as the storage account. Please note that this will not create a Virtual Network
|
||||
[Parameter(Mandatory=$false, Position=8, ValueFromPipeline=$false)]
|
||||
[string]$vnetName,
|
||||
|
||||
# The subnet names of the Virtual Network the Virtual Machine should be provisioned into.
|
||||
[Parameter(Mandatory=$false, Position=9, ValueFromPipeline=$false)]
|
||||
[string[]]$subnetNames
|
||||
)
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Remove the specified Cloud Service and clean up the deployments under it.
|
||||
.DESCRIPTION
|
||||
Remove the specified Cloud Service and clean up the deployments under it.
|
||||
.INPUTS
|
||||
$serviceName - The Cloud Service name.
|
||||
.OUTPUTS
|
||||
None.
|
||||
#>
|
||||
|
||||
function CleanupCloudService
|
||||
{
|
||||
param(
|
||||
# The Cloud Service Name
|
||||
[string]$serviceName
|
||||
)
|
||||
|
||||
$slots = @("Staging", "Production")
|
||||
|
||||
foreach($slot in $slots)
|
||||
{
|
||||
$deployment = Get-AzureDeployment -Slot $slot -ServiceName $serviceName -ErrorAction Ignore
|
||||
|
||||
if($deployment -ne $null)
|
||||
{
|
||||
$machines = Get-AzureVM -ServiceName $serviceName -ErrorAction Ignore
|
||||
|
||||
if($machines -ne $null)
|
||||
{
|
||||
foreach($machine in $machines)
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to remove virtual machine $($machine.Name)."
|
||||
Remove-AzureVM -Name $machine.Name -ServiceName $serviceName
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to remove deployment $($deployment.Name)."
|
||||
Remove-AzureDeployment -ServiceName $serviceName -Slot $slot -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): Start to remove cloud service $serviceName."
|
||||
Remove-AzureService -ServiceName $serviceName -Force
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a new Virtual Machine.
|
||||
.DESCRIPTION
|
||||
Create a new Virtual Machine. If there exits a Cloud Service with the same name, it will be removed along with its deployments.
|
||||
.INPUTS
|
||||
$imageName - The name of the base Virtual Machine image.
|
||||
$storageAccountName - The name of the Storage Account which will be used to store the Virtual Machine.
|
||||
$serviceName - The name of the Cloud Service for the Virtual Machine.
|
||||
$vmName - The name of the Virtual Machine.
|
||||
$vmSize - The size of the Virtual Machine.
|
||||
$adminUserName - The name of the admin account.
|
||||
$adminUserPassword - The password of the admin account.
|
||||
$vnetName - The name of the Virtual Network.
|
||||
$subnetNames - The subnet names of the Virtual Network.
|
||||
.OUTPUTS
|
||||
None.
|
||||
#>
|
||||
|
||||
function CreateVirtualMachine
|
||||
{
|
||||
param(
|
||||
# The name of the base Virtual Machine image
|
||||
[string]$imageName,
|
||||
|
||||
# The name of the Storage Account which will be used to store the Virtual Machine
|
||||
[string]$storageAccountName,
|
||||
|
||||
# The name of the Cloud Service for the Virtual Machine
|
||||
[string]$serviceName,
|
||||
|
||||
# The name of the Virtual Machine
|
||||
[string]$vmName,
|
||||
|
||||
# The size of the Virtual Machine
|
||||
[string]$vmSize,
|
||||
|
||||
# The name of the admin account
|
||||
[string]$adminUserName,
|
||||
|
||||
# The password of the admin account
|
||||
[string]$adminUserPassword,
|
||||
|
||||
# The name of the Virtual Network
|
||||
[string]$vnetName,
|
||||
|
||||
# The subnet names of the Virtual Network
|
||||
[string[]]$subnetNames
|
||||
)
|
||||
|
||||
# Check if the image exists
|
||||
$image = Get-AzureVMImage -ImageName $imageName
|
||||
if(!$image)
|
||||
{
|
||||
Write-Host "$(Get-Date): $imageName doesn't exist."
|
||||
return
|
||||
}
|
||||
|
||||
$storageAccount = Get-AzureStorageAccount -StorageAccountName $storageAccountName
|
||||
if(!$storageAccount)
|
||||
{
|
||||
Write-Host "$(Get-Date): $storageAccountName doesn't exist. You can run New-AzureStorageAccount to create a new one."
|
||||
return
|
||||
}
|
||||
|
||||
$vnetSite = $null
|
||||
if(![string]::IsNullOrEmpty($vnetName))
|
||||
{
|
||||
$vnetSite = Get-AzureVNetSite -VNetName $vnetName
|
||||
if(!$vnetSite)
|
||||
{
|
||||
Write-Host "$(Get-Date): $vnetName doesn't exist."
|
||||
return
|
||||
}
|
||||
|
||||
$vnetLocation = (Get-AzureAffinityGroup -Name $vnetSite.AffinityGroup).Location
|
||||
$storageAccountLocation = $storageAccount.Location
|
||||
if(!$storageAccountLocation)
|
||||
{
|
||||
$storageAccountLocation = (Get-AzureAffinityGroup -Name $storageAccount.AffinityGroup).Location
|
||||
}
|
||||
|
||||
if($vnetLocation -ne $storageAccountLocation)
|
||||
{
|
||||
Write-Host "$(Get-Date): $vnetName should be in the same location as $storageAccountName."
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
$cloudService = Get-AzureService -ServiceName $serviceName -ErrorAction Ignore
|
||||
|
||||
if($cloudService -ne $null)
|
||||
{
|
||||
Write-Host "$(Get-Date): Start to clean up existing cloud service $serviceName."
|
||||
CleanupCloudService $serviceName
|
||||
}
|
||||
|
||||
$vmConfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmSize -ImageName $imageName |
|
||||
Add-AzureProvisioningConfig -Windows -EnableWinRMHttp -AdminUsername $adminUserName -Password $adminUserPassword
|
||||
|
||||
Write-Host "$(Get-Date): Start to create virtual machine: $vmName."
|
||||
|
||||
if(!$vnetSite)
|
||||
{
|
||||
if(!$storageAccount.Location)
|
||||
{
|
||||
New-AzureVM -VMs $vmConfig -AffinityGroup $storageAccount.AffinityGroup -ServiceName $serviceName -WaitForBoot
|
||||
}
|
||||
else
|
||||
{
|
||||
New-AzureVM -VMs $vmConfig -Location $storageAccount.Location -ServiceName $serviceName -WaitForBoot
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($subnetNames -ne $null)
|
||||
{
|
||||
$vmConfig = Set-AzureSubnet -VM $vmConfig -SubnetNames $subnetNames
|
||||
}
|
||||
|
||||
New-AzureVM -VMs $vmConfig -VNetName $vnetName -AffinityGroup $vnetSite.AffinityGroup -ServiceName $serviceName -WaitForBoot
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
Download and install a WinRm certificate to the certficate store
|
||||
.DESCRIPTION
|
||||
Gets the WinRM certificate from the specified Virtual Machine, and install it on the LocalMachine store.
|
||||
.INPUTS
|
||||
$serviceName - The name of the Cloud Service.
|
||||
$vmName - The name of the Virtual Machine.
|
||||
.OUTPUTS
|
||||
NONE
|
||||
#>
|
||||
|
||||
function DownloadAndInstallWinRMCert
|
||||
{
|
||||
param(
|
||||
# The name of the Cloud Service
|
||||
[string]$serviceName,
|
||||
|
||||
# The name of the Virtual Machine
|
||||
[string]$vmName
|
||||
)
|
||||
|
||||
$winRMCert = (Get-AzureVM -ServiceName $serviceName -Name $vmname | select -ExpandProperty vm).DefaultWinRMCertificateThumbprint
|
||||
|
||||
$AzureX509cert = Get-AzureCertificate -ServiceName $serviceName -Thumbprint $winRMCert -ThumbprintAlgorithm sha1
|
||||
|
||||
$certTempFile = [IO.Path]::GetTempFileName()
|
||||
|
||||
$AzureX509cert.Data | Out-File $certTempFile
|
||||
|
||||
$certToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $certTempFile
|
||||
|
||||
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "LocalMachine"
|
||||
|
||||
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
|
||||
|
||||
$exists = $false
|
||||
foreach($certificate in $store.Certificates)
|
||||
{
|
||||
if($certificate.Thumbprint -eq $certToImport.Thumbprint)
|
||||
{
|
||||
$exists = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if(!$exists)
|
||||
{
|
||||
$store.Add($certToImport)
|
||||
}
|
||||
|
||||
$store.Close()
|
||||
|
||||
Remove-Item $certTempFile
|
||||
}
|
||||
|
||||
# Prepare azure environement
|
||||
|
||||
Import-AzurePublishSettingsFile -PublishSettingsFile $azurePublishSettingsFile -ErrorAction Stop
|
||||
Select-AzureSubscription -SubscriptionName $subscriptionName -ErrorAction Stop
|
||||
Set-AzureSubscription -SubscriptionName $subscriptionName -CurrentStorageAccount $storageAccountName -ErrorAction Stop
|
||||
|
||||
# Use vmName as serviceName. Clean up the existing one before creation.
|
||||
$serviceName = $vmName
|
||||
CreateVirtualMachine $imageName $storageAccountName $serviceName $vmName $vmSize $adminUserName $adminUserPassword $vnetName $subnetNames
|
||||
|
||||
Write-Host "$(Get-Date): Start to download and install the remoting cert (self-signed) to local machine trusted root."
|
||||
DownloadAndInstallWinRMCert $serviceName $vmName
|
||||
|
||||
$remotingUri = (Get-AzureWinRMUri -ServiceName $serviceName -Name $vmName).AbsoluteUri
|
||||
$remotingCredential = New-Object System.Management.Automation.PSCredential "$vmName\$adminUserName", (ConvertTo-SecureString -String $adminUserPassword -AsPlainText -Force)
|
||||
|
||||
Write-Host "$(Get-Date): Start to configure SQL Server via powershell remoting uri: $remotingUri."
|
||||
|
||||
$configureSQLServerScript =
|
||||
{
|
||||
$configureSQLServerScript = Join-Path -Path $env:SystemDrive -ChildPath "ConfigureDeveloperDesktop\Scripts\ConfigureSQLServer.ps1"
|
||||
|
||||
$result = & $configureSQLServerScript
|
||||
|
||||
return $result
|
||||
}
|
||||
$result = Invoke-Command -ConnectionUri $remotingUri -Credential $remotingCredential -ScriptBlock $configureSQLServerScript
|
||||
|
||||
if($result -ne 0)
|
||||
{
|
||||
Write-Host "$(Get-Date): Failed to configure SQL Server."
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "$(Get-Date): Please run Get-AzureRemoteDesktopFile to connect the machine and login as $vmName\$adminUserName."
|
|
@ -0,0 +1,18 @@
|
|||
# CreateNewADDSForest #
|
||||
|
||||
## Description ##
|
||||
Create a new Virtual Machine with Active Directory Domain Services. It is based on the Windows Server 2012 image.
|
||||
|
||||
The script must be executed with elevated privileges.
|
||||
|
||||
## Scenario ##
|
||||
You want to create a new domain controller.
|
||||
|
||||
## Requirements ##
|
||||
- PowerShell Version 3.0
|
||||
- Windows Azure PowerShell August 2013
|
||||
|
||||
## See Also ##
|
||||
- CreateVNet.ps1
|
||||
- CreateSharePointDeveloperMachineInDomain.ps1
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# CreateSharePointDeveloperMachine #
|
||||
|
||||
## Description ##
|
||||
Create a new Virtual Machine for SharePoint development based on Visual Studio 2013 image.
|
||||
The script configures SQL Server Database Engine, Reporting Service, Analysis Service, Integration Service, Agent Service and create a defulat instance (MSSQLSERVER).
|
||||
The script also configures the following SharePoint environment in the Virtual Machine.
|
||||
- SharePoint configuration database: "SP2013_Configuration".
|
||||
- SharePoint Central Administration content database: "SP2013_Content_CentralAdministration" Central Administration Port: 11111 Central Administration Authentication: NTLM.
|
||||
- Web Application "Developer Test Site" on port 80 with default authentication provider. Using default app pool running under ¨ClocalSPFarmAccountName identity.
|
||||
- Root site collection "Developer Test Site Collection" Based on team site template. Primary site collection owner is the logged on user.
|
||||
|
||||
The script must be executed with elevated privileges.
|
||||
|
||||
## Scenario ##
|
||||
You want to create a development environment for SharePoint 2013 development on an Azure Virtual Machine.
|
||||
|
||||
## Requirements ##
|
||||
- Your subscription account needs to be MSDN subscriber to access the Visual Studio 2013 image.
|
||||
- PowerShell Version 3.0
|
||||
- Windows Azure PowerShell August 2013
|
||||
|
||||
## See Also ##
|
||||
- CreateWebSQLDeveloperMachine.ps1
|
||||
- CreateSharePointDeveloperMachineInDomain.ps1
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# CreateSharePointDeveloperMachineInDomain #
|
||||
|
||||
## Description ##
|
||||
Create a new Virtual Machine for SharePoint development in the specified domain based on Visual Studio 2013 image.
|
||||
The script configures SQL Server Database Engine, Reporting Service, Analysis Service, Integration Service, Agent Service and create a defulat instance (MSSQLSERVER).
|
||||
The script also configures the following SharePoint environment in the Virtual Machine.
|
||||
- SharePoint configuration database: "SP2013_Configuration".
|
||||
- SharePoint Central Administration content database: "SP2013_Content_CentralAdministration" Central Administration Port: 11111 Central Administration Authentication: NTLM.
|
||||
- Web Application "Developer Test Site" on port 80 with default authentication provider. Using default app pool running under ¨ClocalSPFarmAccountName identity.
|
||||
- Root site collection "Developer Test Site Collection" Based on team site template. Primary site collection owner is the logged on user.
|
||||
|
||||
Before executing, follow the steps to enable CredSSP on the client machine for delegation.
|
||||
- Run Set-WSManQuickConfig to make sure WinRM service is running.
|
||||
- Run Enable-WSManCredSSP -Role Client -DelegateComputer "*.cloudapp.net" Note: This command will fail if your client machine is connected to any networks defined as "Public network" in "Network and Sharing Center."
|
||||
- Enable delegating of fresh credentials using group policy editor on your client machine. Run gpedit.msc -> Computer Configuration -> Administrative Templates -> System -> Credentials Delegation and then change the state of "Allow Delegating Fresh Credentials with NTLM-only server authentication" to "Enabled."(Its default state will say, "Not configured.") In the Add Servers sections add : WSMAN/*.cloudapp.net. Click here for more details on enabling CredSSP.
|
||||
|
||||
The script must be executed with elevated privileges.
|
||||
|
||||
## Scenario ##
|
||||
You want to create a development environment for SharePoint 2013 development in a domain.
|
||||
|
||||
## Requirements ##
|
||||
- Your subscription account needs to be MSDN subscriber to access the Visual Studio 2013 image.
|
||||
- PowerShell Version 3.0
|
||||
- Windows Azure PowerShell August 2013
|
||||
|
||||
## See Also ##
|
||||
- CreateWebSQLDeveloperMachine.ps1
|
||||
- CreateSharePointDeveloperMachine.ps1
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# CreateVNet #
|
||||
|
||||
## Description ##
|
||||
Create a Virtual Network using the settings from the Virtual Network configuration file.
|
||||
|
||||
The configuration file follows the schema definition which can be found in http://msdn.microsoft.com/en-us/library/windowsazure/jj157100.aspx.
|
||||
Here is an example:
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<NetworkConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration">
|
||||
<VirtualNetworkConfiguration>
|
||||
<VirtualNetworkSites>
|
||||
<VirtualNetworkSite name="VNet1" AffinityGroup="AffinityGroup1">
|
||||
<AddressSpace>
|
||||
<AddressPrefix>10.0.0.0/20</AddressPrefix>
|
||||
</AddressSpace>
|
||||
<Subnets>
|
||||
<Subnet name="Subnet1">
|
||||
<AddressPrefix>10.0.0.0/28</AddressPrefix>
|
||||
</Subnet>
|
||||
</Subnets>
|
||||
</VirtualNetworkSite>
|
||||
</VirtualNetworkSites>
|
||||
</VirtualNetworkConfiguration>
|
||||
</NetworkConfiguration>
|
||||
|
||||
## Scenario ##
|
||||
You want to create a Virtual Network on Windows Azure.
|
||||
|
||||
## Requirements ##
|
||||
- PowerShell Version 3.0
|
||||
- Windows Azure PowerShell June 2013
|
||||
|
||||
## See Also ##
|
||||
- CreateNewADDSForest.ps1
|
||||
- CreateWebSQLDeveloperMachine.ps1
|
||||
- CreateSharePointDeveloperMachine.ps1
|
||||
- CreateSharePointDeveloperMachineInDomain.ps1
|
|
@ -0,0 +1,19 @@
|
|||
# CreateWebSQLDeveloperMachineInDomain #
|
||||
|
||||
## Description ##
|
||||
Create a new Virtual Machine for Web and SQL development based on Visual Studio 2013 image.
|
||||
The script configures SQL Server Database Engine, Reporting Service, Analysis Service, Integration Service, Agent Service and create a defulat instance (MSSQLSERVER).
|
||||
|
||||
The script must be executed with elevated privileges.
|
||||
|
||||
## Scenario ##
|
||||
You want to create a development environment for Web/SQL development on an Azure Virtual Machine.
|
||||
|
||||
## Requirements ##
|
||||
- Your subscription account needs to be MSDN subscriber to access the Visual Studio 2013 image.
|
||||
- PowerShell Version 3.0
|
||||
- Windows Azure PowerShell August 2013
|
||||
|
||||
## See Also ##
|
||||
- CreateSharePointDeveloperMachine.ps1
|
||||
- CreateSharePointDeveloperMachineInDomain.ps1
|
Загрузка…
Ссылка в новой задаче