Created
October 19, 2018 09:01
-
-
Save mczerniawski/66f8f6d9cc38ed5d5ab2a7561cda8704 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Set-ClusterVMAntiAffinity { | |
<# | |
.SYNOPSIS | |
Will configure Preferred Owners for Virtual Machine running on Failover Cluster | |
.DESCRIPTION | |
Uses Invoke-Command to allow for PSCredential | |
If Preferred Owner is provided will verify if it matches cluster Owner Nodes. | |
If yes - will set Preferred Owners for given VMs. | |
If no - will abort. | |
If $null, or '' is provided will reset Preferred Owners to defaults for given VM | |
.PARAMETER Cluster | |
Cluster Name | |
.PARAMETER Credential | |
Optional PSCredential used to connect to cluster | |
.PARAMETER VMName | |
Virtual Machine Name or array of names to process | |
.PARAMETER AntiAffinityGroupName | |
AntiAffinity Group name to configure VM with. | |
.PARAMETER Append | |
Switch option whether group should be added to current set. | |
.EXAMPLE | |
Set two VMs 'windows2016' and 'windows2016core' with AntiAffinity Group named 'templates' | |
Set-ClusterVMAntiAffinity -Cluster 'cluster0' -VMName 'windows2016','windows2016core' -AntiAffinityGroupName 'Templates' -Verbose | |
VERBOSE: Processing with default credentials of user {mczerniawski_admin} | |
VERBOSE: Processing VM {windows2016} | |
VERBOSE: VM {windows2016} current AntiAffinity Groups: {} | |
VERBOSE: Setting Anti Affinity: {Templates} for VM {windows2016} | |
VERBOSE: Processing VM {windows2016core} | |
VERBOSE: VM {windows2016core} current AntiAffinity Groups: {Template} | |
VERBOSE: Setting Anti Affinity: {Templates} for VM {windows2016core} | |
Cluster VMName AntiAffinityGroupName | |
------- ------ --------------------- | |
cluster0 windows2016 Templates | |
cluster0 windows2016core Templates | |
.EXAMPLE | |
Add AntiAffinity Group named 'templates2' to two VMs 'windows2016' and 'windows2016core' | |
Set-ClusterVMAntiAffinity -Cluster 'cluster0' -VMName 'windows2016','windows2016core' -AntiAffinityGroupName 'Templates2' -Verbose -Append | |
VERBOSE: Processing with default credentials of user {mczerniawski_admin} | |
VERBOSE: Processing VM {windows2016} | |
VERBOSE: VM {windows2016} current AntiAffinity Groups: {Templates} | |
VERBOSE: Append selected. Preparing new object for AntiAffinity Group name for VM {windows2016}. | |
VERBOSE: Setting Anti Affinity: {Templates2} for VM {windows2016} | |
VERBOSE: Processing VM {windows2016core} | |
VERBOSE: VM {windows2016core} current AntiAffinity Groups: {Templates} | |
VERBOSE: Append selected. Preparing new object for AntiAffinity Group name for VM {windows2016core}. | |
VERBOSE: Setting Anti Affinity: {Templates2} for VM {windows2016core} | |
Cluster VMName AntiAffinityGroupName | |
------- ------ --------------------- | |
cluster0 windows2016 {Templates, Templates2} | |
cluster0 windows2016core {Templates, Templates2} | |
.EXAMPLE | |
Clear any Anti Affinity Group name on 'windows2016' VM | |
Set-ClusterVMAntiAffinity -Cluster 'cluster0' -VMName 'windows2016' -AntiAffinityGroupName $null -Verbose | |
VERBOSE: Processing with default credentials of user {mczerniawski_admin} | |
VERBOSE: Provided no AntiAffinity Group Name. Will reset to default setting | |
VERBOSE: Processing VM {windows2016} | |
VERBOSE: VM {windows2016} current AntiAffinity Groups: {} | |
VERBOSE: Setting Anti Affinity: {} for VM {windows2016} | |
Cluster VMName AntiAffinityGroupName | |
------- ------ --------------------- | |
cluster0 windows2016 | |
#> | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory, HelpMessage = 'Provide Cluster Name', | |
ValueFromPipeline, ValueFromPipelineByPropertyName)] | |
[ValidateNotNullOrEmpty()] | |
[System.String] | |
$Cluster, | |
[Parameter(Mandatory = $false, HelpMessage = 'Provide Credentials for Cluster', | |
ValueFromPipeline, ValueFromPipelineByPropertyName)] | |
[System.Management.Automation.PSCredential] | |
$Credential, | |
[Parameter(Mandatory, HelpMessage = 'Provide VMName', | |
ValueFromPipeline, ValueFromPipelineByPropertyName)] | |
[ValidateNotNullOrEmpty()] | |
[System.String[]] | |
$VMName, | |
[Parameter(Mandatory = $false, HelpMessage = 'Provide Preferred Owners Nodes to restrict VM to failover to', | |
ValueFromPipeline, ValueFromPipelineByPropertyName)] | |
[System.String[]] | |
$AntiAffinityGroupName, | |
[Parameter(Mandatory = $false, HelpMessage = 'Append AntiAffinity group to current set', | |
ValueFromPipeline, ValueFromPipelineByPropertyName)] | |
[switch] | |
$Append | |
) | |
begin { | |
#region PSSession parameters | |
$connectionParams = @{ | |
ComputerName = $Cluster | |
} | |
if ($PSBoundParameters.ContainsKey('Credential')) { | |
$connectionParams.Credential = $Credential | |
Write-Verbose -Message "Processing with provided credentials {$($Credential.UserName)}" | |
} | |
else { | |
Write-Verbose -Message "Processing with default credentials of user {$($env:USERNAME)}" | |
} | |
$ClusterSession = New-PSSession @connectionParams -ErrorAction Stop | |
#endregion | |
#null or empty string - reset to defaults | |
if (-not $AntiAffinityGroupName) { | |
Write-Verbose -Message "Provided no AntiAffinity Group Name. Will reset to default setting" | |
$AntiAffinityGroupName = '' | |
} | |
} | |
process { | |
foreach ($VM in $VMName) { | |
Write-Verbose -Message "Processing VM {$VM}" | |
$ClusterVM = Invoke-Command -Session $ClusterSession -ScriptBlock { | |
Get-ClusterGroup -Name $USING:VM -ErrorAction SilentlyContinue | |
} | |
if (-not $ClusterVM) { | |
Write-Error -Message "VM {$VM} not found on cluster {$Cluster}" | |
} | |
else { | |
Write-Verbose -Message "VM {$VM} current AntiAffinity Groups: {$($ClusterVM.AntiAffinityClassNames)}" | |
#set to defaults | |
if ($Append) { | |
Write-Verbose -Message "Append selected. Preparing new object for AntiAffinity Group name for VM {$VM}." | |
$finalAntiAffinityGroupName = @($ClusterVM.AntiAffinityClassNames) + @($AntiAffinityGroupName) | |
} | |
else { | |
$finalAntiAffinityGroupName = @($AntiAffinityGroupName) | |
} | |
Write-Verbose -Message "Setting Anti Affinity: {$AntiAffinityGroupName} for VM {$VM} " | |
$finalVMAntiAffinity = Invoke-Command -Session $ClusterSession -ScriptBlock { | |
(Get-ClusterGroup -Name $USING:VM).AntiAffinityClassNames = @($USING:finalAntiAffinityGroupName) | |
(Get-ClusterGroup -Name $USING:VM).AntiAffinityClassNames | |
} | |
[pscustomobject]@{ | |
Cluster = $Cluster | |
VMName = $VM | |
AntiAffinityGroupName = $finalVMAntiAffinity | |
} | |
} | |
} | |
} | |
end { | |
$ClusterSession | Remove-PSSession -ErrorAction SilentlyContinue | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment