PowerShell : Déploiement d’une infrastructure SharePoint
Comme promis suite à l’IT Camp “SQL Server /SharePoint/Windows Intune, les scénarios d’usage en mode Cloud hybride” du mercredi 18 Septembre 2013, voici le script PowerShell permettant le déploiement automatique des machines virtuelles dans le Cloud Azure. Le script va déployer l’infrastructure ci-dessous. La machine SQL comportera un disque pour les données et un disque pour les journaux de transactions. Les binaires de SharePoint seront installés, mais il sera nécessaire de terminer manuellement l’installation via l’assistant de SharePoint.
Les pré-requis pour faire fonctionner le script sont les suivants :
- Avoir un abonnement Azure (version d’essai 1 mois : https://www.windowsazure.com/en-us/pricing/free-trial/)
- Avoir un service de Cloud déjà créé (détail dans cet article)
- Avoir un réseau virtuel déjà créé (détail dans cet article)
Cet article est composé de la manière suivante :
- Création d’un service de Cloud
- Création d’un réseau virtuel
- Le script
Création du service de Cloud
Après s’être connecté au portail Azure (https://manage.windowsazure.com), cliquez sur le bouton « + Nouveau »
Dans le menu « Nouveau », cliquez sur « Calcul | Service de Cloud computing | création rapide ». Puis renseignez les champs « URL » et « Région ou groupes d’affinités »
Le nouveau service de Cloud apparait alors dans la liste des services de Cloud. Dans cet exemple, mon service de Cloud se nomme « AutoDeployFr ».
Création du réseau Virtuel
Cliquez sur le bouton « + Nouveau », puis sur « Services de réseau | Réseau virtuel | Création personnalisée »
Dans la première fenêtre « Créer un réseau virtuel », donnez un nom à votre réseau et déterminez un groupe d’affinités. Puis cliquez sur la flèche en bas à droite.
Dans la deuxième fenêtre, définissez un DNS. Dans cet exemple j’ai défini un DNS avec le nom « AutoDeployDNS » et une adresse IP 192.168.0.4. Puis cliquez sur la flèche en bas à droite.
Dans la troisième fenêtre définissez les adresses de votre réseau et de vos sous réseaux. Cliquez sur pour valider la création du réseau virtuel.
Attention, les noms des sous réseaux seront utilisés dans le script.
Voici une copie du réseau virtuel que j’ai créé pour cet exemple.
Le script
Voici le script que j’ai essayé de commenter au maximum. Avant d’exécuter le script, vérifiez que le nom des images virtuelles n’a pas changé entre temps.
Pour ce faire utilisez la commande Power Shell : Get-AzureVMImage | select Image. Puis mettez éventuellement à jour le nom des images virtuelles. Ci-dessous un exemple de nom des images :
Pensez aussi à renommer les différentes variables.
Le script donc :
#Script de déploiement de machines SharePoint et SQL avec AD et 1 compte d'installation
cls
# Si le fichier Azure.psd1 est manquant, Windows Azure PowerShell est téléchargeable ici:
# https://go.microsoft.com/?linkid=9811175&clcid=0x409
Import-Module "C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure\Azure.psd1"
#region Configuration du compte AZURE à utiliser
#Le fichier PublishSettings peut se récupérer sur ce site "https://windows.azure.com/download/publishprofile.aspx"
Import-AzurePublishSettingsFile 'C:\Users\franmer\Documents\PowerShell\PublishSettings\MS'
Set-AzureSubscription -SubscriptionName 'Windows Azure Internal Consumption' -CurrentStorageAccount franmerstorage
Select-AzureSubscription -SubscriptionName 'Windows Azure Internal Consumption'
#endregion
#region déclaration des paramètres
# Définition du ServiceName et du réseau virtuel (déjà existants dans Azure)
$serviceName = 'AutoDeployFr'
$virtualNetworkName = 'AutoDeployNetwork'
#Renseignement des sous-réseaux présents dans le réseau virtuel Azure.
#Dans cet exemple, le réseau "AutoDeployNetWork" dispose de 3 sous réseaux "DCSubnet", "SQLSubnet", "SP2013Subnet"
#Le nom de ces subnets doivent être identique à ceux de votre réseau virtuelle crée via le portail Azure
$AzureDCSubNet = 'DCSubnet'
$SQLSubnet ='SQLSubnet'
$SPSubnet = 'SP2013Subnet'
#Définition du nom de l'administrateur du domaine et du nom du domaine
$adminUsername = 'franmer'
$adminPassword='Pass@word1'
$domainName = 'ITCamp.demo.com'
$ShortDomainName = 'ITCamp'
#Définition du compte d'installation de SQL et SharePoint
$InstallUser = 'InstallUserfranmer'
$PassWordInstallUser = 'Pass@word1'
$SecureStringPassWordInstallUser = ConvertTo-SecureString –String $PassWordInstallUser –AsPlainText -Force
#Définition des images à utiliser
#les images peuvent être récupérées avec la commande : Get-AzureVMImage | select ImageName
#ATTENTION, les noms des images peuvent changer en fonction des mises à jour !!
$WindowsServer2012ImageName = 'bd507d3a70934695bc2128e3e5a255ba__RightImage-Windows-2012-x64-v13.4.12.2'
$WindowsAndSqlServerImageName = 'fb83b3509582419d99629ce476bcb5c8__Microsoft-SQL-Server-2012SP1-Enterprise-CY13SU04-SQL2012-SP1-11.0.3350.0-Win2012'
$WindowsandSharePoint2013Trial = 'c6e0f177abd8496e934234bd27f46c5d__SharePoint-2013-Trial-9-18-2013'
#Définition du domaine controlleur
$DcVmName = 'ITCampDC1'
$FullDomainName = 'ITCamp.demo.com'
$DCVMSize = 'Small'
$AvailabilitySetName = 'ITCampDC'
#Définition de la machine SQL
$SQLVMSize ='Medium'
$SQLprefix = 'ITCampSQL'
$SizeSQLDataDisk = 100 #Gb
$SizeSQLLogsDisk = 100 #Gb
$defaultSqlDataFolder = ':\FranmerDATA' #Sans la lettre du disque
$defaultSqlLogsFolder = ':\FranmerLOGS' #Sans la lettre du disque
$installerDatabaseUsername = $ShortDomainName + "\" + $InstallUser
$installerDatabasePassword = 'Pass@word1'
$installerDomainUsername = $ShortDomainName + '\franmer'
$NbSQLServer = 1
Write-Host $installerDatabaseUsername
Write-Host $installerDomainUsername
#Définition de la machine SharePoint
$SPprefix = 'ITCampSP'
$LBSetName = 'SPWebLB'
$SPVMSize = 'Medium'
$NbSPServer = 1
#Conversion de adminPassword en secureString
$SecureStringadminPassword = ConvertTo-SecureString –String $adminPassword –AsPlainText -Force
$credential = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $adminUsername, $SecureStringadminPassword
#Création d'un collection vide d'images virtuelles
$vms = @()
#endregion
#region create domain controller
$StartTime = Get-Date
write-host "début à : " $StartTime
Write-Host "creating $DcVmName"
$adminPort = 52101
#create a new VM Config
$newVM = `
New-AzureVMConfig -ImageName $WindowsServer2012ImageName -InstanceSize $DCVMSize -Name $DcVmName `
-AvailabilitySetName $AvailabilitySetName -DiskLabel "${DcVmName}os" `
-HostCaching ReadWrite -Label "$DcVmName" |
Add-AzureProvisioningConfig -Windows -AdminUsername $adminUsername -Password $adminPassword -NoRDPEndpoint |
Add-AzureDataDisk -CreateNew -DiskSizeInGB 30 -DiskLabel "${DcVmName}data1" -LUN 0 |
Add-AzureEndpoint -LocalPort 3389 -Name "RDP" -Protocol tcp -PublicPort $adminPort |
Set-AzureSubnet $AzureDCSubNet
#add the VM config to the collection
$vms += ,$newVM
#show the collection
$vms | format-table
#create the VM and wait for boot
New-AzureVM -ServiceName $serviceName -VMs $vms -VNetName $virtualNetworkName -WaitForBoot
Start-Sleep -Seconds 60
#endregion
#region function definition for PowerShell remoting
write-host "Definition for PowerShell remoting"
function InstallWinRMCert($serviceName, $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()
Write-Host $certTempFile
$AzureX509cert.Data | Out-File $certTempFile
# Target The Cert That Needs To Be Imported
$CertToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $certTempFile
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "LocalMachine"
$store.Certificates.Count
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$store.Add($CertToImport)
$store.Close()
Remove-Item $certTempFile
}
#endregion
#region Installation des fonctionnalités sur le DC
#Installation de ADDS
write-host "Installation de ADDS"
$uri = Get-AzureWinRMUri -ServiceName $serviceName -Name $DcVmName
InstallWinRMCert $serviceName $DcVmName
# Utilisation du PowerShell dans la machine virtuelle distante (le domaine controlleur)
Invoke-Command -ConnectionUri $uri.ToString() -Credential $credential `
-ArgumentList $SecureStringadminPassword -ScriptBlock `
{
param($SecureStringadminPassword)
$logLabel = $((get-date).ToString("yyyyMMddHHmmss"))
$logPath = "$env:TEMP\init-webservervm_webserver_install_log_$logLabel.txt"
Import-Module -Name ServerManager
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools -LogPath $logPath
$disks = Get-Disk | where { $_.NumberOfPartitions -eq 0 }
foreach ($d in $disks)
{
# there should be one disk only
$diskNumber = $d.Number
echo "will format disk $diskNumber"
Initialize-Disk $diskNumber
New-Partition -DiskNumber $diskNumber -UseMaximumSize -AssignDriveLetter
Format-Volume -DriveLetter F -Confirm:$False
get-volume -DriveLetter F
}
Import-module ADDSDeployment
Install-ADDSForest -DomainName "ITCamp.demo.com" -InstallDns:$true -DatabasePath "F:\NTDS" `
-LogPath "F:\NTDS" -SysvolPath "F:\SYSVOL" -NoRebootOnCompletion:$false -Force:$true `
-SafeModeAdministratorPassword $SecureStringadminPassword
}
#endregion
#region wait for reboot and start a new collection
Start-Sleep -Seconds 60
$DcVm = Get-AzureVM -ServiceName $serviceName -Name $DcVmName
While ($DcVm.InstanceStatus -ne "ReadyRole")
{
write-host "Waiting for DC to be ready... Current Status = " $DcVm.InstanceStatus
Start-Sleep -Seconds 15
$DcVm = Get-AzureVM -ServiceName $serviceName -Name $DcVmName
}
$vms = @()
#endregion
#region Ajout d'un compte utilisateur dans l'AD pour réaliser les installations de SQL Server et SharePoint
write-host "Ajout d'un utilisateur dans le domaine"
Invoke-Command -ConnectionUri $uri.ToString() -Credential $credential -ArgumentList $InstallUser, $SecureStringPassWordInstallUser -ScriptBlock {
param($InstallUser , $SecureStringPassWordInstallUser)
#$pwd = ConvertTo-SecureString "Pass@word1" -AsPlainText -Force
New-ADUser -Name $InstallUser -AccountPassword $SecureStringPassWordInstallUser -PasswordNeverExpires $true -ChangePasswordAtLogon $false -Enabled $true
}
#endregion
#================================================================================================================
#region Installation de SQL Server
for($i=1; $i -le $NbSQLServer; $i++)
{
Write-Host "creating $SQLprefix${i}"
$adminPort = 53100 + $i
#Création de la configuration de la VM
$newVM = `
New-AzureVMConfig -ImageName $WindowsAndSqlServerImageName -InstanceSize $SQLVMSize -Name "$SQLprefix$i" `
-AvailabilitySetName "$SQLprefix" -DiskLabel "$SQLprefix${i}os" `
-HostCaching ReadWrite -Label "$SQLprefix${i}" |
Add-AzureProvisioningConfig -WindowsDomain -AdminUsername $adminUsername -Password $adminPassword `
-Domain $ShortDomainName -DomainUserName $adminUsername -DomainPassword $adminPassword -JoinDomain $domainName `
-NoRDPEndpoint |
Add-AzureDataDisk -CreateNew -DiskSizeInGB $SizeSQLDataDisk -LUN 0 -DiskLabel "$SQLprefix${i}Data" |
Add-AzureDataDisk -CreateNew -DiskSizeInGB $SizeSQLLogsDisk -LUN 1 -DiskLabel "$SQLprefix${i}Logs" |
Add-AzureEndpoint -LocalPort 3389 -Name "RDP" -Protocol tcp -PublicPort $adminPort |
Set-AzureSubnet $SQLSubnet
#add the VM config to the collection
$vms += ,$newVM
}
#endregion
#region SharePoint Server
for($i=1; $i -le $NbSPServer; $i++)
{
Write-Host "creating $SPprefix$i"
$adminPort = 52200 + $i
#Création de la configuration de la VM
$newVM = `
New-AzureVMConfig -ImageName $WindowsandSharePoint2013Trial -InstanceSize $SPVMSize -Name "$SPprefix$i" `
-AvailabilitySetName "$SPprefix" -DiskLabel "$SPprefix${i}os" `
-HostCaching ReadWrite -Label "$SPprefix${i}" |
Add-AzureProvisioningConfig -WindowsDomain -AdminUsername $adminUsername -Password $adminPassword `
-Domain $ShortDomainName -DomainUserName $adminUsername -DomainPassword $adminPassword -JoinDomain $domainName `
-NoRDPEndpoint |
Add-AzureDataDisk -CreateNew -DiskSizeInGB 50 -LUN 0 -DiskLabel "$SPprefix${i}data1" |
Add-AzureEndpoint -LocalPort 3389 -Name "RDP" -Protocol tcp -PublicPort $adminPort |
Add-AzureEndpoint -LocalPort 80 -Name "Web" -Protocol tcp -PublicPort 80 -LBSetName $LBSetName -ProbePort 8080 -ProbeProtocol http -ProbePath '/' |
Set-AzureSubnet $SPSubnet
#Rajout de la VM dans le collection
$vms += ,$newVM
}
#endregion
#region create SharePoint and SQL Server VMs and wait for them to boot
#show the collection
$vms | format-table
#create the VM and wait for boot
New-AzureVM -ServiceName $serviceName -VMs $vms -WaitForBoot
#endregion
#region install features on SharePoint Servers
for($i=1; $i -le $NbSPServer; $i++)
{
$vmName = "$SPprefix$i"
$uri = Get-AzureWinRMUri -ServiceName $serviceName -Name $vmName
InstallWinRMCert $serviceName $vmName
# Use native PowerShell Cmdlet to execute a script block on the remote virtual machine
Invoke-Command -ConnectionUri $uri.ToString() -Credential $credential -ScriptBlock `
{
$logLabel = $((get-date).ToString("yyyyMMddHHmmss"))
$logPath = "$env:TEMP\init-webservervm_webserver_install_log_$logLabel.txt"
Import-Module -Name ServerManager
Install-WindowsFeature -Name Web-Server -IncludeAllSubFeature -IncludeManagementTools -LogPath $logPath
}
}
#endregion
#region Rajout d'un compte d'installation du domaine dans la machine virtuelle SQL
#$vmType = 'Small'
#$highAvailabilityType = 'None'
$InstallUser = 'InstallUserfranmer'
$PassWordInstallUser = 'Pass@word1'
for($i=1; $i -le $NbSQLServer; $i++)
{
$uriSQL = Get-AzureWinRMUri -serviceName $serviceName -Name $SQLprefix${i}
Invoke-Command -ConnectionUri $uriSQL.ToString() -Credential $credential -ArgumentList $installerDatabaseUsername, $installerDatabasePassword, $installerDomainUsername, $defaultSqlDataFolder,
$defaultSqlLogsFolder -ScriptBlock {
param($installerDatabaseUsername, $installerDatabasePassword, $installerDomainUsername, $defaultSqlDataFolder, $defaultSqlLogsFolder)
Import-Module ServerManager
Set-ExecutionPolicy Unrestricted
net localgroup administrators "$installerDomainUsername" /Add
Start-Sleep -Seconds 20
# Formatage des disques durs
Write-host "Formatage des disques durs"
for($i=2; $i -le 3; $i++)
{
Initialize-Disk -Number $i -PartitionStyle MBR
$NewPartition = New-Partition -DiskNumber $i -UseMaximumSize -AssignDriveLetter
if ($i -match 2)
{
Write-Host "Formatage du disque des données"
$SQLPath = $NewPartition.DriveLetter + $defaultSqlDataFolder
$DataDiskLetter = $NewPartition.DriveLetter
}
Else
{
Write-Host "Formatage du disque des journaux de transactions"
$SQLPath = $NewPartition.DriveLetter + $defaultSqlLogsFolder
$LogsDiskLetter = $NewPartition.DriveLetter
}
Format-Volume -DriveLetter $NewPartition.DriveLetter -FileSystem NTFS -NewFileSystemLabel $SQLPath -Confirm:$False
}
Write-Host "Configuring firewall..."
netsh advfirewall firewall add rule name='SQL Server (TCP-In)' program='C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Binn\sqlservr.exe' dir=in action=allow protocol=TCP
Write-Host "Firewall configured."
Write-Host "Configuring database permissions and options..."
Import-Module "sqlps" -Verbose
Write-Host "Module sqlps importé"
Invoke-Sqlcmd -ServerInstance $env:COMPUTERNAME -Database master -Query `
"
USE [master]
IF Not EXISTS (SELECT name FROM master.sys.server_principals WHERE name = '$installerDatabaseUsername')
BEGIN
CREATE LOGIN [$installerDatabaseUsername] WITH PASSWORD='$installerDatabasePassword'
EXEC sp_addsrvrolemember '$installerDatabaseUsername', 'dbcreator'
EXEC sp_addsrvrolemember '$installerDatabaseUsername', 'securityadmin'
END
IF Not EXISTS (SELECT name FROM master.sys.server_principals WHERE name = '$installerDomainUsername')
BEGIN
CREATE LOGIN [$installerDomainUsername] FROM WINDOWS
EXEC sp_addsrvrolemember '$installerDomainUsername', 'sysadmin'
END
EXEC sp_addsrvrolemember 'NT AUTHORITY\SYSTEM', 'sysadmin'
"
Invoke-Sqlcmd -ServerInstance $env:COMPUTERNAME -database master -Query `
"USE [master]
GO
sp_configure 'show advanced options', 1;RECONFIGURE WITH OVERRIDE;
GO
sp_configure 'max degree of parallelism', 1;RECONFIGURE WITH OVERRIDE;
GO"
Write-Host "Database configured."
Write-Host "Enabling mixed authentication mode and setting folder locations..."
$s = new-object ('Microsoft.SqlServer.Management.Smo.Server') $env:COMPUTERNAME
$s.Settings.LoginMode = [Microsoft.SqlServer.Management.Smo.ServerLoginMode]::Mixed
if(-not [string]::IsNullOrEmpty($defaultSqlDataFolder))
{
mkdir $DataDiskLetter$defaultSqlDataFolder
$s.Settings.DefaultFile = $DataDiskLetter+$defaultSqlDataFolder
}
if(-not [string]::IsNullOrEmpty($defaultSqlLogsFolder))
{
mkdir $LogsDiskLetter$defaultSqlLogsFolder
$s.Settings.DefaultLog = $LogsDiskLetter+$defaultSqlLogsFolder
}
$s.Alter()
Write-Host "Redémarrage service SQL (2)"
Restart-Service -Name MSSQLSERVER -Force
Write-Host "Mixed authentication mode enabled and folder locations set."
}
}
#endregion
$EndTime = Get-Date
Write-host "Fin à : "$EndTime
Sources :
- Blog MSDN Benjamin GUINEBERTIERE: https://blogs.msdn.com/b/benjguin/archive/2013/05/24/sample-automation-script-exemple-de-script-d-automatisation.aspx
- Blog MSDN Windows Azure: https://blogs.msdn.com/b/windowsazure/archive/2013/05/24/automating-sharepoint-deployments-in-windows-azure-using-powershell.aspx
Au plaisir de vous voir lors d’un IT Camp!
Pour tester Windows Server 2012, Windows 8, SQL Server 2012 et SQL Server 2014 CTP1, vous pouvez télécharger gratuitement la version d’évaluation disponible sous la forme :
· Windows Server 2012 :
- d'une image ISO : https://aka.ms/jeveuxwindows2012
- d'un fichier VHD avec un système préinstallé : https://aka.ms/jeveuxwindows2012
· SQL Server 2012 :
· Evaluation SQL Server 2014 CTP1 :
· Testez Azure gratuitement pendant un mois :