Public/Restart-NetScaler.ps1

<#
Copyright 2015 Brandon Olin
 
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
 
    http://www.apache.org/licenses/LICENSE-2.0
 
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
#>


function Restart-NetScaler {
    <#
    .SYNOPSIS
        Restart NetScaler appliance, with an option to save NetScaler config file before rebooting.
 
    .DESCRIPTION
        Restart NetScaler appliance, with an option to save NetScaler config file before rebooting.
 
    .EXAMPLE
        Restart-NetScaler
 
    .EXAMPLE
        Restart-NetScaler -Session $session -Force
 
    .EXAMPLE
        Restart-NetScaler -Session $session -SaveConfig
 
    .EXAMPLE
        Restart-NetScaler -Session $session -WarmReboot
 
    .EXAMPLE
        Restart-NetScaler -Wait -WaitTimeout 180
 
    .PARAMETER Session
        The NetScaler session object.
 
    .PARAMETER SaveConfig
        Save NetScaler config file before rebooting.
 
    .PARAMETER WarmReboot
        Perform a warm reboot of the NetScaler appliance.
 
    .PARAMETER Wait
        Wait for Nitro REST API is online after reboot.
 
    .PARAMETER WaitTimeout
        Timeout in seconds for the wait after reboot.
 
    .PARAMETER Force
        Suppress confirmation when rebooting NetScaler.
    #>

    [cmdletbinding(SupportsShouldProcess = $true, ConfirmImpact='High')]
    param(
        [parameter(Mandatory)]
        $Session = $script:session,

        [switch]$SaveConfig,

        [switch]$WarmReboot,

        [switch]$Wait,

        [int]$WaitTimeout = 900,

        [switch]$Force
    )

    begin {
        _AssertSessionActive
    }

    process {
        $ip = $($Session.EndPoint)
        if ($Force -or $PSCmdlet.ShouldProcess($ip, 'Reboot NetScaler appliance')) {

            if ($PSBoundParameters.ContainsKey('SaveConfig')) {
                Save-NSConfig -Session $Session
            }

            $params = @{
                warm=$WarmReboot.ToBool() 
            }
            _InvokeNSRestApi -Session $Session -Method POST -Type reboot -Payload $params -Action reboot

            $canWait = $true
            $ping = New-Object -TypeName System.Net.NetworkInformation.Ping
            if ($PSBoundParameters.ContainsKey('Wait')) {
                $waitStart = Get-Date
                Write-Verbose -Message 'Trying to ping until unreachable to ensure reboot process'
                while ($canWait -and $($ping.Send($ip, 2000)).Status -eq [System.Net.NetworkInformation.IPStatus]::Success) {
                    if ($($(Get-Date) - $waitStart).TotalSeconds -gt $WaitTimeout) {
                        $canWait = $false
                        break
                    } else {
                        Write-Verbose -Message 'Still reachable. Pinging again...'
                        Start-Sleep -Seconds 2
                    }
                } 

                if ($canWait) {
                    Write-Verbose -Message 'Trying to reach Nitro REST API to test connectivity...'
                    while ($canWait) {
                        $connectTestError = $null
                        $response = $null
                        try {
                            $params = @{
                                Uri = "$($script:protocol)://$ip/nitro/v1/config"
                                Method = 'GET'
                                ContentType = 'application/json'
                                ErrorVariable = 'connectTestError'
                            }
                            $response = Invoke-RestMethod @params
                        }
                        catch {
                            if ($connectTestError) {
                                if ($connectTestError.InnerException.Message -eq 'The remote server returned an error: (401) Unauthorized.') {
                                    break
                                } elseif ($($(Get-Date) - $waitStart).TotalSeconds -gt $WaitTimeout) {
                                    $canWait = $false
                                    break
                                } else {
                                    Write-Verbose -Message 'Nitro REST API is not responding. Trying again...'
                                    Start-Sleep -Seconds 2
                                }
                            }
                        }
                        if ($response) {
                            break
                        }
                    }
                }

                if ($canWait) {
                    Write-Verbose -Message 'NetScaler appliance is back online.'
                } else {
                    throw 'Timeout expired. Unable to determine if NetScaler appliance is back online.'
                }
            }
        }
    }
}