240 lines
6.6 KiB
PowerShell
240 lines
6.6 KiB
PowerShell
<#
|
|
.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"
|
|
}
|
|
|
|
foreach ($Node in $ClusterNodes) {
|
|
Write-LogDebug "Installing Failover Cluster modules on '$Node' ..."
|
|
$null = Invoke-Command `
|
|
-ComputerName $Node `
|
|
-Credential $Credential `
|
|
-ScriptBlock {
|
|
Add-WindowsFeature Failover-Clustering, RSAT-Clustering-PowerShell
|
|
}
|
|
}
|
|
|
|
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
|
|
#>
|
|
New-Cluster -Name "$ClusterName" -StaticAddress "$StaticAddress"
|
|
Start-Sleep -Seconds 30
|
|
}
|
|
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
|
|
#>
|
|
Add-ClusterNode -Cluster "$ClusterName" -Name "$Node"
|
|
}
|
|
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
|
|
|
|
#>
|