Functions/Connect-F5.psm1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
function Connect-F5 {

    <#
        .SYNOPSIS
            Connects to an active F5
        .EXAMPLE
            Connect-F5
        .LINK
            https://github.com/jorioux/F5-LTM-Helper
    #>


    param(
        [Parameter(Mandatory = $false)]
        [string]$SessionFile=$([system.io.path]::GetTempPath()+"f5-session.xml"),
        [string]$NamesFile=$([system.io.path]::GetTempPath()+"f5-names.xml"),
        [string]$CredFile=$([system.io.path]::GetTempPath()+"cred.xml"),
        [System.Management.Automation.PSCredential]$Credential,
        [switch]$Force
    )

    if($VerbosePreference -ne "SilentlyContinue"){
        $Verbose = $true
    } else {
        $Verbose = $false
    }

    $Session = $null

    Write-Verbose "Using session file: $SessionFile"

    if($Force) {

        Remove-Item -Path $SessionFile -ErrorAction SilentlyContinue -Verbose:$Verbose
        
    } elseif(Test-Path($SessionFile)) {

        $Session = Import-CliXml -Path $SessionFile -Verbose:$Verbose

        $Headers = New-Object "System.Collections.Generic.Dictionary``2[System.String,System.String]"
        $Headers.add('X-F5-Auth-Token',$Session.WebSession.Headers.'X-F5-Auth-Token')
        $Headers.add('Token-Expiration',$Session.WebSession.Headers.'Token-Expiration')
        $WebSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
        $WebSession.Headers = $Headers
        $Session.WebSession = $WebSession
        $Session = $Session | Add-Member -Name GetLink -MemberType ScriptMethod {
            param($Link)
            $Link -replace 'localhost', $this.Name
        } -PassThru 

        if($(Get-F5Status -F5Session $Session -ErrorAction SilentlyContinue -Verbose:$Verbose) -eq "ACTIVE"){
            Write-Verbose "Connected to active F5: $($Session.Name)"
            Write-Verbose $("Session token expiration: "+$Session.WebSession.Headers.'Token-Expiration')
            return $Session
        } else {
            Write-Warning "Not connected to an ACTIVE F5"
        }
    } else {
        Write-Verbose "Creating a new F5 session file"
    }

    if($Credential -eq $null){
        $Credential = Set-CredFile -Path $CredFile -Verbose:$Verbose
        if($Credential -eq $null){
            return $Session
        }
    }

    $F5Names = Set-F5NamesFile -Path $NamesFile -Verbose:$Verbose
    if($F5Names -eq $null){
        return $Session
    }
    
    $ActiveFound = $false

    #For each F5 name (or ip) in the f5-names.xml file
    $F5Names | ForEach-Object {

        #If the ACTIVE F5 have not been found yet
        if($ActiveFound -ne $true){

            Write-Verbose "Checking state of $_..."

            #Get session object
            $Session = New-F5Session -LTMName $_ -LTMCredentials $Credential -PassThru -ErrorAction SilentlyContinue -Verbose:$Verbose

            #If connection failed
            if($Session.LTMVersion -eq '0.0.0.0'){
                Write-Warning "Failed to connect to $_"
                $Session = $null

            #If connection is successful, check if its the ACTIVE F5
            } else {
                Write-Verbose "-->`tConnection is successful on $_"
                $F5Status = Get-F5Status -F5Session $Session -ErrorAction SilentlyContinue -Verbose:$Verbose
                if($F5Status -eq 'ACTIVE'){
                    Write-Verbose $("-->`tState of "+$_+": "+$F5Status)
                    $Session | Export-CliXml -Path $SessionFile -Verbose:$Verbose
                    Write-Verbose "Session exported to $SessionFile"
                    $ActiveFound = $true
                } else {
                    Write-Verbose $("-->`tState of "+$_+": "+$F5Status)
                }
            }
        }
    }
    if($Session -eq $null){
        Write-Warning "Cannot find active F5"
        if((read-host "Do you want to enter new F5 credentials ? (y/n)") -eq 'y'){
            Set-CredFile -Force -Verbose:$Verbose
        }
    }
    return $Session
}


Function Set-F5NamesFile {

    param(
        [Parameter(Mandatory = $false)]
        [string]$Path=$([system.io.path]::GetTempPath()+"f5-names.xml"),
        [switch]$Force
    )

    if($VerbosePreference -ne "SilentlyContinue"){
        $Verbose = $true
    } else {
        $Verbose = $false
    }

    $F5Names = $null

    Write-Verbose "Using F5 names file: $Path"

    if(!($Force)){
        try{
            $F5Names = Import-CliXml -Path $Path
            Write-Verbose "`tSuccessfully imported F5 names:"
            $F5Names | ForEach-Object {
                Write-Verbose "-->`t$_"
            }
        }catch{
            Write-Warning "Unable to import F5 names"
        }
    }

    if($F5Names -eq $null){
        Write-Verbose "Creating F5 names file..."
        $F5Names = @()
        do {
            $input = (Read-Host "Enter F5 names")
            if ($input -ne '') {$F5Names += $input}
        }
        until ($input -eq '')
        if($F5Names.count -ne 0){
            $F5Names | Export-CliXml -Path $Path
            Write-Verbose "F5 names exported to $Path"
        } else {
            Write-Warning "Failed to create F5 names file"
        }
    }
    return $F5Names
}