ClusUtils.psm1

Import-Module $PSScriptRoot\PsHelper.psm1

function Test-IsCluster {

    param(
        [array]$ComputerName = @(hostname),
        [pscredential] $Credential = [pscredential]::Empty
    )
    $scriptBlock = {
        $feature = Get-WindowsFeature -name Failover-Clustering
        if ($feature -eq $null -or $feature.InstallState -ne "Installed") {
            return $false
        }

        try {
            $cluster = get-cluster -ErrorAction SilentlyContinue
        }
        catch {

        }

        return ($cluster -ne $null)
    }

    Invoke-ReliableCommand -computerName $ComputerName -credential $Credential -scriptblock $scriptBlock
}

function Test-IsMultiNodeCluster {

    $isCluster = Test-IsCluster
    
    if (-not $isCluster) {
        return $false
    }

    return (Get-ClusterNode).Count -gt 1  
}

function Get-CSV {
    if (-not $(Test-IsCluster)) {
        return $null
    }

    $csv = Get-ClusterSharedVolume -ErrorAction SilentlyContinue | Select -last 1

    if ($csv -eq $null) {
        return $null
    }

    return $csv.SharedVolumeInfo.FriendlyVolumeName
}

function Get-AllCSV {
    if (-not $(Test-IsCluster)) {
        return $null
    }

    $csv = Get-ClusterSharedVolume -ErrorAction SilentlyContinue

    if ($csv -eq $null) {
        return $null
    }

    return $csv.SharedVolumeInfo.FriendlyVolumeName
}

function Test-IsCsvPath {
    param(
        [parameter(Mandatory = $true)][string] $path
    )

    $csvs = Get-AllCSV

    if ($csvs -eq $null) {
        return $false
    }

    if (-not $csvs.GetType().BaseType.Name -eq "Array") {
        return $path.ToLower().StartsWith($csv.ToLower())
    }

    foreach ($csv in $csvs) {
        if ($path.ToLower().StartsWith($csv.ToLower())) {
            return $true
        }
    }

    return $false
}

function Wait-ForClusterNetwork {
    param(
        [string] $computerName = (hostname),
        [pscredential] $credential = [pscredential]::Empty,
        [Parameter(Mandatory = $true)] $subnet
    )


    $scriptBlock = {
        param($subnet)

        $maxRetry = 24
        $retry = 0
        $address = $subnet.Split("/")[0]
        while ($retry -lt $maxRetry) {
            $net = Get-ClusterNetwork | Where-Object { $_.Address -eq $address } 

            if ($net -ne $null) {
                return
            }

            Start-Sleep 5
            $retry++
        }

        throw "Timeout waiting for cluster network $subnet"
    }

    Invoke-ReliableCommand -computerName $computerName -credential $credential -scriptblock $scriptBlock -ArgumentList @($subnet)
}
function Set-ClusterNetworkToClient {
    param(
        [string] $computerName = (hostname),
        [pscredential] $credential = [pscredential]::Empty,
        [Parameter(Mandatory = $true)] $subnet
    )

    $scriptBlock = {
        param($subnet)
        $address = $subnet.Split("/")[0]
        $net = Get-ClusterNetwork | Where-Object { $_.Address -eq $address } 

        if ($net -ne $null) {
            $net.Role = 3
        }
    }

    Invoke-ReliableCommand -computerName $computerName -credential $credential -scriptblock $scriptBlock -ArgumentList @($subnet)
}