Ps Pool Member Control
Problem this snippet solves:
This question comes up quite often here on DevCentral: "How can I gracefully shut down my servers for maintenance without disrupting current user sessions?". In fact, I answered this question just the other day again in the iControl forum and figured I'd throw out an application that accomplished this. So I went about writing this application to allow for the graceful shutdown of a given pool member. Of course, the application wouldn't be complete without listing the pools and members for a specified pool as well as allowing for enabling and disabling of the server so I went ahead and included those pieces as a bonus.
Code :
#---------------------------------------------------------------------------- # The contents of this file are subject to the "END USER LICENSE AGREEMENT FOR F5 # Software Development Kit for iControl"; you may not use this file except in # compliance with the License. The License is included in the iControl # Software Development Kit. # # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and limitations # under the License. # # The Original Code is iControl Code and related documentation # distributed by F5. # # The Initial Developer of the Original Code is F5 Networks, # Inc. Seattle, WA, USA. Portions created by F5 are Copyright (C) 1996-2007 F5 Networks, # Inc. All Rights Reserved. iControl (TM) is a registered trademark of F5 Networks, Inc. # # Alternatively, the contents of this file may be used under the terms # of the GNU General Public License (the "GPL"), in which case the # provisions of GPL are applicable instead of those above. If you wish # to allow use of your version of this file only under the terms of the # GPL and not to allow others to use your version of this file under the # License, indicate your decision by deleting the provisions above and # replace them with the notice and other provisions required by the GPL. # If you do not delete the provisions above, a recipient may use your # version of this file under either the License or the GPL #---------------------------------------------------------------------------- param ( $g_bigip = $null, $g_uid = $null, $g_pwd = $null, $g_pool = $null, $g_member = $null, $g_mode = $null ); Set-PSDebug -strict; #------------------------------------------------------------------------- # function Write-Usage #------------------------------------------------------------------------- function Write-Usage() { Write-Host "Usage: PoolMemberControl.ps1 host uid pwd [pool [member:ip [mode = "enable"|"disable"]]]"; exit; } #------------------------------------------------------------------------- # Get-Pools #------------------------------------------------------------------------- function Get-Pools() { $pool_list = (Get-F5.iControl).LocalLBPool.get_list(); Write-Host "Available Pools:"; foreach ($pool in $pool_list) { Write-Host " $pool"; } } #------------------------------------------------------------------------- # Get-PoolMembers #------------------------------------------------------------------------- Function Get-PoolMembers() { param($pool_name); $member_lists = (Get-F5.iControl).LocalLBPool.get_member((, $pool_name)); Write-Host "Members for Pool ${pool_name}:" foreach($member in $member_lists[0]) { $addr = $member.address; $port = $member.port; Write-Host " ${addr}:${port}" } } #------------------------------------------------------------------------- # Get-PoolMemberStatus #------------------------------------------------------------------------- Function Get-PoolMemberStatus() { param($pool_name, $member); $vals = $member.Split( (, ':')); $member_addr = $vals[0]; $member_port = $vals[1]; $bFound = 0; $MemberObjectStatusAofA = (Get-F5.iControl).LocalLBPoolMember.get_object_status((, $pool_name)); foreach($MemberObjectStatus in $MemberObjectStatusAofA[0]) { $a2 = $MemberObjectStatus.member.address; $p2 = $MemberObjectStatus.member.port; if ( "${member_addr}:${member_port}" -eq "${a2}:${p2}" ) { $Availability = $MemberObjectStatus.object_status.availability_status; $Enabled = $MemberObjectStatus.object_status.enabled_status; $Description = $MemberObjectStatus.object_status.status_description; Write-Host "Pool $pool_name, Member ${member_addr}:${member_port} status:" Write-Host " Availability : $Availability" Write-Host " Enabled : $Enabled" Write-Host " Description : $Description" $bFound = 1; } } if ( $bFound -eq 0 ) { Write-Host "Member ${member_addr}:${member_port} could not be found in pool $pool_name!" } } #------------------------------------------------------------------------- # Enable-Member #------------------------------------------------------------------------- function Enable-Member() { param($pool_name, $member); $vals = $member.Split( (, ':')); $member_addr = $vals[0]; $member_port = $vals[1]; $MemberMonitorState = New-Object -TypeName iControl.LocalLBPoolMemberMemberMonitorState; $MemberMonitorState.member = New-Object -TypeName iControl.CommonIPPortDefinition; $MemberMonitorState.member.address = $member_addr; $MemberMonitorState.member.port = $member_port; $MemberMonitorState.monitor_state = "STATE_ENABLED"; $MemberMonitorStateAofA = New-Object -TypeName "iControl.LocalLBPoolMemberMemberMonitorState[][]" 1,1 $MemberMonitorStateAofA[0][0] = $MemberMonitorState; Write-Host "Setting Montior State to Enabled"; (Get-F5.iControl).LocalLBPoolMember.set_monitor_state( (, $pool_name), $MemberMonitorStateAofA); $MemberSessionState = New-Object -TypeName iControl.LocalLBPoolMemberMemberSessionState; $MemberSessionState.member = New-Object -TypeName iControl.CommonIPPortDefinition; $MemberSessionState.member.address = $member_addr; $MemberSessionState.member.port = $member_port; $MemberSessionState.session_state = "STATE_ENABLED"; $MemberSessionStateAofA = New-Object -TypeName "iControl.LocalLBPoolMemberMemberSessionState[][]" 1,1 $MemberSessionStateAofA[0][0] = $MemberSessionState; Write-Host "Setting Session Enabled State to Enabled"; (Get-F5.iControl).LocalLBPoolMember.set_session_enabled_state( (, $pool_name), $MemberSessionStateAofA); Get-PoolMemberStatus $pool_name $member } #------------------------------------------------------------------------- # Disable-Member #------------------------------------------------------------------------- function Disable-Member() { param($pool_name, $member); $vals = $member.Split( (, ':')); $member_addr = $vals[0]; $member_port = $vals[1]; Write-Host "Disabling Session Enabled State..."; $MemberSessionState = New-Object -TypeName iControl.LocalLBPoolMemberMemberSessionState; $MemberSessionState.member = New-Object -TypeName iControl.CommonIPPortDefinition; $MemberSessionState.member.address = $member_addr; $MemberSessionState.member.port = $member_port; $MemberSessionState.session_state = "STATE_DISABLED"; $MemberSessionStateAofA = New-Object -TypeName "iControl.LocalLBPoolMemberMemberSessionState[][]" 1,1 $MemberSessionStateAofA[0][0] = $MemberSessionState; (Get-F5.iControl).LocalLBPoolMember.set_session_enabled_state( (, $pool_name), $MemberSessionStateAofA); Write-Host "Waiting for current connections to drop to zero..." $MemberDef = New-Object -TypeName iControl.CommonIPPortDefinition; $MemberDef.address = $member_addr; $MemberDef.port = $member_port; $MemberDefAofA = New-Object -TypeName "iControl.CommonIPPortDefinition[][]" 1,1 $MemberDefAofA[0][0] = $MemberDef; $cur_connections = 1; while ( $cur_connections -gt 0 ) { $MemberStatisticsA = (Get-F5.iControl).LocalLBPoolMember.get_statistics( (, $pool_name), $MemberDefAofA); $MemberStatisticEntry = $MemberStatisticsA[0].statistics[0]; $Statistics = $MemberStatisticEntry.statistics; foreach ($Statistic in $Statistics) { $type = $Statistic.type; $value = $Statistic.value; if ( $type -eq "STATISTIC_SERVER_SIDE_CURRENT_CONNECTIONS" ) { # just use the low value. Odds are there aren't over 2^32 current connections. # If your site is this big, you'll have to convert this to a 64 bit number. $cur_connections = $value.low; Write-Host "Current Connections: $cur_connections" } } Start-Sleep -s 1 } Write-Host "Disabling Monitor State..."; $MemberMonitorState = New-Object -TypeName iControl.LocalLBPoolMemberMemberMonitorState; $MemberMonitorState.member = New-Object -TypeName iControl.CommonIPPortDefinition; $MemberMonitorState.member.address = $member_addr; $MemberMonitorState.member.port = $member_port; $MemberMonitorState.monitor_state = "STATE_DISABLED"; $MemberMonitorStateAofA = New-Object -TypeName "iControl.LocalLBPoolMemberMemberMonitorState[][]" 1,1 $MemberMonitorStateAofA[0][0] = $MemberMonitorState; (Get-F5.iControl).LocalLBPoolMember.set_monitor_state( (, $pool_name), $MemberMonitorStateAofA); Get-PoolMemberStatus $pool_name $member } #------------------------------------------------------------------------- # Do-Initialize #------------------------------------------------------------------------- function Do-Initialize() { if ( (Get-PSSnapin | Where-Object { $_.Name -eq "iControlSnapIn"}) -eq $null ) { Add-PSSnapIn iControlSnapIn } $success = Initialize-F5.iControl -HostName $g_bigip -Username $g_uid -Password $g_pwd; return $success; } #------------------------------------------------------------------------- # Main Application Logic #------------------------------------------------------------------------- if ( ($g_bigip -eq $null) -or ($g_uid -eq $null) -or ($g_pwd -eq $null) ) { Write-Usage; } if ( Do-Initialize ) { if ( $g_pool -eq $null ) { Get-Pools; } elseif ( $g_member -eq $null ) { Get-PoolMembers $g_pool; } elseif ( $g_mode -eq $null ) { Get-PoolMemberStatus $g_pool $g_member; } else { switch ($g_mode.ToLower()) { "enable" { Enable-Member $g_pool $g_member; } "disable" { Disable-Member $g_pool $g_member; } default { Write-Usage; } } } } else { Write-Error "ERROR: iControl subsystem not initialized" }
Published Mar 09, 2015
Version 1.0CodeCentral_194
Cirrus
Joined May 05, 2019
CodeCentral_194
Cirrus
Joined May 05, 2019
No CommentsBe the first to comment