ES1_ArchiveConfiguration.psm1

<#
    .NOTES
    ===========================================================================
     
    Copyright � 2018 Dell Inc. or its subsidiaries. All Rights Reserved.

    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
    ===========================================================================
    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
    WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
    IF THIS CODE AND INFORMATION IS MODIFIED, THE ENTIRE RISK OF USE OR RESULTS IN
    CONNECTION WITH THE USE OF THIS CODE AND INFORMATION REMAINS WITH THE USER.

    .DESCRIPTION
        Functions for managing and configuring Archive Connections and servers

#>



Add-Type -TypeDefinition @"
public enum ArchiveType{
    IPM,
    NATIVE
}
"@



function New-ES1ArchiveConnection {
<#
.SYNOPSIS
    Create a new "Native" or "IPM" archive connection.
.DESCRIPTION
    Create a new "Native" or "IPM" archive connection.
    The SQL database should be created using the documented process. At least one archive server must be installed and setup to use
    the same SQL database specified.

.PARAMETER ArchiveName
    The name to be used for the new archive connection
.PARAMETER ArchiveType
    The type (NATIVE or IPM) of archive to be created.
.PARAMETER ArchiveDbServer
    Name of SQL server (and instance if applicable) hosting the new archive database
.PARAMETER ArchiveDbName
    Name of the database on the SQL server
.PARAMETER Description
    Text description of the new archive connection.

.EXAMPLE
    New-ES1ArchiveConnection -ArchiveName Archive2 -ArchiveDbServer sql2008 -ArchiveDbName ES1Archive2 -Description "Second Native Archive" -ArchiveType NATIVE


#>

[CmdletBinding()]
PARAM( [Parameter(Mandatory=$true)]
        [Alias('archive')]
        [string] $ArchiveName,
        [Parameter(Mandatory=$true)]
        [ArchiveType] $ArchiveType,
        [Parameter(Mandatory=$true)]
        [string] $ArchiveDbServer,
        [Parameter(Mandatory=$true)]
        [string] $ArchiveDbName,
        [Parameter(Mandatory=$false)]
        [string] $Description
        )

BEGIN{
        $MyDebug = $false
        # Do both these checks to take advantage of internal parsing of syntaxes like -Debug:$false
        if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey("Debug") -and $PSCmdlet.MyInvocation.BoundParameters["Debug"].IsPresent)
        {
            $DebugPreference = "Continue"
            Write-Debug "Debug Output activated"
            # for convenience
            $MyDebug = $true
        }

    try {
         [bool] $loaded = Add-ES1Types 

        if (-not $loaded )
        {
            Write-Error 'Error loading SourceOne Objects and Types'
            break
        }
    }
    catch
    {
        Write-Error $_ 
        break
    }
}

PROCESS {
 
    [EMC.Interop.ExBase.exDataProviderType] $S1ArchiveType= [EMC.Interop.ExBase.exDataProviderType]::exDataProviderType_Unknown

    try {

        $JDFAPIMgrClass = new-object -TypeName EMC.Interop.ExJDFAPI.CoExJDFAPIMgrClass
        $JDFAPIMgrClass.SetTraceInfo($Global:S1LogFile)

        $SQLServer = $ArchiveDbServer
        # Get only the server name, there might be a SQL instance specified
        if ($ArchiveDbServer.Contains('\'))
        {
            $names=$ArchiveDbServer.Split('\\')
            $SQLServer= $names[0]
        }
      
        
        # Make sure the DB server is reachable, archive database exists and some servers are configured
        $Available = Invoke-Ping -Computer $SQLServer 
        if ($Available.STATUS -eq 'Responding')
        {
            try {
                
                $PBAServers = @(Get-ES1NAServers -dbServer $ArchiveDbServer -dbName $ArchiveDbName)

             # $PBAServers = @(Invoke-ES1SQLQuery -SqlServer $ArchiveDbServer -DbName $ArchiveDbName -SqlQuery $SQLPBAServers)
              
               Write-Verbose "Found PBAServers : $($PBAServers)"

               if ($PBAServers.Length -le 0)
               {
                    throw "No Archive servers are installed for this connection. At least one archive server must be configured for $($ArchiveDbName)"
               }

            }
            catch [System.Management.Automation.MethodException]
            {
                throw "Cannot open connection to SQL Server $($ArchiveDbServer) and/or database $($ArchiveDbName) "
            }
            catch
            {
                # Re-throw other exceptions
                throw $_
            }
        }
        else
        {
            throw "SQL server $($SQLServer) is unreachable"
        }

        # Map type argument to ENUM value
        switch($ArchiveType)
        {
             IPM
             {
                $S1ArchiveType = [EMC.Interop.ExBase.exDataProviderType]::exDataProviderType_ExAsIPM
             }

             NATIVE
             {
                $S1ArchiveType = [EMC.Interop.ExBase.exDataProviderType]::exDataProviderType_ExAS
             }

        }

        if ($S1ArchiveType -eq [EMC.Interop.ExBase.exDataProviderType]::exDataProviderType_Unknown)
        {
            throw "Unsupported or Uknknown archive type specified"
        }

        
        # Create an Archive Provider Config object and put in the properties
        $providerCfg= new-object -ComObject ExAsProviderCfg.CoExAsProviderCfg
        $providerCfg.SetTraceInfo($Global:S1LogFile)
        $providerCfg.dbName =$ArchiveDbName
        $providerCfg.dbServer=$ArchiveDbServer
        $providerCfg.SetProperty('ProviderTypeID', $S1ArchiveType)

        # This does not validate access to the SQL server and DB. We did that above
        # TODO - Does this throw ??
        $cfgResults = $providerCfg.Validate()

        # Get properly formatted XML to pass into the Initialize for the ProviderTypeConfig
        $providerCfgXML = $providerCfg.GetXML()

        $newProvider = $JDFAPIMgrClass.CreateNewObject([EMC.Interop.ExJDFAPI.exJDFObjectType]::exJDFObjectType_ProviderTypeConfig)
        $newProvider.SetTraceInfo($Global:S1LogFile)
 
        $newProvider.name=$ArchiveName
        $newProvider.providerTypeID =  $S1ArchiveType   
        $newProvider.xConfig = $providerCfgXML
        $newProvider.description = $Description
  

        # This may throw for problems connecting to the activity DB
        $results = $newProvider.Validate()      
        
        # Validation errors are in the results
        foreach ($valResult in $results)
        {
            # Check the "IsWarning" attibute, false means fatal error
            if ($valResult.IsWarning -eq $false)
            {
                throw $valResult.errorDescription
            }
    
        }


        # Create a new archive repository object
        $newRepoClass = new-object -TypeName EMC.Interop.ExAsAdminAPI.CoExASRepositoryClass       
        $newRepoClass.SetTraceInfo($Global:S1LogFile)

        $propset = new-object -comobject ExDataSet.CoExPropertySet.1
        $propset.Item.InvokeSet($newProvider.xConfig,0)
        [string]$pName = $newProvider.name
     
        # Initialize the repository
        # this should work but doesn't. Which is why reflection and Invoke is used
        #$newRepoClass.Initialize($pName, $propset)

        $initMethod = $newRepoClass.GetType().GetMethod('Initialize')
        $initMethod.Invoke($newRepoClass, @($pName;$propset))
        
         #
        # 7.2+ Has Index validation setting which should be put into the new provider
        #
        $funcExists = $JDFAPIMgrClass | Get-Member -MemberType Method | where {$_.Name -eq 'GetSystemIndexValSettings'} 
        if ($funcExists)
        {
            $common = $newRepoClass.GetCommonConfig()
            $indexsettings = $JDFAPIMgrClass.GetSystemIndexValSettings()

            $common.EnableIndexVal  = $indexsettings.enableIndexVal;
            $common.EnableSchedule  = $indexsettings.enableSchedule;
            $common.EnableFixMode   = $indexsettings.enableFixMode;
            $common.ScheduleDay     = $indexsettings.scheduleDay;
            $common.StartTimeHour   = $indexsettings.startTimeHour;
            $common.StartTimeMin    = $indexsettings.startTimeMin;
            $common.NumbersToRepair = $indexsettings.numbersToRepair;
            $common.ScanMode        = $indexsettings.scanMode;
            
            $common.Save()
        }
  

        #
        # Since this is a new archive there are not too many shares to validate, if any
        # (I think the GUI does this for Edit use case not necessarily create)
        # Haven't been able to test this error path...
        $NetworkResults = @($newRepoClass.ValidateNetworkShare())
        
        if ($NetworkResults -and ($NetworkResults.Length -gt 0))
        {
            Write-Verbose "Error Validating network shares : $($NetworkResults)"
            throw "Error Validating network shares"
        }

        # Now Save it to create Archive Connection
        try
        {
                $claims = $newRepoClass.ClaimNetworkShare();

                $newProvider.Save()
                Write-Host "If the SourceOne Console is running you must restart it to refresh the Archive list" -BackgroundColor DarkYellow

        }
        catch
        {
            Write-Error $_

        }
        

    }
    catch {
        Write-Error $_

    }
    finally
    {
         if ($JDFAPIMgrClass)
         {
            [System.Runtime.Interopservices.Marshal]::ReleaseComObject($JDFAPIMgrClass) > $null
         }
         if ($providerCfg)    
         {
            [System.Runtime.Interopservices.Marshal]::ReleaseComObject($providerCfg) > $null
         }
         if( $newRepoClass)
         {
            [System.Runtime.Interopservices.Marshal]::ReleaseComObject($newRepoClass) > $null
            [System.Runtime.Interopservices.Marshal]::ReleaseComObject($propset) > $null
         }


    }


}

END{}

}




function Show-ArchiverRoles {
<#
.SYNOPSIS
    Display a list of SourceOne Archive machines and their enabled roles
    
.DESCRIPTION
    Display a list of SourceOne Archive machines and their enabled roles
.PARAMATER ArchiveName
    If specified get only the archive server roles for the archive connection specified. Otherwise servers for
    all archives are returned.
.EXAMPLE
    Show-ArchiverRoles

Number of Archives: 3

ArchiveName ServerName RolesValue Enabled Roles
----------- ---------- ---------- -------------
Archive1 s1Master7-J1.qagsxpdc.com 15 {Archive, Index, Query, Retrieval}
IPMArchive IPMWorker02.qagsxpdc.com 14 {Index, Query, Retrieval}
SecondIPM IPMArchive2.qagsxpdc.com 14 {Index, Query, Retrieval}

#>

    [CmdletBinding()]
    param( 
    [Parameter(Mandatory=$false)]
    [Alias('archive')]
    [string] $ArchiveName)

    begin {
        try {
            [bool] $loaded = Add-ES1Types #-ErrorAction SilentlyContinue

            if (-not $loaded )
            {
                Write-Error 'Error loading SourceOne Objects and Types'
                break
            }
        }
        catch
        {
            Write-Error $_ 
            break
        }


    }

    process {
        $asmgr = new-object -ComObject ExAsAdminAPI.CoExASAdminAPI

        $asmgr.Initialize()

        $ASRoles = [enum]::GetNames([EMC.Interop.ExASBaseAPI.exASServerPersonalities])
        Write-Debug "$($ASRoles)"

        if ($ArchiveName)
        {
             try {
                $ASRepos = @($asmgr.GetRepository($ArchiveName))
            }
            catch {
                throw "Error getting repository for connection $($ArchiveName). Check the name "
            }
        }
        else
        {
            $ASRepos = $asmgr.EnumerateRepositories()
        }

        Write-host Number of Archives: $ASRepos.Count
        $AllArchives = @()

        foreach ($repo in $ASRepos)
        {
            $Servers = @($repo.EnumerateServers())
            Write-Debug "Archive: $($repo.Name) has $($Servers.Count) servers"

            #
            # Add some new columns
            $Servers | Add-Member NoteProperty -Name "ArchiveName" -Value $repo.Name
            $Servers | Add-Member NoteProperty -Name "ArchiveRoles" -Value ""

            foreach ($server in $Servers)
            {
                $roles = @()
                $personality = $server.ServerPersonality

                for ($i = 0 ; $i -lt ($ASRoles.Length-1); $i++)
                {

                    [int] $bits = [EMC.Interop.ExASBaseAPI.exASServerPersonalities]$ASRoles[$i]

                    if ($personality -band $bits)
                    {
                        $roles += ([EMC.Interop.ExASBaseAPI.exASServerPersonalities]$ASRoles[$i]).ToString().Substring(10)
                    }

                }

                $server.ArchiveRoles=$roles

            }
            $AllArchives += $Servers

        } 

        $fmt = @{ Expression = { $_.ArchiveName }; label = "ArchiveName" },
        @{ Expression = { $_.FullName }; label = "ServerName" },
        @{ Expression = { $_.ServerPersonality }; label = "RolesValue" },
        @{ Expression = { $_.ArchiveRoles }; label = "Enabled Roles" }

        $AllArchives | Format-Table -AutoSize $fmt | Out-String -Width 10000

    }

    end {}
}

<#
.SYNOPSIS
    Get a list of SourceOne Archive server objects and their properties
    
.DESCRIPTION
    Get a list of SourceOne Archive server objects and their properties. The list of objects returned contains
    IExASServer objects with two additional properties added (ArchiveName and ArchiveRoles) for convenience.
.PARAMETER ArchiveName
    Optional, The archive connection name to get the server configruation for. If not provided the server configurations for all
    archives is returned.
    
.EXAMPLE
    $arServers=Get-ES1ArchiveServerConfig
    $arServers | Select ArchiveName,ArchiveRoles,MessageCenterDir,VersionInfo | ft -AutoSize

    ArchiveName ArchiveRoles MessageCenterDir VersionInfo
    ----------- ------------ ---------------- -----------
    Archive1 {Archive, Index, Query, Retrieval} \\S1MASTER64\MsgCenter\Message_Center 7.1.3.3054
    IPMArchive {Index, Query, Retrieval} 7.1.3.3054
    SecondIPM {Index, Query, Retrieval} 7.1.3.3054

#>

function Get-ES1ArchiveServerConfig
{
    [CmdletBinding()]
    param( 
    [Parameter(Mandatory=$false)]
    [Alias('archive')]
    [string] $ArchiveName)

    BEGIN {
        try {
            [bool] $loaded = Add-ES1Types #-ErrorAction SilentlyContinue

            if (-not $loaded )
            {
                Write-Error 'Error loading SourceOne Objects and Types'
                break
            }
        }
        catch
        {
            Write-Error $_ 
            break
        }


    }

  PROCESS {
        $asmgr = new-object -ComObject ExAsAdminAPI.CoExASAdminAPI

        $asmgr.Initialize()

        $ASRoles = [enum]::GetNames([EMC.Interop.ExASBaseAPI.exASServerPersonalities])
        Write-Debug "$($ASRoles)"

        if ($ArchiveName)
        {
             try {
                $ASRepos = @($asmgr.GetRepository($ArchiveName))
            }
            catch {
                throw "Error getting repository for connection $($ArchiveName). Check the name "
            }
        }
        else
        {
            $ASRepos = $asmgr.EnumerateRepositories()
        }
        
        $AllArchives = @()

        foreach ($repo in $ASRepos)
        {
            $Servers = @($repo.EnumerateServers())
            Write-Debug "Archive: $($repo.Name) has $($Servers.Count) servers"

            #
            # Add some new columns
            $Servers | Add-Member NoteProperty -Name "ArchiveName" -Value $repo.Name
            $Servers | Add-Member NoteProperty -Name "ArchiveRoles" -Value ""

            foreach ($server in $Servers)
            {
                $roles = @()

                # Decode the personality bits to something human readable
                $personality = $server.ServerPersonality

                for ($i = 0 ; $i -lt ($ASRoles.Length-1); $i++)
                {
                    [int] $bits = [EMC.Interop.ExASBaseAPI.exASServerPersonalities]$ASRoles[$i]

                    if ($personality -band $bits)
                    {
                        $roles += ([EMC.Interop.ExASBaseAPI.exASServerPersonalities]$ASRoles[$i]).ToString().Substring(10)
                    }

                }

                $server.ArchiveRoles=$roles

            }
            $AllArchives += $Servers

        } 

        $AllArchives

    }
    END {}

}

function Set-ArchiveServerRoles {
<#
.SYNOPSIS
    Set or change the Roles for an archive server
.DESCRIPTION
    Set or change the Roles for archive server(s) specified

    DYNAMIC PARAMETERS
    -MessageCenterLoc [string]
    If the "Archive" role is selected, the MessageCenter location for the server must be specified.

.PARAMETER ArchiveName
    Archive Connection name of the archive whose servers' roles will be modified
.PARAMETER ArchiveServerName
    Specific server name (fully qualified) which will be modified
    
.PARAMETER ServerRoles
    The roles (Archive,Index,Search,Retrieval) to be enabled. This will overwrite existing roles with only the roles specified here.

.PARAMETER ServersToIndex
    If the "Index" role is selected, a list of archive servers to index must be provided. This list of servers will overwrite any existing ones.

.EXAMPLE
    

#>

[CmdletBinding()]
PARAM( [Parameter(Mandatory=$true)]
        [Alias('archive')]
        [string] $ArchiveName,
        [Parameter(Mandatory=$true,
        ValueFromPipeLine=$true, 
        ValueFromPipeLineByPropertyName=$true)]
        [Alias("FullName")]
        [string[]] $ArchiveServerName,               #
        [Parameter(Mandatory=$true)]
        [ValidateSet ("ALL","ARCHIVE","INDEX", "SEARCH", "RETRIEVAL")]
        [string[]] $ServerRoles,             # handle a list of Roles...
        [Parameter(Mandatory=$false)]
        [string[]]$ServersToIndex            # handle a list of servers
        )

 DynamicParam {
        # Set up parameter attribute
        $MessageCenterLoc = New-Object System.Management.Automation.ParameterAttribute
        $MessageCenterLoc.Mandatory = $false
        $MessageCenterLoc.HelpMessage ="UNC to message center location "

        # Set up ValidateScript param with actual file name values
        $fileValidateParam = New-Object System.Management.Automation.ValidateScriptAttribute { 
            if (($ServerRoles -contains "ARCHIVE") -or ($ServerRoles -contains "All"))
            {
                if( -not (Test-Path $_) )
                {
                     throw "Message Center location does not exist or is not accessible"
                } 
                else 
                {
                    $true
                }
            }
            else 
            {
                $true
            }
        }

        # Add the parameter attributes to an attribute collection
        $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $attributeCollection.Add($MessageCenterLoc)
        $attributeCollection.Add($fileValidateParam)

        # Create the actual $MessageCenterLoc', parameter
        $fileParam = New-Object System.Management.Automation.RuntimeDefinedParameter('MessageCenterLoc', [string], $attributeCollection)

        # Push the parameter(s) into a parameter dictionary
        $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        $paramDictionary.Add('MessageCenterLoc', $fileParam)

        # Return the dictionary
        return $paramDictionary
    }


BEGIN {

        # Do some variable parameter validation
        if ((($ServerRoles -contains "ARCHIVE") -or ($ServerRoles -contains "All")) -and (-not $PSCmdlet.MyInvocation.BoundParameters.ContainsKey("MessageCenterLoc")))
        {
                Write-Error "ARCHIVE role requires the MessageCenterLoc parameter"
                break
        }

        if ((($ServerRoles -contains "INDEX") -or ($ServerRoles -contains "All"))-and (-not $PSCmdlet.MyInvocation.BoundParameters.ContainsKey("ServersToIndex")))
        {
                Write-Error "INDEX role requires ServersToIndex parameter"
                break
        }
        #
        # Because we used a DynamicParam to only validate if the "ARCHIVE" role is set,
        # we have to create the $MessageCenterLoc variable from the $PSBoundParameters
        #
        $MessageCenterLoc = $PSBoundParameters.MessageCenterLoc

        $MyDebug = $false
        # Do both these checks to take advantage of internal parsing of syntaxes like -Debug:$false
        if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey("Debug") -and $PSCmdlet.MyInvocation.BoundParameters["Debug"].IsPresent)
        {
            $DebugPreference = "Continue"
            Write-Debug "Debug Output activated"
            # for convenience
            $MyDebug = $true
        }

    try {
         [bool] $loaded = Add-ES1Types 

        if (-not $loaded )
        {
            Write-Error 'Error loading SourceOne Objects and Types'
            break
        }
    }
    catch
    {
        Write-Error $_ 
        break
    }
}

PROCESS {

    $asmgr = new-object -ComObject ExAsAdminAPI.CoExASAdminAPI
    $asmgr.Initialize()

    try {
        # Get the repository requested
        $repo=$asmgr.GetRepository($ArchiveName)

        # Get the servers configured for this archive/repository
        $Servers = @($repo.EnumerateServers())

        # Create the bitmask of roles
        [int] $newRoles=0
        foreach ($role in $ServerRoles)
        {
            switch ($role)
            {
                ARCHIVE
                {
                    $newRoles = $newRoles -bor [EMC.Interop.ExASBaseAPI.exASServerPersonalities]::exASServerArchive
                }
                INDEX
                {
                    $newRoles = $newRoles -bor [EMC.Interop.ExASBaseAPI.exASServerPersonalities]::exASServerIndex
                }

                SEARCH
                {
                    $newRoles = $newRoles -bor [EMC.Interop.ExASBaseAPI.exASServerPersonalities]::exASServerQuery
                }

                RETRIEVAL
                {
                    $newRoles = $newRoles -bor [EMC.Interop.ExASBaseAPI.exASServerPersonalities]::exASServerRetrieval
                }

                ALL
                {
                    $newRoles = [EMC.Interop.ExASBaseAPI.exASServerPersonalities]::exASServerAll
                }
            }
        }


        foreach ($machine in $Servers)
        {
            # Is this the machine we want to change roles on ?
            if ($machine.Fullname -eq $ArchiveServerName)
            {
                Write-Verbose "Found server to modify: $($machine.FullName)"
                # Yes it is...
                $machine.SetTraceInfo($Global:S1LogFile)
                $machine.ServerPersonality = $newRoles
    
               if ($newRoles -band [EMC.Interop.ExASBaseAPI.exASServerPersonalities]::exASServerArchive )
               {
                    Write-Verbose "Server $($machine.FullName) : Message Center Location set to $($MessageCenterLoc)"
                    $machine.MessageCenterDir = $MessageCenterLoc
               }

               if ($newRoles -band [EMC.Interop.ExASBaseAPI.exASServerPersonalities]::exASServerIndex )
               {                    
                    Write-Verbose "Server $($machine.FullName) : Enabling Indexing for $($ServersToIndex)"
                    $ArchiversToIndex = New-Object -ComObject ExSTLContainers.CoExVector

                    # The server names MUST match the same case as in the configruation so the UI
                    # will show the role enabled. We'll use the name S1 knows
                    foreach($S1host in $ServersToIndex)
                    {
                        $S1Name = $Servers | where {$_.FullName -eq $S1host}
                        if ($S1Name)
                        {
                            $ArchiversToIndex.Add($S1Name.FullName)
                        }
                        else
                        {
                            throw "Error: $($S1host) is not a server for this archive" 
                        }
                    }
                    
                    $machine.ArchiveServerNames=$ArchiversToIndex
                  
               }

               # Validate and Save if everything is OK
                   Write-Verbose "Validating new roles for Server $($machine.FullName)"
                $results = $machine.Validate()
                foreach ($valResult in $results)
                {
                    # Check the "IsWarning" attibute, false means fatal error
                    if ($valResult.IsWarning -eq $false)
                    {
                        throw $valResult.errorDescription
                    }
                    else
                    {
                        Write-Warning "$($valResult.errorDescription)"
                    }
    
                }

                Write-Verbose "Saving new configuration for Server $($machine.FullName)"
                $machine.Save()

                break
            }

        }

    }
    catch
    {
        Write-Error $_

    }
     finally
    {
         if ($asmgr)
         {
            [System.Runtime.Interopservices.Marshal]::ReleaseComObject($asmgr) > $null
         }


    }
 
}
END{}
}
<#
.SYNOPSIS
    
.DESCRIPTION

.PARAMETER ArchiveName
    Optional, The archive connection name to get the server configruation for. If not provided the server configurations for all
    archives is returned.
    
.EXAMPLE

#>

function Get-ES1ArchiveConnection
{
    [CmdletBinding()]
    param( 
    [Parameter(Mandatory=$false)]
    [Alias('archive')]
    [string] $ArchiveName)

    BEGIN {
        try {
            [bool] $loaded = Add-ES1Types #-ErrorAction SilentlyContinue

            if (-not $loaded )
            {
                Write-Error 'Error loading SourceOne Objects and Types'
                break
            }
        }
        catch
        {
            Write-Error $_ 
            break
        }


    }

  PROCESS {

  try {
            
        $JDFAPIMgrClass = new-object -TypeName EMC.Interop.ExJDFAPI.CoExJDFAPIMgrClass
        $JDFAPIMgrClass.SetTraceInfo($Global:S1LogFile)

        $providerCfgs = $JDFAPIMgrClass.GetProviderTypeConfigs()
        
        # If a single archive was passed in find it.
        if ($ArchiveName)
        {
            $ASRepos = @($providerCfgs | where {$_.Name -eq $ArchiveName} )
            if ($ASRepos.Length -le 0)
            {
                throw "Argument Error: Could not find any archive named $($ArchiveName))"
            }
        }
        else
        {
            $ASRepos = $providerCfgs
        }
        
        $AllArchives = @()

        foreach ($repo in $ASRepos)
        {
            $archiveDB='NA'
            $archiveDBServer='NA'

            $typeName = ([EMC.Interop.ExBase.exDataProviderType]$repo.providerTypeID).ToString().Substring(19)
            [System.Xml.XmlDocument] $XMLcfg=$repo.XConfig
            
            if (($repo.providerTypeID -eq [EMC.Interop.ExBase.exDataProviderType]::exDataProviderType_ExAS) -or `
                ($repo.providerTypeID -eq [EMC.Interop.ExBase.exDataProviderType]::exDataProviderType_ExAsIPM))
                {
                    $archiveDB=$XMLcfg.ExASProviderConfig.DBName
                    $archiveDBServer=$XMLcfg.ExASProviderConfig.DBServer
                }
            
            if ($repo.providerTypeID -eq [EMC.Interop.ExBase.exDataProviderType]::exDataProviderType_Ex4X) 
                {
                    $archiveDB=$XMLcfg.GeneralCfgProps.Servers.Server.DbConnection.SQLDBName
                    $archiveDBServer=$XMLcfg.GeneralCfgProps.Servers.Server.DBConnection.SQLServer
                }


            $props = [ordered]@{'ArchiveName'=$repo.Name;'ID'=$repo.Id ;'ProviderTypeID'=$repo.providerTypeID ; `
                                 'TypeName'=$typeName; 'DBServer'=$archiveDBServer; 'DBName'=$archiveDB; `
                                 'Created'=$repo.createTime; 'LastModfied'=$repo.lastModified; `
                                 'ModifiedBy'= $repo.modifiedBy}
            
            $AllArchives += New-object -TypeName PSObject -Prop $props
        } 

    }
 catch {
            Write-Error $_
        }
        finally
        {
        }

        $AllArchives

    }
    END {}

}

New-Alias -Name Get-ArchiveServerConfig -Value Get-ES1ArchiveServerConfig

Export-ModuleMember -Function * -Alias *