Atempo.Lina.psm1

<#
=========== MODULE STRUCTURE ===========
 
    This module contains the following file structure
        -- Atempo.Lina.psm1 : Global variables + Loading of functions (Common,Get,Set,New,Remove)
        -- Atempo.Lina.psd1 : Lina PowerShell Module manifest (description, release notes, icon, author etc)
        -- help.html : HTML Help file (usually opened using Get-LinaHelp)
        -- Functions/ : Folder containing all the functions/cmdlets
                |-- Common.ps1 : Connect/Disconnect and all internal functions
                |-- Get.ps1 : Get-Lina* / Listing elements
                |-- New.ps1 : New-Lina* / Creating elements
                |-- Remove.ps1 : Remove-Lina* / Deleting elements
                |-- Set.ps1 : Set-Lina* / Modifying elements
 
=========== TODO ===========
    Update QA Script for Get-LinaUser / UserGroup / Remove-LinaUserGroup
    New-LinaUserProfile from scratch ?
    AppVeyor Continuous integration + Docker on premise for testing ?
    Write-host green/red/orange
    All LinaUser cmdlet
    Manage disconnections error
    Use Invoke-WebRequest instead of RestMethod => uniformize returns inside functions and improve debug like in Miria module
    Use SecurePassword
    Clone a strategy ?
    Creation of Protections ?
    Managing LinaTenant auto-assignment rules
    manage list of replications
    managing all missing objects (paths, rules etc)
    Ability to pipe commands => should be done everywhere
#>


# Needed for URLEncode
Add-Type -AssemblyName System.Web

# Can be set to $False from calling script to enforce certificate checking
$global:GLOBAL_IGNORE_CERTIFICATES = $True

# an be set to $True from calling script to enable verbose logging
$global:LINA_DEBUG_MODE=$False


# ============ Internal Variables =============== #

# Path to the Functions dir containing all functions
$global:FUNCTIONS_DIR  = @( Get-ChildItem -Path $PSScriptRoot\Functions\*.ps1 -ErrorAction SilentlyContinue )

$global:LoggedSession = $null
$global:GLOBAL_LINA_SERVER = $null
$global:LINA_TRANSLATIONS = $null
$global:LINA_VERSION = $null
$global:INT_LINA_API_VERSION = $null

# Mapping PowerShell Lina Strategies Properties to Lina REST API properties
$global:INT_STRATEGIES_MAPPINGS= @{
    Name                        = "Name" ;
    RPOInMinutes                = "ParamSchedule" ;
    RetentionInDays             = "ParamDataAging" ;
    AlertAfterDays              = "ParamAlertTime" ;
    ThroughputLimitKBps         = "ParamThroughputLimit" ;
    AlwaysEncrypt               = "ParamEncryptionActivated" ;
    WanMode                     = "ParamWanActivated" ;
    CompressionAlgo             = "ParamCompression" ;
    ReplicationTargetID         = "ParamRepliTargetID";
    AllowClientRPO              = "ParamAllowClientRPO" ;
    AllowClientRules            = "ParamAllowClientRules" ;
    AllowClientPause            = "ParamAllowClientPause" ;
    AllowClientBoost            = "ParamAllowClientBoost" ;
    AllowClientNetworkParams    = "ParamAllowClientNetworkParams" ;
    AllowWebAccess              = "ParamAllowWebAccess" ;
    QuotaMaxProtSizeMB          = "ParamQuotaMaxProtSize" ;
    QuotaMaxProtObjs            = "ParamQuotaMaxProtObjs" ;
    QuotaMaxHistSizeMB          = "ParamQuotaMaxHistSize" ;
    QuotaMaxHistObjs            = "ParamQuotaMaxHistObjs" ;
    ReplicationTargets          = "RepliTarget" ;
    TenantID                    = "DomainID"
}
# Possible values for User Types (0, 3, 4 may not exist but it's to avoid crashes just in case)
$global:INT_USER_TYPES= @{ 
    1 = "Local";
    2 = "LDAP";
    3 = "LDAP Group";
    4 = "Unknown"
}

# Checking PowerShell version because Get-LinaUserProfile is using Enum variables and requires PowerShell >= 5
if ($PSVersionTable.PSVersion.Major -ge 5) {
    $global:ROLES1_LIST = [flags()] Enum ROLES1_LIST {
        ViewAlerts = 0x1
        SetAlerts  = 0x2
        ViewSupport = 0x4
        ViewUserProfiles   = 0x8
        CreateUserProfiles = 0x10
        DeleteUserProfiles = 0x20
        SetUserProfiles    = 0x40
        ViewUsers   = 0x80
        CreateUsers = 0x100
        DeleteUsers = 0x200
        SetUsers    = 0x400
        ViewServices = 0x800
        SetServices  = 0x1000
        ViewReplications   = 0x2000
        CreateReplications = 0x4000
        DeleteReplications = 0x8000
        SetReplications    = 0x10000
        AllowCrossResto = 0x200000
        AllowWebResto   = 0x400000
        ViewBMR     = 0x800000
        SetBMR      = 0x1000000
        AllowBMRResto   = 0x2000000 
    }
    $global:ROLES2_LIST = [flags()] Enum ROLES2_LIST {
        ViewFiles = 0x1
        ViewLicense = 0x2
        SetLicense  = 0x4
        ViewSmtp = 0x8 
        SetSmtp  = 0x10 
        ViewLdap = 0x20
        SetLdap  = 0x40
        ViewTunables         = 0x80
        SetTunables          = 0x100
        ViewAdvancedTunables = 0x200
        ViewStreams   = 0x400
        DeleteStreams = 0x800
        ViewStatistics      = 0x1000
        RecomputeStatistics = 0x2000
        ViewConfig   = 0x4000
        SetConfig    = 0x8000
        # Added Service after Restart to work automatically in Translate
        RestartService   = 0x10000
        ViewSnapshot   = 0x20000
        CreateSnapshot = 0x40000
        DeleteSnapshot = 0x80000 
    }
    $global:ROLES3_LIST = [flags()] Enum ROLES3_LIST {
        ViewAlnAgent   = 0x1
        CreateAlnAgent = 0x2
        DeleteAlnAgent = 0x4
        SetAlnAgent    = 0x8
        
        ViewAlnStrategy   = 0x10
        CreateAlnStrategy = 0x20
        DeleteAlnStrategy = 0x40
        SetAlnStrategy    = 0x80
        
        ViewAlnProtection   = 0x100
        CreateAlnProtection = 0x200
        DeleteAlnProtection = 0x400
        SetAlnProtection    = 0x800
        
        ViewAlnProtectionRule   = 0x1000
        CreateAlnProtectionRule = 0x2000
        DeleteAlnProtectionRule = 0x4000
        SetAlnProtectionRule    = 0x8000
    }
    $global:ROLES4_LIST = [flags()] Enum ROLES4_LIST {
        ViewAlnProtectionZone   = 0x1
        CreateAlnProtectionZone = 0x2
        DeleteAlnProtectionZone = 0x4
        SetAlnProtectionZone    = 0x8
        
        ViewAlnFileCategory   = 0x10
        CreateAlnFileCategory = 0x20
        DeleteAlnFileCategory = 0x40
        SetAlnFileCategory    = 0x80
        
        SetAlnDefaultConfiguration = 0x100
        
        ViewDomains = 0x200
        CreateDomains = 0x400
        DeleteDomains = 0x800
        SetDomains = 0x1000
 
        SetAlnGlobalDefaultConfiguration = 0x2000
    }

    # Calculating max values for each role, used for builtin accounts with negative values
    $global:ROLES1_MAX=0  
    [enum]::GetNames([ROLES1_LIST]) | ForEach-Object {$ROLES1_MAX+=$([ROLES1_LIST]::$_.value__)}
    $global:ROLES2_MAX=0
    [enum]::GetNames([ROLES2_LIST]) | ForEach-Object {$ROLES2_MAX+=$([ROLES2_LIST]::$_.value__)}
    $global:ROLES3_MAX=0 
    [enum]::GetNames([ROLES3_LIST]) | ForEach-Object {$ROLES3_MAX+=$([ROLES3_LIST]::$_.value__)}
    $global:ROLES4_MAX=0  
    [enum]::GetNames([ROLES4_LIST]) | ForEach-Object {$ROLES4_MAX+=$([ROLES4_LIST]::$_.value__)}


}else {
    # Declaring them for PS < 5.0 but won't work. Needs a workaround to avoid using Enum + flags (bitmasks)
    # Trying to avoid some crashes
    $global:ROLES2_LIST=@()
    $global:ROLES3_LIST=@()
    $global:ROLES4_LIST=@()
    $global:ROLES1_MAX=0
    $global:ROLES2_MAX=0  
    $global:ROLES3_MAX=0  
    $global:ROLES4_MAX=0 
}

# Loading dynamically all scripts containing the functions in Functions/
Foreach($import in @($FUNCTIONS_DIR))
{
    Try
    {
        . $import.fullname
    }
    Catch
    {
        Write-Error -Message "Failed to import function $($import.fullname): $_"
    }
}