Cleaned up unused files
* removed outdated files * moved everything related to windows to contrib/windows * moved everything related to cirros to contrib/cirros Change-Id: Ibdffb96e25b94f545a836cb5df75beeae2b286a7
This commit is contained in:
parent
d38e097523
commit
f025daeebb
27
README.rst
27
README.rst
|
@ -2,20 +2,15 @@ Murano
|
|||
======
|
||||
Murano Project introduces an application catalog, which allows application
|
||||
developers and cloud administrators to publish various cloud-ready
|
||||
applications in a browsable categorised catalog, which may be used by the
|
||||
applications in a browsable categorised catalog, which may be used by the
|
||||
cloud users (including the inexperienced ones) to pick-up the needed
|
||||
applications and services and composes the reliable environments out of them
|
||||
in a “push-the-button” manner.
|
||||
in a "push-the-button" manner.
|
||||
|
||||
murano-deployment
|
||||
-----------------
|
||||
murano-deployment repository contains scripts and automation tools for
|
||||
various aspects of Murano deployment. The most noticeable parts of this
|
||||
repository are:
|
||||
|
||||
* Image builder helper for Windows platform;
|
||||
* Set of PowerShell scripts for deployment Windows environment;
|
||||
* Manifests for packaging Murano into .deb and .rpm packages.
|
||||
murano CI system.
|
||||
|
||||
Project Resources
|
||||
-----------------
|
||||
|
@ -24,19 +19,3 @@ Project Resources
|
|||
* `Code Review <https://review.openstack.org/>`__
|
||||
* `Sources <https://wiki.openstack.org/wiki/Murano/SourceCode>`__
|
||||
* `Developers Guide <http://murano-docs.github.io/latest/developers-guide/content/ch02.html>`__
|
||||
|
||||
How To Participate
|
||||
------------------
|
||||
If you would like to ask some questions or make proposals, feel free to reach
|
||||
us on #murano IRC channel at FreeNode. Typically somebody from our team will
|
||||
be online at IRC from 6:00 to 20:00 UTC. You can also contact Murano community
|
||||
directly by openstack-dev@lists.openstack.org adding [Murano] to a subject.
|
||||
|
||||
We’re holding public weekly meetings on Tuesdays at 17:00 UTC
|
||||
on #openstack-meeting-alt IRC channel at FreeNode.
|
||||
|
||||
If you want to contribute either to docs or to code, simply send us change
|
||||
request via `gerrit <https://review.openstack.org/>`__.
|
||||
You can `file bugs <https://bugs.launchpad.net/murano/+filebug>`__ and
|
||||
`register blueprints <https://blueprints.launchpad.net/murano/+addspec>`__ on
|
||||
Launchpad.
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
CloudBase-Init
|
||||
==============
|
||||
|
||||
A few modifications were made to the original CloudBase-Init deployment tools.
|
||||
They are stored under this folder.
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
* `Murano <http://murano.mirantis.com>`__
|
||||
* `CloudBase-Init <http://www.cloudbase.it/cloud-init-for-windows-instances/>`__
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
[DEFAULT]
|
||||
username=Admin
|
||||
groups=Administrators
|
||||
inject_user_password=false
|
||||
network_adapters=
|
||||
config_drive_raw_hdd=false
|
||||
config_drive_cdrom=false
|
||||
verbose=true
|
||||
logdir=C:\Program Files (x86)\Cloudbase Solutions\Cloudbase-Init\log\
|
||||
logfile=cloudbase-init.log
|
||||
plugins=cloudbaseinit.plugins.windows.userdata.UserDataPlugin
|
|
@ -1,37 +0,0 @@
|
|||
import codecs
|
||||
|
||||
from cloudbaseinit.osutils.factory import *
|
||||
from cloudbaseinit.plugins.base import *
|
||||
from cloudbaseinit.openstack.common import log as logging
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('agent_config_file', default='C:\\Murano\\Agent\\WindowsAgent.exe.config', help='')
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(opts)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SetHostNamePlugin(BasePlugin):
|
||||
def execute(self, service):
|
||||
meta_data = service.get_meta_data('openstack')
|
||||
if 'meta' not in meta_data:
|
||||
LOG.debug("Section 'meta' not found in metadata")
|
||||
return False
|
||||
|
||||
if 'agent_config_xml' not in meta_data['meta']:
|
||||
LOG.debug("Config for agent not found in metadata section")
|
||||
return False
|
||||
|
||||
try:
|
||||
configFile=codecs.open(CONF.agent_config_file, encoding='utf-8', mode='w+')
|
||||
configFile.write(meta_data['meta']['agent_config_xml'])
|
||||
configFile.close()
|
||||
except:
|
||||
LOG.error("Unable to update agent file.")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
from cloudbaseinit.osutils.factory import *
|
||||
from cloudbaseinit.plugins.base import *
|
||||
from cloudbaseinit.openstack.common import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SetHostNamePlugin(BasePlugin):
|
||||
def execute(self, service):
|
||||
meta_data = service.get_meta_data('openstack')
|
||||
if 'name' not in meta_data:
|
||||
LOG.debug('Name not found in metadata')
|
||||
return False
|
||||
|
||||
osutils = OSUtilsFactory().get_os_utils()
|
||||
|
||||
new_host_name = meta_data['name'].replace('.', '-')
|
||||
return osutils.set_host_name(new_host_name)
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
Import-Module CoreFunctions
|
||||
|
||||
$ModuleBase = "C:\Murano\Modules"
|
||||
|
||||
|
||||
$NewModule_Name = "ModuleName"
|
||||
$NewModule_Base64 = @'
|
||||
%BASE64_STRINGS%
|
||||
'@
|
||||
|
||||
|
||||
$AgentConfig_Path = "C:\Murano\Agent\WindowsAgent.exe.config"
|
||||
$AgentConfig_Base64 = @'
|
||||
%AGENT_CONFIG_BASE64%
|
||||
'@
|
||||
|
||||
|
||||
ConvertFrom-Base64String -Base64String $NewModule_Base64 -Path "$ModuleBase\$NewModule_Name.zip"
|
||||
Remove-Item -Path "$ModuleBase\$NewModule_Name" -Recurse -Force
|
||||
Expand-Zip -Path "$ModuleBase\$NewModule_Name.zip" -Destination "$ModuleBase\$NewModule_Name"
|
||||
|
||||
|
||||
Remove-Item -Path $AgentConfig_Path -Force
|
||||
ConvertFrom-Base64String -Base64String $NewModule_Base64 -Path $AgentConfig_Path
|
|
@ -1,119 +1,119 @@
|
|||
|
||||
function Register-WebApp {
|
||||
<#
|
||||
.LINKS
|
||||
|
||||
http://www.iis.net/learn/manage/powershell/powershell-snap-in-creating-web-sites-web-applications-virtual-directories-and-application-pools
|
||||
#>
|
||||
param (
|
||||
[String] $Source,
|
||||
[String] $Path = "C:\inetpub\wwwroot",
|
||||
[String] $Name = "",
|
||||
[String] $Username = "",
|
||||
[String] $Password = ""
|
||||
)
|
||||
|
||||
Import-Module WebAdministration
|
||||
|
||||
if ($Name -eq "") {
|
||||
$Name = @([IO.Path]::GetDirectoryName($Source) -split '\\')[-1]
|
||||
if ($Name -eq "wwwroot") {
|
||||
throw("Application pool name couldn't be 'wwwroot'.")
|
||||
}
|
||||
}
|
||||
else {
|
||||
$Path = [IO.Path]::Combine($Path, $Name)
|
||||
}
|
||||
|
||||
Copy-Item -Path $Source -Destination $Path -Recurse -Force
|
||||
|
||||
|
||||
# Create new application pool
|
||||
$AppPool = New-WebAppPool -Name $Name -Force
|
||||
#$AppPool = Get-Item "IIS:\AppPools\$Name"
|
||||
$AppPool.managedRuntimeVersion = 'v4.0'
|
||||
$AppPool.managedPipelineMode = 'Classic'
|
||||
$AppPool.processModel.loadUserProfile = $true
|
||||
$AppPool.processModel.logonType = 'LogonBatch'
|
||||
|
||||
#Set Identity type
|
||||
if ($Username -eq "") {
|
||||
$AppPool.processModel.identityType = 'ApplicationPoolIdentity'
|
||||
}
|
||||
else {
|
||||
$AppPool.processModel.identityType = 'SpecificUser'
|
||||
$AppPool.processModel.userName = $Username
|
||||
$AppPool.processModel.password = $Password
|
||||
$AppPool | Set-Item
|
||||
}
|
||||
|
||||
|
||||
# Create Website
|
||||
$WebSite = New-WebSite -Name $Name -Port 80 -HostHeader $Name -PhysicalPath $Path -Force
|
||||
#$WebSite = Get-Item "IIS:\Sites\$Name"
|
||||
|
||||
# Set the Application Pool
|
||||
Set-ItemProperty "IIS:\Sites\$Name" 'ApplicationPool' $Name
|
||||
|
||||
#Turn on Directory Browsing
|
||||
#Set-WebConfigurationProperty -Filter '/system.webServer/directoryBrowse' -Name 'enabled' -Value $true -PSPath "IIS:\Sites\$Name"
|
||||
|
||||
# Update Authentication
|
||||
#Set-WebConfigurationProperty -Filter '/system.WebServer/security/authentication/AnonymousAuthentication' -Name 'enabled' -Value $true -Location $name
|
||||
#Set-WebConfigurationProperty -Filter '/system.WebServer/security/authentication/windowsAuthentication' -Name 'enabled' -Value $false -Location $Name
|
||||
#Set-WebConfigurationProperty -Filter '/system.WebServer/security/authentication/basicAuthentication' -Name 'enabled' -Value $false -Location $Name
|
||||
|
||||
$WebSite.Start()
|
||||
|
||||
Add-Content -Path "C:\Windows\System32\Drivers\etc\hosts" -Value "127.0.0.1 $Name"
|
||||
}
|
||||
|
||||
|
||||
function Deploy-WebAppFromGit {
|
||||
param (
|
||||
[String] $URL,
|
||||
[String] $TempPath = [IO.Path]::Combine([IO.Path]::GetTempPath(), [IO.Path]::GetRandomFileName()),
|
||||
[String] $OutputPath = [IO.Path]::Combine([IO.Path]::GetTempPath(), [IO.Path]::GetRandomFileName())
|
||||
)
|
||||
Write-Log "TempPath = '$TempPath'"
|
||||
Write-Log "OutputPath = '$OutputPath'"
|
||||
|
||||
|
||||
# Fetch web application
|
||||
#----------------------
|
||||
Write-Log "Fetching sources from Git ..."
|
||||
|
||||
$null = New-Item -Path $TempPath -ItemType Container
|
||||
Exec -FilePath 'git.exe' -ArgumentList @('clone', $URL) -WorkingDir $TempPath -RedirectStreams
|
||||
|
||||
$Path = @(Get-ChildItem $TempPath)[0].FullName
|
||||
#----------------------
|
||||
|
||||
|
||||
# Build web application
|
||||
#----------------------
|
||||
Write-Log "Building sources ..."
|
||||
|
||||
$msbuild = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe"
|
||||
|
||||
$null = New-Item -Path $OutputPath -ItemType Container
|
||||
|
||||
$SlnFiles = @(Get-ChildItem -Path $Path -Filter *.sln -Recurse)
|
||||
|
||||
# Start new processs with additional env variables:
|
||||
#* VisualStudioVersion = "10.0"
|
||||
#* EnableNuGetPackageRestore = "true"
|
||||
Exec -FilePath $msbuild `
|
||||
-ArgumentList @($SlnFiles[0].FullName, "/p:OutputPath=$OutputPath") `
|
||||
-Environment @{'VisualStudioVersion' = '10.0'; 'EnableNuGetPackageRestore' = 'true'} `
|
||||
-RedirectStreams
|
||||
|
||||
$AppFolder = @(Get-ChildItem ([IO.Path]::Combine($OutputPath, '_PublishedWebsites')))[0]
|
||||
#----------------------
|
||||
|
||||
|
||||
# Install web application
|
||||
#------------------------
|
||||
Register-WebApp -Source $AppFolder.FullName -Name $AppFolder.Name
|
||||
#------------------------
|
||||
}
|
||||
|
||||
function Register-WebApp {
|
||||
<#
|
||||
.LINKS
|
||||
|
||||
http://www.iis.net/learn/manage/powershell/powershell-snap-in-creating-web-sites-web-applications-virtual-directories-and-application-pools
|
||||
#>
|
||||
param (
|
||||
[String] $Source,
|
||||
[String] $Path = "C:\inetpub\wwwroot",
|
||||
[String] $Name = "",
|
||||
[String] $Username = "",
|
||||
[String] $Password = ""
|
||||
)
|
||||
|
||||
Import-Module WebAdministration
|
||||
|
||||
if ($Name -eq "") {
|
||||
$Name = @([IO.Path]::GetDirectoryName($Source) -split '\\')[-1]
|
||||
if ($Name -eq "wwwroot") {
|
||||
throw("Application pool name couldn't be 'wwwroot'.")
|
||||
}
|
||||
}
|
||||
else {
|
||||
$Path = [IO.Path]::Combine($Path, $Name)
|
||||
}
|
||||
|
||||
Copy-Item -Path $Source -Destination $Path -Recurse -Force
|
||||
|
||||
|
||||
# Create new application pool
|
||||
$AppPool = New-WebAppPool -Name $Name -Force
|
||||
#$AppPool = Get-Item "IIS:\AppPools\$Name"
|
||||
$AppPool.managedRuntimeVersion = 'v4.0'
|
||||
$AppPool.managedPipelineMode = 'Classic'
|
||||
$AppPool.processModel.loadUserProfile = $true
|
||||
$AppPool.processModel.logonType = 'LogonBatch'
|
||||
|
||||
#Set Identity type
|
||||
if ($Username -eq "") {
|
||||
$AppPool.processModel.identityType = 'ApplicationPoolIdentity'
|
||||
}
|
||||
else {
|
||||
$AppPool.processModel.identityType = 'SpecificUser'
|
||||
$AppPool.processModel.userName = $Username
|
||||
$AppPool.processModel.password = $Password
|
||||
$AppPool | Set-Item
|
||||
}
|
||||
|
||||
|
||||
# Create Website
|
||||
$WebSite = New-WebSite -Name $Name -Port 80 -HostHeader $Name -PhysicalPath $Path -Force
|
||||
#$WebSite = Get-Item "IIS:\Sites\$Name"
|
||||
|
||||
# Set the Application Pool
|
||||
Set-ItemProperty "IIS:\Sites\$Name" 'ApplicationPool' $Name
|
||||
|
||||
#Turn on Directory Browsing
|
||||
#Set-WebConfigurationProperty -Filter '/system.webServer/directoryBrowse' -Name 'enabled' -Value $true -PSPath "IIS:\Sites\$Name"
|
||||
|
||||
# Update Authentication
|
||||
#Set-WebConfigurationProperty -Filter '/system.WebServer/security/authentication/AnonymousAuthentication' -Name 'enabled' -Value $true -Location $name
|
||||
#Set-WebConfigurationProperty -Filter '/system.WebServer/security/authentication/windowsAuthentication' -Name 'enabled' -Value $false -Location $Name
|
||||
#Set-WebConfigurationProperty -Filter '/system.WebServer/security/authentication/basicAuthentication' -Name 'enabled' -Value $false -Location $Name
|
||||
|
||||
$WebSite.Start()
|
||||
|
||||
Add-Content -Path "C:\Windows\System32\Drivers\etc\hosts" -Value "127.0.0.1 $Name"
|
||||
}
|
||||
|
||||
|
||||
function Deploy-WebAppFromGit {
|
||||
param (
|
||||
[String] $URL,
|
||||
[String] $TempPath = [IO.Path]::Combine([IO.Path]::GetTempPath(), [IO.Path]::GetRandomFileName()),
|
||||
[String] $OutputPath = [IO.Path]::Combine([IO.Path]::GetTempPath(), [IO.Path]::GetRandomFileName())
|
||||
)
|
||||
Write-Log "TempPath = '$TempPath'"
|
||||
Write-Log "OutputPath = '$OutputPath'"
|
||||
|
||||
|
||||
# Fetch web application
|
||||
#----------------------
|
||||
Write-Log "Fetching sources from Git ..."
|
||||
|
||||
$null = New-Item -Path $TempPath -ItemType Container
|
||||
Exec -FilePath 'git.exe' -ArgumentList @('clone', $URL) -WorkingDir $TempPath -RedirectStreams
|
||||
|
||||
$Path = @(Get-ChildItem $TempPath)[0].FullName
|
||||
#----------------------
|
||||
|
||||
|
||||
# Build web application
|
||||
#----------------------
|
||||
Write-Log "Building sources ..."
|
||||
|
||||
$msbuild = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe"
|
||||
|
||||
$null = New-Item -Path $OutputPath -ItemType Container
|
||||
|
||||
$SlnFiles = @(Get-ChildItem -Path $Path -Filter *.sln -Recurse)
|
||||
|
||||
# Start new processs with additional env variables:
|
||||
#* VisualStudioVersion = "10.0"
|
||||
#* EnableNuGetPackageRestore = "true"
|
||||
Exec -FilePath $msbuild `
|
||||
-ArgumentList @($SlnFiles[0].FullName, "/p:OutputPath=$OutputPath") `
|
||||
-Environment @{'VisualStudioVersion' = '10.0'; 'EnableNuGetPackageRestore' = 'true'} `
|
||||
-RedirectStreams
|
||||
|
||||
$AppFolder = @(Get-ChildItem ([IO.Path]::Combine($OutputPath, '_PublishedWebsites')))[0]
|
||||
#----------------------
|
||||
|
||||
|
||||
# Install web application
|
||||
#------------------------
|
||||
Register-WebApp -Source $AppFolder.FullName -Name $AppFolder.Name
|
||||
#------------------------
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
include Deploy-WebApp.ps1
|
||||
|
||||
call Import-Module Name="CoreFunctions"
|
||||
call Deploy-WebAppFromGit URL="git://github.com/Mirantis/murano-mvc-demo.git"
|
||||
|
||||
reboot 0
|
||||
|
||||
out out.json
|
||||
include Deploy-WebApp.ps1
|
||||
|
||||
call Import-Module Name="CoreFunctions"
|
||||
call Deploy-WebAppFromGit URL="git://github.com/Mirantis/murano-mvc-demo.git"
|
||||
|
||||
reboot 0
|
||||
|
||||
out out.json
|
|
@ -1,13 +1,13 @@
|
|||
Scripts:
|
||||
- Deploy-WebApp.ps1
|
||||
|
||||
Commands:
|
||||
- Name: Import-Module
|
||||
Arguments:
|
||||
Name: "CoreFunctions"
|
||||
|
||||
- Name: Deploy-WebAppFromGit
|
||||
Arguments:
|
||||
URL: "git://github.com/Mirantis/murano-mvc-demo.git"
|
||||
|
||||
RebootOnCompletion: 0
|
||||
Scripts:
|
||||
- Deploy-WebApp.ps1
|
||||
|
||||
Commands:
|
||||
- Name: Import-Module
|
||||
Arguments:
|
||||
Name: "CoreFunctions"
|
||||
|
||||
- Name: Deploy-WebAppFromGit
|
||||
Arguments:
|
||||
URL: "git://github.com/Mirantis/murano-mvc-demo.git"
|
||||
|
||||
RebootOnCompletion: 0
|
|
@ -1,9 +1,9 @@
|
|||
include Install-WebServer.ps1
|
||||
|
||||
call Import-Module Name="CoreFunctions"
|
||||
call Copy-Prerequisites Destination="C:\Prerequisites"
|
||||
call Install-WebServer PrerequisitesPath="C:\Prerequisites"
|
||||
|
||||
reboot 0
|
||||
|
||||
out out.json
|
||||
include Install-WebServer.ps1
|
||||
|
||||
call Import-Module Name="CoreFunctions"
|
||||
call Copy-Prerequisites Destination="C:\Prerequisites"
|
||||
call Install-WebServer PrerequisitesPath="C:\Prerequisites"
|
||||
|
||||
reboot 0
|
||||
|
||||
out out.json
|
|
@ -1,17 +1,17 @@
|
|||
Scripts:
|
||||
- Install-WebServer.ps1
|
||||
|
||||
Commands:
|
||||
- Name: Import-Module
|
||||
Arguments:
|
||||
Name: "CoreFunctions"
|
||||
|
||||
- Name: Copy-Prerequisites
|
||||
Arguments:
|
||||
Destination: "C:\Prerequisites"
|
||||
|
||||
- Name: Install-WebServer
|
||||
Arguments:
|
||||
PrerequisitesPath: "C:\Prerequisites"
|
||||
|
||||
RebootOnCompletion: 0
|
||||
Scripts:
|
||||
- Install-WebServer.ps1
|
||||
|
||||
Commands:
|
||||
- Name: Import-Module
|
||||
Arguments:
|
||||
Name: "CoreFunctions"
|
||||
|
||||
- Name: Copy-Prerequisites
|
||||
Arguments:
|
||||
Destination: "C:\Prerequisites"
|
||||
|
||||
- Name: Install-WebServer
|
||||
Arguments:
|
||||
PrerequisitesPath: "C:\Prerequisites"
|
||||
|
||||
RebootOnCompletion: 0
|
|
@ -1,89 +1,89 @@
|
|||
function Copy-Prerequisites {
|
||||
param (
|
||||
[String] $Path = '',
|
||||
[String] $Destination = ''
|
||||
)
|
||||
|
||||
Write-Log "--> Copy-Prerequisites"
|
||||
|
||||
if ($Destination -eq '') {
|
||||
throw("Copy-Prerequisites: Destination path not specified!")
|
||||
}
|
||||
|
||||
if ($Path -eq '') {
|
||||
$Path = [Environment]::GetEnvironmentVariable('MuranoFileShare')
|
||||
if ($Path -eq $null) {
|
||||
throw("Copy-Prerequisites: Unable to determine source path for prerequisites.")
|
||||
}
|
||||
}
|
||||
|
||||
Write-Log "Creating new PSDrive ..."
|
||||
New-PSDrive -Name 'P' -PSProvider 'FileSystem' -Root $Path | Out-Null
|
||||
Write-Log "Creating destination folder ..."
|
||||
New-Item -Path $Destination -ItemType Container -Force | Out-Null
|
||||
Write-Log "Copying items ..."
|
||||
Copy-Item -Path 'P:\Prerequisites\IIS' -Destination $Destination -Recurse -Force | Out-Null
|
||||
Write-Log "Removing PSDrive ..."
|
||||
Remove-PSDrive -Name 'P' -PSProvider 'FileSystem' -Force | Out-Null
|
||||
|
||||
Write-Log "<-- Copy-Prerequisites"
|
||||
}
|
||||
|
||||
|
||||
|
||||
function Install-WebServer {
|
||||
param (
|
||||
[String] $PrerequisitesPath
|
||||
)
|
||||
|
||||
Write-Log "--> Install-WebServer"
|
||||
|
||||
$FeatureList = @(
|
||||
'Web-Server',
|
||||
'Web-Net-Ext45',
|
||||
'Web-ASP',
|
||||
'Web-Asp-Net45',
|
||||
'Web-ISAPI-Ext',
|
||||
'Web-ISAPI-Filter',
|
||||
'Web-Includes'
|
||||
)
|
||||
|
||||
$PrerequisitesList = @(
|
||||
'AspNetMvc4Setup.exe',
|
||||
'WebApplications.exe'
|
||||
)
|
||||
|
||||
$PrerequisitesPath = [IO.Path]::Combine($PrerequisitesPath, 'IIS')
|
||||
|
||||
Write-Log "Validating prerequisites based on the list ..."
|
||||
foreach ($FileName in $PrerequisitesList) {
|
||||
$FilePath = [IO.Path]::Combine($PrerequisitesPath, $FileName)
|
||||
if (-not (Test-Path -Path $FilePath -PathType Leaf)) {
|
||||
throw("Prerequisite file not found: '$FilePath'")
|
||||
}
|
||||
}
|
||||
|
||||
Import-Module ServerManager
|
||||
|
||||
Write-Log "Installing Web Server ..."
|
||||
Install-WindowsFeature $FeatureList -IncludeManagementTools
|
||||
|
||||
Write-Log "Installing AspNetMvp4 ..."
|
||||
$Exec = Exec -FilePath $([IO.Path]::Combine($PrerequisitesPath, 'AspNetMvc4Setup.exe')) -ArgumentList '/q' -PassThru
|
||||
if ($Exec.ExitCode -ne 0) {
|
||||
throw("Installation of 'AspNetMvc4Setup.exe' failed. Process exit code '$($Exec.ExitCode)'")
|
||||
}
|
||||
|
||||
# Extract WebApplications folder with *.target files to
|
||||
# C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0
|
||||
Write-Log "Installing WebApplication targets ..."
|
||||
$WebApplicationsTargetsRoot = 'C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0'
|
||||
$null = New-Item -Path $WebApplicationsTargetsRoot -ItemType Container
|
||||
$Exec = Exec -FilePath $([IO.Path]::Combine($PrerequisitesPath, 'WebApplications.exe')) -ArgumentList @("-o`"$WebApplicationsTargetsRoot`"", '-y') -PassThru
|
||||
if ($Exec.ExitCode -ne 0) {
|
||||
throw("Installation of 'WebApplications.exe' failed. Process exit code '$($Exec.ExitCode)'")
|
||||
}
|
||||
|
||||
Write-Log "<-- Install-WebServer"
|
||||
}
|
||||
|
||||
function Copy-Prerequisites {
|
||||
param (
|
||||
[String] $Path = '',
|
||||
[String] $Destination = ''
|
||||
)
|
||||
|
||||
Write-Log "--> Copy-Prerequisites"
|
||||
|
||||
if ($Destination -eq '') {
|
||||
throw("Copy-Prerequisites: Destination path not specified!")
|
||||
}
|
||||
|
||||
if ($Path -eq '') {
|
||||
$Path = [Environment]::GetEnvironmentVariable('MuranoFileShare')
|
||||
if ($Path -eq $null) {
|
||||
throw("Copy-Prerequisites: Unable to determine source path for prerequisites.")
|
||||
}
|
||||
}
|
||||
|
||||
Write-Log "Creating new PSDrive ..."
|
||||
New-PSDrive -Name 'P' -PSProvider 'FileSystem' -Root $Path | Out-Null
|
||||
Write-Log "Creating destination folder ..."
|
||||
New-Item -Path $Destination -ItemType Container -Force | Out-Null
|
||||
Write-Log "Copying items ..."
|
||||
Copy-Item -Path 'P:\Prerequisites\IIS' -Destination $Destination -Recurse -Force | Out-Null
|
||||
Write-Log "Removing PSDrive ..."
|
||||
Remove-PSDrive -Name 'P' -PSProvider 'FileSystem' -Force | Out-Null
|
||||
|
||||
Write-Log "<-- Copy-Prerequisites"
|
||||
}
|
||||
|
||||
|
||||
|
||||
function Install-WebServer {
|
||||
param (
|
||||
[String] $PrerequisitesPath
|
||||
)
|
||||
|
||||
Write-Log "--> Install-WebServer"
|
||||
|
||||
$FeatureList = @(
|
||||
'Web-Server',
|
||||
'Web-Net-Ext45',
|
||||
'Web-ASP',
|
||||
'Web-Asp-Net45',
|
||||
'Web-ISAPI-Ext',
|
||||
'Web-ISAPI-Filter',
|
||||
'Web-Includes'
|
||||
)
|
||||
|
||||
$PrerequisitesList = @(
|
||||
'AspNetMvc4Setup.exe',
|
||||
'WebApplications.exe'
|
||||
)
|
||||
|
||||
$PrerequisitesPath = [IO.Path]::Combine($PrerequisitesPath, 'IIS')
|
||||
|
||||
Write-Log "Validating prerequisites based on the list ..."
|
||||
foreach ($FileName in $PrerequisitesList) {
|
||||
$FilePath = [IO.Path]::Combine($PrerequisitesPath, $FileName)
|
||||
if (-not (Test-Path -Path $FilePath -PathType Leaf)) {
|
||||
throw("Prerequisite file not found: '$FilePath'")
|
||||
}
|
||||
}
|
||||
|
||||
Import-Module ServerManager
|
||||
|
||||
Write-Log "Installing Web Server ..."
|
||||
Install-WindowsFeature $FeatureList -IncludeManagementTools
|
||||
|
||||
Write-Log "Installing AspNetMvp4 ..."
|
||||
$Exec = Exec -FilePath $([IO.Path]::Combine($PrerequisitesPath, 'AspNetMvc4Setup.exe')) -ArgumentList '/q' -PassThru
|
||||
if ($Exec.ExitCode -ne 0) {
|
||||
throw("Installation of 'AspNetMvc4Setup.exe' failed. Process exit code '$($Exec.ExitCode)'")
|
||||
}
|
||||
|
||||
# Extract WebApplications folder with *.target files to
|
||||
# C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0
|
||||
Write-Log "Installing WebApplication targets ..."
|
||||
$WebApplicationsTargetsRoot = 'C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0'
|
||||
$null = New-Item -Path $WebApplicationsTargetsRoot -ItemType Container
|
||||
$Exec = Exec -FilePath $([IO.Path]::Combine($PrerequisitesPath, 'WebApplications.exe')) -ArgumentList @("-o`"$WebApplicationsTargetsRoot`"", '-y') -PassThru
|
||||
if ($Exec.ExitCode -ne 0) {
|
||||
throw("Installation of 'WebApplications.exe' failed. Process exit code '$($Exec.ExitCode)'")
|
||||
}
|
||||
|
||||
Write-Log "<-- Install-WebServer"
|
||||
}
|
||||
|
|
@ -1,26 +1,26 @@
|
|||
{
|
||||
"Scripts": [
|
||||
"ZnVuY3Rpb24gQ29weS1QcmVyZXF1aXNpdGVzIHsNCglwYXJhbSAoDQoJCVtTdHJpbmddICRQYXRoID0gJycsDQoJCVtTdHJpbmddICREZXN0aW5hdGlvbiA9ICcnDQoJKQ0KDQoJV3JpdGUtTG9nICItLT4gQ29weS1QcmVyZXF1aXNpdGVzIg0KDQogICAgaWYgKCREZXN0aW5hdGlvbiAtZXEgJycpIHsNCiAgICAgICAgdGhyb3coIkNvcHktUHJlcmVxdWlzaXRlczogRGVzdGluYXRpb24gcGF0aCBub3Qgc3BlY2lmaWVkISIpDQogICAgfQ0KDQogICAgaWYgKCRQYXRoIC1lcSAnJykgew0KICAgICAgICAkUGF0aCA9IFtFbnZpcm9ubWVudF06OkdldEVudmlyb25tZW50VmFyaWFibGUoJ011cmFub0ZpbGVTaGFyZScpDQogICAgICAgIGlmICgkUGF0aCAtZXEgJG51bGwpIHsNCiAgICAgICAgICAgIHRocm93KCJDb3B5LVByZXJlcXVpc2l0ZXM6IFVuYWJsZSB0byBkZXRlcm1pbmUgc291cmNlIHBhdGggZm9yIHByZXJlcXVpc2l0ZXMuIikNCiAgICAgICAgfQ0KICAgIH0NCg0KCVdyaXRlLUxvZyAiQ3JlYXRpbmcgbmV3IFBTRHJpdmUgLi4uIg0KCU5ldy1QU0RyaXZlIC1OYW1lICdQJyAtUFNQcm92aWRlciAnRmlsZVN5c3RlbScgLVJvb3QgJFBhdGggfCBPdXQtTnVsbA0KCVdyaXRlLUxvZyAiQ3JlYXRpbmcgZGVzdGluYXRpb24gZm9sZGVyIC4uLiINCglOZXctSXRlbSAtUGF0aCAkRGVzdGluYXRpb24gLUl0ZW1UeXBlIENvbnRhaW5lciAtRm9yY2UgfCBPdXQtTnVsbA0KCVdyaXRlLUxvZyAiQ29weWluZyBpdGVtcyAuLi4iDQoJQ29weS1JdGVtIC1QYXRoICdQOlxQcmVyZXF1aXNpdGVzXElJUycgLURlc3RpbmF0aW9uICREZXN0aW5hdGlvbiAtUmVjdXJzZSAtRm9yY2UgfCBPdXQtTnVsbA0KCVdyaXRlLUxvZyAiUmVtb3ZpbmcgUFNEcml2ZSAuLi4iDQoJUmVtb3ZlLVBTRHJpdmUgLU5hbWUgJ1AnIC1QU1Byb3ZpZGVyICdGaWxlU3lzdGVtJyAtRm9yY2UgfCBPdXQtTnVsbA0KCQ0KCVdyaXRlLUxvZyAiPC0tIENvcHktUHJlcmVxdWlzaXRlcyINCn0NCg0KDQoNCmZ1bmN0aW9uIEluc3RhbGwtV2ViU2VydmVyIHsNCglwYXJhbSAoDQoJCVtTdHJpbmddICRQcmVyZXF1aXNpdGVzUGF0aA0KCSkNCgkNCglXcml0ZS1Mb2cgIi0tPiBJbnN0YWxsLVdlYlNlcnZlciINCg0KCSRGZWF0dXJlTGlzdCA9IEAoDQoJCSdXZWItU2VydmVyJywNCgkJJ1dlYi1OZXQtRXh0NDUnLA0KCQknV2ViLUFTUCcsDQoJCSdXZWItQXNwLU5ldDQ1JywNCgkJJ1dlYi1JU0FQSS1FeHQnLA0KCQknV2ViLUlTQVBJLUZpbHRlcicsDQoJCSdXZWItSW5jbHVkZXMnDQoJKQ0KCQ0KCSRQcmVyZXF1aXNpdGVzTGlzdCA9IEAoDQoJCSdBc3BOZXRNdmM0U2V0dXAuZXhlJywNCgkJJ1dlYkFwcGxpY2F0aW9ucy5leGUnDQoJKQ0KICAgIA0KCSRQcmVyZXF1aXNpdGVzUGF0aCA9IFtJTy5QYXRoXTo6Q29tYmluZSgkUHJlcmVxdWlzaXRlc1BhdGgsICdJSVMnKQ0KICAgIA0KCVdyaXRlLUxvZyAiVmFsaWRhdGluZyBwcmVyZXF1aXNpdGVzIGJhc2VkIG9uIHRoZSBsaXN0IC4uLiINCglmb3JlYWNoICgkRmlsZU5hbWUgaW4gJFByZXJlcXVpc2l0ZXNMaXN0KSB7DQoJCSRGaWxlUGF0aCA9IFtJTy5QYXRoXTo6Q29tYmluZSgkUHJlcmVxdWlzaXRlc1BhdGgsICRGaWxlTmFtZSkNCgkJaWYgKC1ub3QgKFRlc3QtUGF0aCAtUGF0aCAkRmlsZVBhdGggLVBhdGhUeXBlIExlYWYpKSB7DQoJCQl0aHJvdygiUHJlcmVxdWlzaXRlIGZpbGUgbm90IGZvdW5kOiAnJEZpbGVQYXRoJyIpDQoJCX0NCgl9DQoJDQoJSW1wb3J0LU1vZHVsZSBTZXJ2ZXJNYW5hZ2VyDQoJDQoJV3JpdGUtTG9nICJJbnN0YWxsaW5nIFdlYiBTZXJ2ZXIgLi4uIg0KCUluc3RhbGwtV2luZG93c0ZlYXR1cmUgJEZlYXR1cmVMaXN0IC1JbmNsdWRlTWFuYWdlbWVudFRvb2xzDQoJDQoJV3JpdGUtTG9nICJJbnN0YWxsaW5nIEFzcE5ldE12cDQgLi4uIg0KCSRFeGVjID0gRXhlYyAtRmlsZVBhdGggJChbSU8uUGF0aF06OkNvbWJpbmUoJFByZXJlcXVpc2l0ZXNQYXRoLCAnQXNwTmV0TXZjNFNldHVwLmV4ZScpKSAtQXJndW1lbnRMaXN0ICcvcScgLVBhc3NUaHJ1DQoJaWYgKCRFeGVjLkV4aXRDb2RlIC1uZSAwKSB7DQoJCXRocm93KCJJbnN0YWxsYXRpb24gb2YgJ0FzcE5ldE12YzRTZXR1cC5leGUnIGZhaWxlZC4gUHJvY2VzcyBleGl0IGNvZGUgJyQoJEV4ZWMuRXhpdENvZGUpJyIpDQoJfQ0KCQ0KCSMgRXh0cmFjdCBXZWJBcHBsaWNhdGlvbnMgZm9sZGVyIHdpdGggKi50YXJnZXQgZmlsZXMgdG8NCgkjICAgQzpcUHJvZ3JhbSBGaWxlcyAoeDg2KVxNU0J1aWxkXE1pY3Jvc29mdFxWaXN1YWxTdHVkaW9cdjEwLjANCglXcml0ZS1Mb2cgIkluc3RhbGxpbmcgV2ViQXBwbGljYXRpb24gdGFyZ2V0cyAuLi4iDQoJJFdlYkFwcGxpY2F0aW9uc1RhcmdldHNSb290ID0gJ0M6XFByb2dyYW0gRmlsZXMgKHg4NilcTVNCdWlsZFxNaWNyb3NvZnRcVmlzdWFsU3R1ZGlvXHYxMC4wJw0KCSRudWxsID0gTmV3LUl0ZW0gLVBhdGggJFdlYkFwcGxpY2F0aW9uc1RhcmdldHNSb290IC1JdGVtVHlwZSBDb250YWluZXINCgkkRXhlYyA9IEV4ZWMgLUZpbGVQYXRoICQoW0lPLlBhdGhdOjpDb21iaW5lKCRQcmVyZXF1aXNpdGVzUGF0aCwgJ1dlYkFwcGxpY2F0aW9ucy5leGUnKSkgLUFyZ3VtZW50TGlzdCBAKCItb2AiJFdlYkFwcGxpY2F0aW9uc1RhcmdldHNSb290YCIiLCAnLXknKSAtUGFzc1RocnUNCglpZiAoJEV4ZWMuRXhpdENvZGUgLW5lIDApIHsNCgkJdGhyb3coIkluc3RhbGxhdGlvbiBvZiAnV2ViQXBwbGljYXRpb25zLmV4ZScgZmFpbGVkLiBQcm9jZXNzIGV4aXQgY29kZSAnJCgkRXhlYy5FeGl0Q29kZSknIikNCgl9DQoNCglXcml0ZS1Mb2cgIjwtLSBJbnN0YWxsLVdlYlNlcnZlciINCn0NCg0K"
|
||||
],
|
||||
"Commands": [
|
||||
{
|
||||
"Name": "Import-Module",
|
||||
"Arguments": {
|
||||
"Name": "CoreFunctions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "Copy-Prerequisites",
|
||||
"Arguments": {
|
||||
"Destination": "C:\\Prerequisites"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "Install-WebServer",
|
||||
"Arguments": {
|
||||
"PrerequisitesPath": "C:\\Prerequisites"
|
||||
}
|
||||
}
|
||||
],
|
||||
"RebootOnCompletion": 0
|
||||
}
|
||||
{
|
||||
"Scripts": [
|
||||
"ZnVuY3Rpb24gQ29weS1QcmVyZXF1aXNpdGVzIHsNCglwYXJhbSAoDQoJCVtTdHJpbmddICRQYXRoID0gJycsDQoJCVtTdHJpbmddICREZXN0aW5hdGlvbiA9ICcnDQoJKQ0KDQoJV3JpdGUtTG9nICItLT4gQ29weS1QcmVyZXF1aXNpdGVzIg0KDQogICAgaWYgKCREZXN0aW5hdGlvbiAtZXEgJycpIHsNCiAgICAgICAgdGhyb3coIkNvcHktUHJlcmVxdWlzaXRlczogRGVzdGluYXRpb24gcGF0aCBub3Qgc3BlY2lmaWVkISIpDQogICAgfQ0KDQogICAgaWYgKCRQYXRoIC1lcSAnJykgew0KICAgICAgICAkUGF0aCA9IFtFbnZpcm9ubWVudF06OkdldEVudmlyb25tZW50VmFyaWFibGUoJ011cmFub0ZpbGVTaGFyZScpDQogICAgICAgIGlmICgkUGF0aCAtZXEgJG51bGwpIHsNCiAgICAgICAgICAgIHRocm93KCJDb3B5LVByZXJlcXVpc2l0ZXM6IFVuYWJsZSB0byBkZXRlcm1pbmUgc291cmNlIHBhdGggZm9yIHByZXJlcXVpc2l0ZXMuIikNCiAgICAgICAgfQ0KICAgIH0NCg0KCVdyaXRlLUxvZyAiQ3JlYXRpbmcgbmV3IFBTRHJpdmUgLi4uIg0KCU5ldy1QU0RyaXZlIC1OYW1lICdQJyAtUFNQcm92aWRlciAnRmlsZVN5c3RlbScgLVJvb3QgJFBhdGggfCBPdXQtTnVsbA0KCVdyaXRlLUxvZyAiQ3JlYXRpbmcgZGVzdGluYXRpb24gZm9sZGVyIC4uLiINCglOZXctSXRlbSAtUGF0aCAkRGVzdGluYXRpb24gLUl0ZW1UeXBlIENvbnRhaW5lciAtRm9yY2UgfCBPdXQtTnVsbA0KCVdyaXRlLUxvZyAiQ29weWluZyBpdGVtcyAuLi4iDQoJQ29weS1JdGVtIC1QYXRoICdQOlxQcmVyZXF1aXNpdGVzXElJUycgLURlc3RpbmF0aW9uICREZXN0aW5hdGlvbiAtUmVjdXJzZSAtRm9yY2UgfCBPdXQtTnVsbA0KCVdyaXRlLUxvZyAiUmVtb3ZpbmcgUFNEcml2ZSAuLi4iDQoJUmVtb3ZlLVBTRHJpdmUgLU5hbWUgJ1AnIC1QU1Byb3ZpZGVyICdGaWxlU3lzdGVtJyAtRm9yY2UgfCBPdXQtTnVsbA0KCQ0KCVdyaXRlLUxvZyAiPC0tIENvcHktUHJlcmVxdWlzaXRlcyINCn0NCg0KDQoNCmZ1bmN0aW9uIEluc3RhbGwtV2ViU2VydmVyIHsNCglwYXJhbSAoDQoJCVtTdHJpbmddICRQcmVyZXF1aXNpdGVzUGF0aA0KCSkNCgkNCglXcml0ZS1Mb2cgIi0tPiBJbnN0YWxsLVdlYlNlcnZlciINCg0KCSRGZWF0dXJlTGlzdCA9IEAoDQoJCSdXZWItU2VydmVyJywNCgkJJ1dlYi1OZXQtRXh0NDUnLA0KCQknV2ViLUFTUCcsDQoJCSdXZWItQXNwLU5ldDQ1JywNCgkJJ1dlYi1JU0FQSS1FeHQnLA0KCQknV2ViLUlTQVBJLUZpbHRlcicsDQoJCSdXZWItSW5jbHVkZXMnDQoJKQ0KCQ0KCSRQcmVyZXF1aXNpdGVzTGlzdCA9IEAoDQoJCSdBc3BOZXRNdmM0U2V0dXAuZXhlJywNCgkJJ1dlYkFwcGxpY2F0aW9ucy5leGUnDQoJKQ0KICAgIA0KCSRQcmVyZXF1aXNpdGVzUGF0aCA9IFtJTy5QYXRoXTo6Q29tYmluZSgkUHJlcmVxdWlzaXRlc1BhdGgsICdJSVMnKQ0KICAgIA0KCVdyaXRlLUxvZyAiVmFsaWRhdGluZyBwcmVyZXF1aXNpdGVzIGJhc2VkIG9uIHRoZSBsaXN0IC4uLiINCglmb3JlYWNoICgkRmlsZU5hbWUgaW4gJFByZXJlcXVpc2l0ZXNMaXN0KSB7DQoJCSRGaWxlUGF0aCA9IFtJTy5QYXRoXTo6Q29tYmluZSgkUHJlcmVxdWlzaXRlc1BhdGgsICRGaWxlTmFtZSkNCgkJaWYgKC1ub3QgKFRlc3QtUGF0aCAtUGF0aCAkRmlsZVBhdGggLVBhdGhUeXBlIExlYWYpKSB7DQoJCQl0aHJvdygiUHJlcmVxdWlzaXRlIGZpbGUgbm90IGZvdW5kOiAnJEZpbGVQYXRoJyIpDQoJCX0NCgl9DQoJDQoJSW1wb3J0LU1vZHVsZSBTZXJ2ZXJNYW5hZ2VyDQoJDQoJV3JpdGUtTG9nICJJbnN0YWxsaW5nIFdlYiBTZXJ2ZXIgLi4uIg0KCUluc3RhbGwtV2luZG93c0ZlYXR1cmUgJEZlYXR1cmVMaXN0IC1JbmNsdWRlTWFuYWdlbWVudFRvb2xzDQoJDQoJV3JpdGUtTG9nICJJbnN0YWxsaW5nIEFzcE5ldE12cDQgLi4uIg0KCSRFeGVjID0gRXhlYyAtRmlsZVBhdGggJChbSU8uUGF0aF06OkNvbWJpbmUoJFByZXJlcXVpc2l0ZXNQYXRoLCAnQXNwTmV0TXZjNFNldHVwLmV4ZScpKSAtQXJndW1lbnRMaXN0ICcvcScgLVBhc3NUaHJ1DQoJaWYgKCRFeGVjLkV4aXRDb2RlIC1uZSAwKSB7DQoJCXRocm93KCJJbnN0YWxsYXRpb24gb2YgJ0FzcE5ldE12YzRTZXR1cC5leGUnIGZhaWxlZC4gUHJvY2VzcyBleGl0IGNvZGUgJyQoJEV4ZWMuRXhpdENvZGUpJyIpDQoJfQ0KCQ0KCSMgRXh0cmFjdCBXZWJBcHBsaWNhdGlvbnMgZm9sZGVyIHdpdGggKi50YXJnZXQgZmlsZXMgdG8NCgkjICAgQzpcUHJvZ3JhbSBGaWxlcyAoeDg2KVxNU0J1aWxkXE1pY3Jvc29mdFxWaXN1YWxTdHVkaW9cdjEwLjANCglXcml0ZS1Mb2cgIkluc3RhbGxpbmcgV2ViQXBwbGljYXRpb24gdGFyZ2V0cyAuLi4iDQoJJFdlYkFwcGxpY2F0aW9uc1RhcmdldHNSb290ID0gJ0M6XFByb2dyYW0gRmlsZXMgKHg4NilcTVNCdWlsZFxNaWNyb3NvZnRcVmlzdWFsU3R1ZGlvXHYxMC4wJw0KCSRudWxsID0gTmV3LUl0ZW0gLVBhdGggJFdlYkFwcGxpY2F0aW9uc1RhcmdldHNSb290IC1JdGVtVHlwZSBDb250YWluZXINCgkkRXhlYyA9IEV4ZWMgLUZpbGVQYXRoICQoW0lPLlBhdGhdOjpDb21iaW5lKCRQcmVyZXF1aXNpdGVzUGF0aCwgJ1dlYkFwcGxpY2F0aW9ucy5leGUnKSkgLUFyZ3VtZW50TGlzdCBAKCItb2AiJFdlYkFwcGxpY2F0aW9uc1RhcmdldHNSb290YCIiLCAnLXknKSAtUGFzc1RocnUNCglpZiAoJEV4ZWMuRXhpdENvZGUgLW5lIDApIHsNCgkJdGhyb3coIkluc3RhbGxhdGlvbiBvZiAnV2ViQXBwbGljYXRpb25zLmV4ZScgZmFpbGVkLiBQcm9jZXNzIGV4aXQgY29kZSAnJCgkRXhlYy5FeGl0Q29kZSknIikNCgl9DQoNCglXcml0ZS1Mb2cgIjwtLSBJbnN0YWxsLVdlYlNlcnZlciINCn0NCg0K"
|
||||
],
|
||||
"Commands": [
|
||||
{
|
||||
"Name": "Import-Module",
|
||||
"Arguments": {
|
||||
"Name": "CoreFunctions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "Copy-Prerequisites",
|
||||
"Arguments": {
|
||||
"Destination": "C:\\Prerequisites"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "Install-WebServer",
|
||||
"Arguments": {
|
||||
"PrerequisitesPath": "C:\\Prerequisites"
|
||||
}
|
||||
}
|
||||
],
|
||||
"RebootOnCompletion": 0
|
||||
}
|
|
@ -1,223 +1,223 @@
|
|||
<#
|
||||
.DESCRIPTION
|
||||
|
||||
## Failover Cluster Input Data (from the UI)
|
||||
|
||||
* Domain Membership
|
||||
- [String] / [Select box] $DomainName - Domain name
|
||||
* Domain User Credentials
|
||||
- [String] $UserName - Username
|
||||
- [Password string] $UserPassword - User password
|
||||
* Shared Folder Information
|
||||
- [String] $ShareServer - Server which will host the folder
|
||||
- [String] $ShareName - Share name
|
||||
- [String] $SharePath - Shared folder internal path
|
||||
* Failover Cluster Members
|
||||
- [String] $ClusterName - Cluster name
|
||||
- [String] $ClusterIP - Static IP address that will be assigned to the cluster
|
||||
- [String[]] $ClusterNodes - List of node names
|
||||
|
||||
|
||||
|
||||
## Failover Cluster creation workflow
|
||||
|
||||
* Create AD domain
|
||||
* Join all the VMs to that domain
|
||||
* Prepare nodes
|
||||
- Install Failover Cluster prerequisites on all FC nodes
|
||||
* Create failover cluster
|
||||
- Create new cluster
|
||||
- Add members
|
||||
* Confugure FC quorum
|
||||
- Create new folder that will be shared
|
||||
- Share that folder with appropriate permissions
|
||||
- Configure quorum mode
|
||||
|
||||
|
||||
|
||||
## Helpful SmbShare* Functions
|
||||
|
||||
* New-SmbShare
|
||||
* Grant-SmbShareAccess
|
||||
|
||||
#>
|
||||
|
||||
trap {
|
||||
&$TrapHandler
|
||||
}
|
||||
|
||||
|
||||
|
||||
function Install-FailoverClusterPrerequisites {
|
||||
#Import-Module FailoverClusters
|
||||
|
||||
Add-WindowsFeature Failover-Clustering, RSAT-Clustering-PowerShell
|
||||
}
|
||||
|
||||
|
||||
|
||||
function New-FailoverClusterSharedFolder {
|
||||
param (
|
||||
[String] $ClusterName,
|
||||
[String] $DomainName,
|
||||
[String] $ShareServer,
|
||||
[String] $SharePath = $($Env:SystemDrive + '\FCShare'),
|
||||
[String] $ShareName = 'FCShare',
|
||||
[String] $UserName,
|
||||
[String] $UserPassword,
|
||||
$Credential = $null
|
||||
)
|
||||
begin {
|
||||
Show-InvocationInfo $MyInvocation
|
||||
}
|
||||
end {
|
||||
Show-InvocationInfo $MyInvocation -End
|
||||
}
|
||||
process {
|
||||
trap {
|
||||
&$TrapHandler
|
||||
}
|
||||
|
||||
Write-Log "--> New-FailoverClusterSharedFolder"
|
||||
|
||||
Write-Log "Creating shared folder for Failover Cluster ..."
|
||||
|
||||
if ($Credential -eq $null) {
|
||||
$Credential = New-Credential -UserName "$DomainName\$UserName" -Password "$UserPassword"
|
||||
}
|
||||
|
||||
if ((Test-Connection -ComputerName $ShareServer -Count 1 -Quiet) -eq $false) {
|
||||
throw("Server '$ShareServer' is unreachable via ICMP.")
|
||||
}
|
||||
|
||||
$Session = New-PSSession -ComputerName $ShareServer -Credential $Credential
|
||||
|
||||
Write-Log "Creating folder on '$ShareServer' ..."
|
||||
Invoke-Command -Session $Session -ScriptBlock {
|
||||
param (
|
||||
[String] $SharePath,
|
||||
[String] $ShareName,
|
||||
[String] $ClusterAccount
|
||||
)
|
||||
|
||||
Remove-SmbShare -Name $ShareName -Force -ErrorAction 'SilentlyContinue'
|
||||
Remove-Item -Path $SharePath -Force -ErrorAction 'SilentlyContinue'
|
||||
|
||||
New-Item -Path $SharePath -ItemType Container -Force
|
||||
|
||||
New-SmbShare -Path $SharePath `
|
||||
-Name $ShareName `
|
||||
-FullAccess "$ClusterAccount", 'Everyone' `
|
||||
-Description "Shared folder for Failover Cluster."
|
||||
|
||||
} -ArgumentList $SharePath, $ShareName, "$DomainName\$ClusterName`$"
|
||||
|
||||
Write-Log "Confguring Failover Cluster to use shared folder as qourum resourse ..."
|
||||
|
||||
$null = Set-ClusterQuorum -NodeAndFileShareMajority "\\$ShareServer\$ShareName"
|
||||
|
||||
Write-Log "<-- New-FailoverClusterSharedFolder"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function New-FailoverCluster {
|
||||
param (
|
||||
[String] $ClusterName,
|
||||
[String] $StaticAddress,
|
||||
[String[]] $ClusterNodes,
|
||||
[String] $DomainName,
|
||||
[String] $UserName,
|
||||
[String] $UserPassword,
|
||||
$Credential
|
||||
)
|
||||
begin {
|
||||
Show-InvocationInfo $MyInvocation
|
||||
}
|
||||
end {
|
||||
Show-InvocationInfo $MyInvocation -End
|
||||
}
|
||||
process {
|
||||
trap {
|
||||
&$TrapHandler
|
||||
}
|
||||
|
||||
Write-Log "ClusterNodes: $($ClusterNodes -join ', ')"
|
||||
|
||||
if ($Credential -eq $null) {
|
||||
$Credential = New-Credential -UserName "$DomainName\$UserName" -Password "$UserPassword"
|
||||
}
|
||||
|
||||
Import-Module FailoverClusters
|
||||
|
||||
if ((Get-Cluster $ClusterName -ErrorAction SilentlyContinue) -eq $null) {
|
||||
Write-Log "Creating new cluster '$ClusterName' ..."
|
||||
Start-PowerShellProcess -Command @"
|
||||
Import-Module FailoverClusters
|
||||
New-Cluster -Name '$ClusterName' -StaticAddress '$StaticAddress'
|
||||
"@ -Credential $Credential -NoBase64
|
||||
Start-Sleep -Seconds 15
|
||||
}
|
||||
else {
|
||||
Write-Log "Cluster '$ClusterName' already exists."
|
||||
}
|
||||
|
||||
foreach ($Node in $ClusterNodes) {
|
||||
Write-Log "Adding node '$Node' to the cluster '$ClusterName' ..."
|
||||
if ((Get-ClusterNode $Node -ErrorAction SilentlyContinue) -eq $null) {
|
||||
Write-Log "Adding node ..."
|
||||
Start-PowerShellProcess -Command @"
|
||||
Import-Module FailoverClusters
|
||||
Add-ClusterNode -Cluster '$ClusterName' -Name '$Node'
|
||||
"@ -Credential $Credential -NoBase64
|
||||
}
|
||||
else {
|
||||
Write-Log "Node '$Node' already a part of the cluster '$ClusterName'."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
<#
|
||||
|
||||
# Example
|
||||
|
||||
$DomainName = 'fc-acme.local'
|
||||
$DomainUser = 'Administrator'
|
||||
$DomainPassword = 'P@ssw0rd'
|
||||
|
||||
$ClusterName = 'fc-test'
|
||||
$ClusterIP = '10.200.0.60'
|
||||
$ClusterNodes = @('fc-node-01','fc-node-02','fc-node-03')
|
||||
|
||||
$ShareServer = 'fc-dc-01'
|
||||
$ShareName = 'FCShare'
|
||||
|
||||
$SharePath = "C:\$ShareName"
|
||||
|
||||
|
||||
|
||||
Import-Module CoreFunctions -Force
|
||||
|
||||
$Creds = New-Credential `
|
||||
-UserName "$DomainName\$DomainUser" `
|
||||
-Password "$DomainPassword"
|
||||
|
||||
New-FailoverCluster `
|
||||
-ClusterName $ClusterName `
|
||||
-StaticAddress $ClusterIP `
|
||||
-ClusterNodes $ClusterNodes `
|
||||
-Credential $Creds
|
||||
|
||||
New-FailoverClusterSharedFolder `
|
||||
-ClusterName $ClusterName `
|
||||
-DomainName $DomainName `
|
||||
-ShareServer $ShareServer `
|
||||
-SharePath "$SharePath" `
|
||||
-ShareName "$ShareName" `
|
||||
-Credential $Creds
|
||||
|
||||
#>
|
||||
<#
|
||||
.DESCRIPTION
|
||||
|
||||
## Failover Cluster Input Data (from the UI)
|
||||
|
||||
* Domain Membership
|
||||
- [String] / [Select box] $DomainName - Domain name
|
||||
* Domain User Credentials
|
||||
- [String] $UserName - Username
|
||||
- [Password string] $UserPassword - User password
|
||||
* Shared Folder Information
|
||||
- [String] $ShareServer - Server which will host the folder
|
||||
- [String] $ShareName - Share name
|
||||
- [String] $SharePath - Shared folder internal path
|
||||
* Failover Cluster Members
|
||||
- [String] $ClusterName - Cluster name
|
||||
- [String] $ClusterIP - Static IP address that will be assigned to the cluster
|
||||
- [String[]] $ClusterNodes - List of node names
|
||||
|
||||
|
||||
|
||||
## Failover Cluster creation workflow
|
||||
|
||||
* Create AD domain
|
||||
* Join all the VMs to that domain
|
||||
* Prepare nodes
|
||||
- Install Failover Cluster prerequisites on all FC nodes
|
||||
* Create failover cluster
|
||||
- Create new cluster
|
||||
- Add members
|
||||
* Confugure FC quorum
|
||||
- Create new folder that will be shared
|
||||
- Share that folder with appropriate permissions
|
||||
- Configure quorum mode
|
||||
|
||||
|
||||
|
||||
## Helpful SmbShare* Functions
|
||||
|
||||
* New-SmbShare
|
||||
* Grant-SmbShareAccess
|
||||
|
||||
#>
|
||||
|
||||
trap {
|
||||
&$TrapHandler
|
||||
}
|
||||
|
||||
|
||||
|
||||
function Install-FailoverClusterPrerequisites {
|
||||
#Import-Module FailoverClusters
|
||||
|
||||
Add-WindowsFeature Failover-Clustering, RSAT-Clustering-PowerShell
|
||||
}
|
||||
|
||||
|
||||
|
||||
function New-FailoverClusterSharedFolder {
|
||||
param (
|
||||
[String] $ClusterName,
|
||||
[String] $DomainName,
|
||||
[String] $ShareServer,
|
||||
[String] $SharePath = $($Env:SystemDrive + '\FCShare'),
|
||||
[String] $ShareName = 'FCShare',
|
||||
[String] $UserName,
|
||||
[String] $UserPassword,
|
||||
$Credential = $null
|
||||
)
|
||||
begin {
|
||||
Show-InvocationInfo $MyInvocation
|
||||
}
|
||||
end {
|
||||
Show-InvocationInfo $MyInvocation -End
|
||||
}
|
||||
process {
|
||||
trap {
|
||||
&$TrapHandler
|
||||
}
|
||||
|
||||
Write-Log "--> New-FailoverClusterSharedFolder"
|
||||
|
||||
Write-Log "Creating shared folder for Failover Cluster ..."
|
||||
|
||||
if ($Credential -eq $null) {
|
||||
$Credential = New-Credential -UserName "$DomainName\$UserName" -Password "$UserPassword"
|
||||
}
|
||||
|
||||
if ((Test-Connection -ComputerName $ShareServer -Count 1 -Quiet) -eq $false) {
|
||||
throw("Server '$ShareServer' is unreachable via ICMP.")
|
||||
}
|
||||
|
||||
$Session = New-PSSession -ComputerName $ShareServer -Credential $Credential
|
||||
|
||||
Write-Log "Creating folder on '$ShareServer' ..."
|
||||
Invoke-Command -Session $Session -ScriptBlock {
|
||||
param (
|
||||
[String] $SharePath,
|
||||
[String] $ShareName,
|
||||
[String] $ClusterAccount
|
||||
)
|
||||
|
||||
Remove-SmbShare -Name $ShareName -Force -ErrorAction 'SilentlyContinue'
|
||||
Remove-Item -Path $SharePath -Force -ErrorAction 'SilentlyContinue'
|
||||
|
||||
New-Item -Path $SharePath -ItemType Container -Force
|
||||
|
||||
New-SmbShare -Path $SharePath `
|
||||
-Name $ShareName `
|
||||
-FullAccess "$ClusterAccount", 'Everyone' `
|
||||
-Description "Shared folder for Failover Cluster."
|
||||
|
||||
} -ArgumentList $SharePath, $ShareName, "$DomainName\$ClusterName`$"
|
||||
|
||||
Write-Log "Confguring Failover Cluster to use shared folder as qourum resourse ..."
|
||||
|
||||
$null = Set-ClusterQuorum -NodeAndFileShareMajority "\\$ShareServer\$ShareName"
|
||||
|
||||
Write-Log "<-- New-FailoverClusterSharedFolder"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function New-FailoverCluster {
|
||||
param (
|
||||
[String] $ClusterName,
|
||||
[String] $StaticAddress,
|
||||
[String[]] $ClusterNodes,
|
||||
[String] $DomainName,
|
||||
[String] $UserName,
|
||||
[String] $UserPassword,
|
||||
$Credential
|
||||
)
|
||||
begin {
|
||||
Show-InvocationInfo $MyInvocation
|
||||
}
|
||||
end {
|
||||
Show-InvocationInfo $MyInvocation -End
|
||||
}
|
||||
process {
|
||||
trap {
|
||||
&$TrapHandler
|
||||
}
|
||||
|
||||
Write-Log "ClusterNodes: $($ClusterNodes -join ', ')"
|
||||
|
||||
if ($Credential -eq $null) {
|
||||
$Credential = New-Credential -UserName "$DomainName\$UserName" -Password "$UserPassword"
|
||||
}
|
||||
|
||||
Import-Module FailoverClusters
|
||||
|
||||
if ((Get-Cluster $ClusterName -ErrorAction SilentlyContinue) -eq $null) {
|
||||
Write-Log "Creating new cluster '$ClusterName' ..."
|
||||
Start-PowerShellProcess -Command @"
|
||||
Import-Module FailoverClusters
|
||||
New-Cluster -Name '$ClusterName' -StaticAddress '$StaticAddress'
|
||||
"@ -Credential $Credential -NoBase64
|
||||
Start-Sleep -Seconds 15
|
||||
}
|
||||
else {
|
||||
Write-Log "Cluster '$ClusterName' already exists."
|
||||
}
|
||||
|
||||
foreach ($Node in $ClusterNodes) {
|
||||
Write-Log "Adding node '$Node' to the cluster '$ClusterName' ..."
|
||||
if ((Get-ClusterNode $Node -ErrorAction SilentlyContinue) -eq $null) {
|
||||
Write-Log "Adding node ..."
|
||||
Start-PowerShellProcess -Command @"
|
||||
Import-Module FailoverClusters
|
||||
Add-ClusterNode -Cluster '$ClusterName' -Name '$Node'
|
||||
"@ -Credential $Credential -NoBase64
|
||||
}
|
||||
else {
|
||||
Write-Log "Node '$Node' already a part of the cluster '$ClusterName'."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
<#
|
||||
|
||||
# Example
|
||||
|
||||
$DomainName = 'fc-acme.local'
|
||||
$DomainUser = 'Administrator'
|
||||
$DomainPassword = 'P@ssw0rd'
|
||||
|
||||
$ClusterName = 'fc-test'
|
||||
$ClusterIP = '10.200.0.60'
|
||||
$ClusterNodes = @('fc-node-01','fc-node-02','fc-node-03')
|
||||
|
||||
$ShareServer = 'fc-dc-01'
|
||||
$ShareName = 'FCShare'
|
||||
|
||||
$SharePath = "C:\$ShareName"
|
||||
|
||||
|
||||
|
||||
Import-Module CoreFunctions -Force
|
||||
|
||||
$Creds = New-Credential `
|
||||
-UserName "$DomainName\$DomainUser" `
|
||||
-Password "$DomainPassword"
|
||||
|
||||
New-FailoverCluster `
|
||||
-ClusterName $ClusterName `
|
||||
-StaticAddress $ClusterIP `
|
||||
-ClusterNodes $ClusterNodes `
|
||||
-Credential $Creds
|
||||
|
||||
New-FailoverClusterSharedFolder `
|
||||
-ClusterName $ClusterName `
|
||||
-DomainName $DomainName `
|
||||
-ShareServer $ShareServer `
|
||||
-SharePath "$SharePath" `
|
||||
-ShareName "$ShareName" `
|
||||
-Credential $Creds
|
||||
|
||||
#>
|
|
@ -1,117 +1,117 @@
|
|||
function Init-Clustering {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Installs all the prerequisites for windows failover cluster.
|
||||
|
||||
.DESCRIPTION
|
||||
Checks that computer is a part of Windows Domain.
|
||||
Installs Failover Clustering windows feature with management tools if needed.
|
||||
Restart may be required to continue installation, so check this cmdlet exit code.
|
||||
If exit code is $true, a restart is required. System should be restarted and
|
||||
CmdLet should be re-executed to perform all the configuration tasks left.
|
||||
|
||||
Is is safe to execute this CmdLet multiple times. It checks which components
|
||||
are missing / unconfigured and performs only necessary steps.
|
||||
|
||||
#>
|
||||
$ComputerSystem = Get-WmiObject Win32_ComputerSystem
|
||||
if (-not $ComputerSystem.PartOfDomain) {
|
||||
throw "The computer should be joined to domain first"
|
||||
}
|
||||
Import-Module ServerManager
|
||||
$Feature = Get-WindowsFeature Failover-Clustering
|
||||
if ($Feature -eq $null) {
|
||||
throw "Failover-Clustering not found" # Should not happen on Win Server 2012
|
||||
}
|
||||
if (-not $Feature.Installed) {
|
||||
Write-Host "Failover Clustering feature is not installed. Installing it using Server Manager..."
|
||||
$FeatureOpResult = Add-WindowsFeature $Feature -IncludeManagementTools
|
||||
if (-not $FeatureOpResult.Success) {
|
||||
throw "Failed to install Failover-Clustering: " + $FeatureOpResult.ExitCode.toString()
|
||||
}
|
||||
if ($FeatureOpResult.RestartNeeded) {
|
||||
Write-Host "Restart is required to continue..."
|
||||
return $true
|
||||
}
|
||||
}
|
||||
$Feature = Get-WindowsFeature RSAT-Clustering
|
||||
if ($Feature -eq $null) {
|
||||
throw "Failover Clustering Tools feature not found" # Should not happen on Win Server 2012
|
||||
}
|
||||
if (-not $Feature.Installed) {
|
||||
Write-Host "Failover Clustering Tools feature is not installed. Installing it using Server Manager..."
|
||||
$FeatureOpResult = Add-WindowsFeature $Feature
|
||||
if (-not $FeatureOpResult.Success) {
|
||||
throw "Failed to install RSAT-Clustering: " + $FeatureOpResult.ExitCode.toString()
|
||||
}
|
||||
if ($FeatureOpResult.RestartNeeded) {
|
||||
Write-Host "Restart is required to continue..."
|
||||
return $true
|
||||
}
|
||||
}
|
||||
$Feature = Get-WindowsFeature RSAT-Clustering-Mgmt
|
||||
if ($Feature -eq $null) {
|
||||
throw "Failover Cluster Management Tools feature not found" # Should not happen on Win Server 2012
|
||||
}
|
||||
if (-not $Feature.Installed) {
|
||||
Write-Host "Failover Cluster Management Tools feature is not installed. Installing it using Server Manager..."
|
||||
$FeatureOpResult = Add-WindowsFeature $Feature
|
||||
if (-not $FeatureOpResult.Success) {
|
||||
throw "Failed to install RSAT-Clustering-Mgmt: " + $FeatureOpResult.ExitCode.toString()
|
||||
}
|
||||
if ($FeatureOpResult.RestartNeeded) {
|
||||
Write-Host "Restart is required to continue..."
|
||||
return $true
|
||||
}
|
||||
}
|
||||
$Feature = Get-WindowsFeature RSAT-Clustering-PowerShell
|
||||
if ($Feature -eq $null) {
|
||||
throw "Failover Cluster Module for Windows PowerShell feature not found" # Should not happen on Win Server 2012
|
||||
}
|
||||
if (-not $Feature.Installed) {
|
||||
Write-Host "Failover Cluster Module for Windows PowerShell feature is not installed. Installing it using Server Manager..."
|
||||
$FeatureOpResult = Add-WindowsFeature $Feature
|
||||
if (-not $FeatureOpResult.Success) {
|
||||
throw "Failed to install RSAT-Clustering-PowerShell: " + $FeatureOpResult.ExitCode.toString()
|
||||
}
|
||||
if ($FeatureOpResult.RestartNeeded) {
|
||||
Write-Host "Restart is required to continue..."
|
||||
return $true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function New-WindowsFailoverCluster {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a Windows Failover Cluster.
|
||||
|
||||
.DESCRIPTION
|
||||
Installs all the prerequisites and creates a new Windows Failover Cluster. Init-Clustering is executed
|
||||
by this cmdlet to ensure that all the required server components are installed. A reboot mey be
|
||||
required to complete installation. In case if this CmdLet returns $true, reboot the system and
|
||||
re-invoke the CmdLet with the same arguments to continue installation.
|
||||
|
||||
.PARAMETER ClusterName
|
||||
Failover Cluster Name. The installation will fail if a cluster or other object with the same name
|
||||
already exists in the domain.
|
||||
|
||||
.PARAMETER Nodes
|
||||
List of computers (fully qualified domain names are recommmeneded) to participate in the cluster.
|
||||
Current user should have all the required permissions to join all the machones to the cluster.
|
||||
#>
|
||||
param(
|
||||
[parameter(Mandatory = $true)]
|
||||
[string]$ClusterName,
|
||||
[parameter(Mandatory = $true)]
|
||||
[array]$Nodes
|
||||
)
|
||||
|
||||
if (Init-Clustering) {
|
||||
return $true
|
||||
}
|
||||
Import-Module FailoverClusters
|
||||
[void](Test-Cluster -Cluster $ClusterName -Node $Nodes)
|
||||
[void](New-Cluster -Name $ClusterName -Node @("bravo.murano.local", "charlie.murano.local") -NoStorage)
|
||||
return $false
|
||||
}
|
||||
function Init-Clustering {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Installs all the prerequisites for windows failover cluster.
|
||||
|
||||
.DESCRIPTION
|
||||
Checks that computer is a part of Windows Domain.
|
||||
Installs Failover Clustering windows feature with management tools if needed.
|
||||
Restart may be required to continue installation, so check this cmdlet exit code.
|
||||
If exit code is $true, a restart is required. System should be restarted and
|
||||
CmdLet should be re-executed to perform all the configuration tasks left.
|
||||
|
||||
Is is safe to execute this CmdLet multiple times. It checks which components
|
||||
are missing / unconfigured and performs only necessary steps.
|
||||
|
||||
#>
|
||||
$ComputerSystem = Get-WmiObject Win32_ComputerSystem
|
||||
if (-not $ComputerSystem.PartOfDomain) {
|
||||
throw "The computer should be joined to domain first"
|
||||
}
|
||||
Import-Module ServerManager
|
||||
$Feature = Get-WindowsFeature Failover-Clustering
|
||||
if ($Feature -eq $null) {
|
||||
throw "Failover-Clustering not found" # Should not happen on Win Server 2012
|
||||
}
|
||||
if (-not $Feature.Installed) {
|
||||
Write-Host "Failover Clustering feature is not installed. Installing it using Server Manager..."
|
||||
$FeatureOpResult = Add-WindowsFeature $Feature -IncludeManagementTools
|
||||
if (-not $FeatureOpResult.Success) {
|
||||
throw "Failed to install Failover-Clustering: " + $FeatureOpResult.ExitCode.toString()
|
||||
}
|
||||
if ($FeatureOpResult.RestartNeeded) {
|
||||
Write-Host "Restart is required to continue..."
|
||||
return $true
|
||||
}
|
||||
}
|
||||
$Feature = Get-WindowsFeature RSAT-Clustering
|
||||
if ($Feature -eq $null) {
|
||||
throw "Failover Clustering Tools feature not found" # Should not happen on Win Server 2012
|
||||
}
|
||||
if (-not $Feature.Installed) {
|
||||
Write-Host "Failover Clustering Tools feature is not installed. Installing it using Server Manager..."
|
||||
$FeatureOpResult = Add-WindowsFeature $Feature
|
||||
if (-not $FeatureOpResult.Success) {
|
||||
throw "Failed to install RSAT-Clustering: " + $FeatureOpResult.ExitCode.toString()
|
||||
}
|
||||
if ($FeatureOpResult.RestartNeeded) {
|
||||
Write-Host "Restart is required to continue..."
|
||||
return $true
|
||||
}
|
||||
}
|
||||
$Feature = Get-WindowsFeature RSAT-Clustering-Mgmt
|
||||
if ($Feature -eq $null) {
|
||||
throw "Failover Cluster Management Tools feature not found" # Should not happen on Win Server 2012
|
||||
}
|
||||
if (-not $Feature.Installed) {
|
||||
Write-Host "Failover Cluster Management Tools feature is not installed. Installing it using Server Manager..."
|
||||
$FeatureOpResult = Add-WindowsFeature $Feature
|
||||
if (-not $FeatureOpResult.Success) {
|
||||
throw "Failed to install RSAT-Clustering-Mgmt: " + $FeatureOpResult.ExitCode.toString()
|
||||
}
|
||||
if ($FeatureOpResult.RestartNeeded) {
|
||||
Write-Host "Restart is required to continue..."
|
||||
return $true
|
||||
}
|
||||
}
|
||||
$Feature = Get-WindowsFeature RSAT-Clustering-PowerShell
|
||||
if ($Feature -eq $null) {
|
||||
throw "Failover Cluster Module for Windows PowerShell feature not found" # Should not happen on Win Server 2012
|
||||
}
|
||||
if (-not $Feature.Installed) {
|
||||
Write-Host "Failover Cluster Module for Windows PowerShell feature is not installed. Installing it using Server Manager..."
|
||||
$FeatureOpResult = Add-WindowsFeature $Feature
|
||||
if (-not $FeatureOpResult.Success) {
|
||||
throw "Failed to install RSAT-Clustering-PowerShell: " + $FeatureOpResult.ExitCode.toString()
|
||||
}
|
||||
if ($FeatureOpResult.RestartNeeded) {
|
||||
Write-Host "Restart is required to continue..."
|
||||
return $true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function New-WindowsFailoverCluster {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a Windows Failover Cluster.
|
||||
|
||||
.DESCRIPTION
|
||||
Installs all the prerequisites and creates a new Windows Failover Cluster. Init-Clustering is executed
|
||||
by this cmdlet to ensure that all the required server components are installed. A reboot mey be
|
||||
required to complete installation. In case if this CmdLet returns $true, reboot the system and
|
||||
re-invoke the CmdLet with the same arguments to continue installation.
|
||||
|
||||
.PARAMETER ClusterName
|
||||
Failover Cluster Name. The installation will fail if a cluster or other object with the same name
|
||||
already exists in the domain.
|
||||
|
||||
.PARAMETER Nodes
|
||||
List of computers (fully qualified domain names are recommmeneded) to participate in the cluster.
|
||||
Current user should have all the required permissions to join all the machones to the cluster.
|
||||
#>
|
||||
param(
|
||||
[parameter(Mandatory = $true)]
|
||||
[string]$ClusterName,
|
||||
[parameter(Mandatory = $true)]
|
||||
[array]$Nodes
|
||||
)
|
||||
|
||||
if (Init-Clustering) {
|
||||
return $true
|
||||
}
|
||||
Import-Module FailoverClusters
|
||||
[void](Test-Cluster -Cluster $ClusterName -Node $Nodes)
|
||||
[void](New-Cluster -Name $ClusterName -Node @("bravo.murano.local", "charlie.murano.local") -NoStorage)
|
||||
return $false
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue