Skip to content

Instantly share code, notes, and snippets.

@mczerniawski
Last active October 9, 2018 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mczerniawski/ed38fbe881574fecb3c9702136a2b12a to your computer and use it in GitHub Desktop.
Save mczerniawski/ed38fbe881574fecb3c9702136a2b12a to your computer and use it in GitHub Desktop.
function Set-ClusterVMPreferredOwner {
<#
.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 PreferredOwner
Preferred Owner to set for given VM
.EXAMPLE
Set-ClusterVMPreferredOwner -Cluster 'Cluster' -VMName 'VM1' -PreferredOwner 'Node1' -Verbose
Will set Preferred Owner on VM1 to Node1
VERBOSE: Processing with default credentials of user {mczerniawski_admin}
VERBOSE: Given preferred owner {Node1} was found in nodes of cluster {Cluster}
VERBOSE: Processing VM {VM1}
VERBOSE: VM {VM1} current preferred owner: {}
VERBOSE: Setting preferred owner: {Node1} for VM {VM1}
VERBOSE: VM {VM1} current preferred owner: {Node1}
.EXAMPLE
Set-ClusterVMPreferredOwner -Cluster 'Cluster' -VMName 'VM1','VM2' -Credential (Get-Credential) -Verbose
Will set Preferred Owner on VM1 to Node1
VERBOSE: Processing with provided credentials {contoso\mczerniawski_admin}
VERBOSE: Provided no Preferred Owner. Will reset to default setting
VERBOSE: Processing VM {VM1}
VERBOSE: VM {VM1} current preferred owner: {Node1}
VERBOSE: Setting preferred owner: {} for VM {VM1}
VERBOSE: VM {VM1} current preferred owner: {}
VERBOSE: Processing VM {VM2}
VERBOSE: VM {VM2} current preferred owner: {}
VERBOSE: Setting preferred owner: {} for VM {VM2}
VERBOSE: VM {VM2} current preferred owner: {}
#>
[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[]]
$PreferredOwner
)
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
#region Validate Preferred Owner
$nodesInCluster = Invoke-Command -Session $ClusterSession -ScriptBlock {
Get-ClusterNode | Select-Object -ExpandProperty Name
}
#null or empty string - reset to defaults
if (-not $PreferredOwner) {
Write-Verbose -Message "Provided no Preferred Owner. Will reset to default setting"
$PreferredOwner = ''
}
#check if given hosts given in $PreferredOwner are members of $Cluster
else {
switch (Compare-Object -ReferenceObject @($nodesInCluster) -DifferenceObject @($PreferredOwner) -IncludeEqual ) {
{$PSItem.SideIndicator -eq '=>'} {
Write-Error -Message "Given preferred owner {$($PSItem.InputObject)} not found in nodes of cluster {$Cluster}. Aborting" -ErrorAction Stop
break
}
{$PSItem.SideIndicator -eq '=='} {
Write-Verbose -Message "Given preferred owner {$($PSItem.InputObject)} was found in nodes of cluster {$Cluster}"
}
}
}
#endregion
}
process {
foreach ($VM in $VMName) {
Write-Verbose -Message "Processing VM {$VM}"
$ClusterVM = Invoke-Command -Session $ClusterSession -ScriptBlock {
Get-ClusterGroup -Name $USING:VM -ErrorAction SilentlyContinue | Select-Object *
}
if (-not $ClusterVM) {
Write-Error -Message "VM {$VM} not found on cluster {$Cluster}"
}
else {
$currentPreferredOwners = Invoke-Command -Session $ClusterSession -ScriptBlock {
Get-ClusterGroup -Name $USING:VM | Get-ClusterOwnerNode | Select-Object -ExpandProperty OwnerNodes
}
Write-Verbose -Message "VM {$VM} current preferred owner: {$($currentPreferredOwners -join ',')}"
Write-Verbose -Message "Setting preferred owner: {$($PreferredOwner -join ',')} for VM {$VM} "
Invoke-Command -Session $ClusterSession -ScriptBlock {
Get-ClusterGroup -Name $USING:VM | Set-ClusterOwnerNode -Owners $USING:PreferredOwner
}
$currentPreferredOwners = Invoke-Command -Session $ClusterSession -ScriptBlock {
Get-ClusterGroup -Name $USING:VM | Get-ClusterOwnerNode | Select-Object -ExpandProperty OwnerNodes
}
Write-Verbose -Message "VM {$VM} current preferred owner: {$($currentPreferredOwners -join ',')}"
}
}
}
end {
$ClusterSession | Remove-PSSession -ErrorAction SilentlyContinue
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment