Node/Pool/VIP Creation Script (from csv input)

Problem this snippet solves:

We deploy huge numbers of servers on a biweekly basis and need to create VIPs for groupings of them to load balance. this is a script i put together to ease that task. Fill out the 4 CSV sheets for Nodes, Pools, VIPs, and profiles for the VIPs. Run script, specify the IP of your BIG-IP and away it goes. Currently working with F5 support to allow blank values in profile import from csv, they provided an example that worked to leave blanks but also inputs none for values with an actual setting.

Code :

<#
F5 Script
Author: Will Longo
Design & Build - Clinical
#>
#load Snapin
if ( (Get-PSSnapin | Where-Object { $_.Name -eq "iControlSnapIn"}) -eq $null ){
Add-PSSnapIn iControlSnapIn}
Function Browse(){   
    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |Out-Null
    [System.Windows.Forms.Application]::EnableVisualStyles()
    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $OpenFileDialog.initialDirectory = (get-location).path
    $OpenFileDialog.filter = "CSV (*.csv)|*.csv|All files (*.*)|*.*"
    $loop = $true
    while($loop)
    {
        if ($OpenFileDialog.ShowDialog() -eq "OK")
        {
            $loop = $false
        } 
        else
        {
            $res = [System.Windows.Forms.MessageBox]::Show("You clicked Cancel. Try again or return to main form?", "Choose a directory", [System.Windows.Forms.MessageBoxButtons]::RetryCancel)
            if($res -eq "Cancel")
            {
                #End script
return
            }
        }
    }
    $OpenFileDialog.filename
}
Function ConfigSave{
$saveyn = read-host "Do you wish to sync your configuration? (Y/N)"
if($saveyn -eq "Y"){(Get-F5.iControl).SystemConfigSync.synchronize_configuration(1)}
else{write-host "Completed";return;}
}
Function VIP{
$vipINFILE = Import-Csv $vipCSV
foreach ($vipset in $vipINFILE | Where-object {$_.Sequence -eq $i})
{
$vipdefinition = New-Object -TypeName iControl.CommonVirtualServerDefinition;
$vipdefinition.name = $vipset.VIPName;
$vipdefinition.address = $vipset.VIPIP;
$vipdefinition.port = $vipset.VIPPort;
$vipdefinition.protocol = $vipset.Protocol;
$vipdefinitions = (, $vipdefinition);
$wildmasks = (, "255.255.255.255");
$resource = New-Object -TypeName iControl.LocalLBVirtualServerVirtualServerResource;
$resource.type = "RESOURCE_TYPE_POOL";
$resource.default_pool_name = $poolset.PoolName;
$resources = (, $resource);
$vippersistence = New-object -TypeName iControl.LocalLBVirtualServerVirtualServerPersistence;
$vippersistence.profile_name = $vipset.vippersistence
$vippersistence.default_profile = $null

$profileINFILE = import-csv $profileCSV
foreach ($profileset in $profileINFILE | where-object {$_.Sequence -eq $i})
{
$vipprofilehttp = New-Object -TypeName iControl.LocalLBVirtualServerVirtualServerProfile;
$vipprofilehttp.profile_context = "PROFILE_CONTEXT_TYPE_ALL";
$vipprofilehttp.profile_name = $profileset.http;
$vipprofilessl = New-Object -TypeName iControl.LocalLBVirtualServerVirtualServerProfile;
$vipprofilessl.profile_context = "PROFILE_CONTEXT_TYPE_CLIENT";
$vipprofilessl.profile_name = $profileset.SSLClient;
$vipprofileoneconnect = New-Object -TypeName iControl.LocalLBVirtualServerVirtualServerProfile;
$vipprofileoneconnect.profile_context = "PROFILE_CONTEXT_TYPE_ALL";
$vipprofileoneconnect.profile_name = $profileset.OneConnect;
}
$vipprofileA = ($vipprofilehttp, $vipprofilessl, $vipprofileoneconnect);
$vipprofileAofA = (, $vipprofileA);
(Get-F5.iControl).LocalLBVirtualServer.create($vipdefinitions,$wildmasks,$resources,$vipprofileAofA)
if($vipset.snat -eq "AutoMAP"){(Get-F5.iControl).LocalLBVirtualServer.set_snat_automap((, $vipset.VIPName))}
(Get-F5.iControl).LocalLBVirtualServer.Add_persistence_profile((,$vipset.VIPName),(,$vippersistence))
write-host $vipset.VIPName " created..."
}
}
Function Pool{
$poolINFILE = Import-Csv $poolCSV
foreach ($poolset in $poolINFILE | where-object {$_.Sequence -eq $i})
{
if($poolset.LoadBalanceMethod -eq "Round Robin"){$LBMethod = "LB_METHOD_ROUND_ROBIN"}
elseif($poolset.LoadBalanceMethod -eq "Observed (member)"){$LBMethod = "LB_METHOD_OBSERVED_MEMBER"}
elseif($poolset.LoadBalanceMethod -eq "Least Connections (member)"){$LBMethod = "LB_METHOD_LEAST_CONNECTION_MEMBER"}
elseif($poolset.LoadBalanceMethod -eq "Ratio (member)"){$LBMethod = "LB_METHOD_RATIO_MEMBER"}
elseif($poolset.LoadBalanceMethod -eq "Predictive (member)"){$LBMethod = "LB_METHOD_PREDICTIVE_MEMBER"}
else{Write-Host "Unknown Load Balance Method"}

$jPPortDefList = New-Object -TypeName iControl.CommonIPPortDefinition[] $MemberList.Length;
for($j=0; $j -lt $MemberList.Length; $j++)
{
$jPPortDefList[$j] = New-Object -TypeName iControl.CommonIPPortDefinition;
$jPPortDefList[$j].address = $MemberList[$j];
$jPPortDefList[$j].port = $poolset.MemberPort;
}
(Get-F5.iControl).LocalLBPool.create( (,$poolset.PoolName), (,$LBMethod), (,$jPPortDefList))
$monitor_association = New-Object -TypeName iControl.LocalLBPoolMonitorAssociation;
$monitor_association.pool_name = $poolset.PoolName;
$monitor_association.monitor_rule = New-Object -TypeName iControl.LocalLBMonitorRule;
$monitor_association.monitor_rule.type = "MONITOR_RULE_TYPE_SINGLE";
$monitor_association.monitor_rule.quorum = 0;
$monitor_association.monitor_rule.monitor_templates = (, $poolset.PoolHealthMonitor);
(Get-F5.iControl).LocalLBPool.set_monitor_association((, $monitor_association))
write-host $poolset.PoolName " created..."
VIP;
}
}
Function Node{
$nodeINFILE = Import-Csv $nodeCSV
foreach ($nodeset in $nodeINFILE)
{
(Get-F5.iControl).LocalLBNodeAddress.create( (,$nodeset.NodeIP), (,0) )
(Get-F5.iControl).LocalLBNodeAddress.set_screen_name( (,$nodeset.NodeIP), (,$nodeset.NodeName ) )
$nodeaddress = New-Object -TypeName iControl.LocalLBMonitorIP;
$nodeaddress.address_type = "ATYPE_STAR_ADDRESS"
$nodeaddress.ipaddress = $nodeset.NodeIP
$monitor_association2 = New-Object -TypeName iControl.LocalLBNodeAddressMonitorAssociation;
$monitor_association2.node_Address = $nodeaddress
$monitor_association2.monitor_rule = New-Object -TypeName iControl.LocalLBMonitorRule;
$monitor_association2.monitor_rule.type = "MONITOR_RULE_TYPE_SINGLE";
$monitor_association2.monitor_rule.quorum = 0;
$monitor_association2.monitor_rule.monitor_templates = (, $nodeset.HealthMonitor);
(Get-F5.iControl).LocalLBNodeAddress.Set_Monitor_Association((,$monitor_association2))
write-host $nodeset.NodeName " created..."
}
$i=1
$ilimiter=read-host "How many Pools are you creating? (Enter a value)"
while($i -le $ilimiter)
{
foreach ($poolmember in $nodeINFILE | where-object {$_.Sequence -eq $i})
{
[array]$memberlist += $poolmember.NodeIP
}
Pool;
Remove-variable memberlist
$i++
}
ConfigSave;
}
#Start
$BigIP = read-host "What is the IP of your F5 Big-IP Device"
#connect
Initialize-F5.iControl -HostName $Bigip -Credentials (Get-Credential);
$host.ui.RawUI.WindowTitle = "Will's F5 Script - Node"
$actorpass = (Get-F5.iControl).SystemFailover.get_failover_state()
if($actorpass -ne "FAILOVER_STATE_ACTIVE"){write-host "This is not the Active F5, Please re-run this script" -ForegroundColor Yellow -BackgroundColor Red;return}
#INPUT
write-host "select your Node CSV"
$nodeCSV = Browse
write-host "select your Pool CSV"
$poolCSV = Browse
write-host "select your VIP CSV"
$vipCSV = Browse
write-host "select your Profiles CSV"
$profileCSV = Browse
if (!$nodecsv){$cancel=$true}
if (!$poolcsv){$cancel=$true}
if (!$vipcsv){$cancel=$true}
if (!$profilecsv){$cancel=$true}
if ($cancel){write-host "Cancelled by User!" -ForegroundColor Yellow -BackgroundColor Red;return}
#start
Node;
Published Mar 08, 2015
Version 1.0
  • I keep getting an error stating "This is not the Active F5, Please re-run this script". I only have one F5 online right now so I don't know why i'm getting this error. Can someone please advise. Thanks.
  • dasz's avatar
    dasz
    Icon for Nimbostratus rankNimbostratus
    How these csv files should be prepared? Best Regards, Daniel