ES1_Configuration.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 inspecting the SourceOne configuration

#>


#requires -Version 3

<#
.SYNOPSIS
 Displays a list of S1 machines and the S1 installed executables and DLL
files in the S1 installation directory
.DESCRIPTION
Displays a list of S1 machines and the S1 installed executables and DLL
files in the S1 installation directory
.OUTPUTS

.EXAMPLE

#>

function Show-ES1Executables
{
[CmdletBinding()]
param( )

begin{}
process {
    [bool] $onMaster = Test-IsOnS1Master
    $scriptComputerName = [environment]::MachineName

    #-------------------------------------------------------------------------------
    # Get Activity Database
    #-------------------------------------------------------------------------------
    Get-ES1ActivityDB | out-null

    #-------------------------------------------------------------------------------
    # Get List of SourceOne Servers
    #-------------------------------------------------------------------------------
    $cServers = @()
    $cServers += $scriptComputerName

    # Get SourceOne Worker Servers
    $dtResults = Get-ES1Workers 
    foreach ($row in $dtResults)
    {
        $cServers += ($row[0].Split("."))[0]
    }


    $dtResults = @(Get-ES1Archivers)
    foreach ($row in $dtResults)
    {
        $cServers += ($row.Split("."))[0]
    } 


    # Remove Duplicates from SourceOne Server List
    $cServers = @($cServers | Select -uniq | Sort)
    $AllBinaries = @()

    Write-Debug "Server Count is: $($cServers.Count)"
    $local = hostname

    # Process each Server
    foreach ($server in $cServers)
    {
        Write-Host 'Getting binaries from server : ' $server

        try {
            $installPath = S1Dir $server

            # Append * so the -Include filter works...
            $installPath += '\*'

            if ($server -eq $local)
            {
                $exeFiles = ls -recurse -path $installpath -Include @("*.exe","*.dll") | select-object -ExpandProperty VersionInfo 
                $AllBinaries += $exeFiles
            }
            else
            {

                if (Test-PsRemoting $server)
                {

                    $files = Invoke-Command -Cn $server -ScriptBlock{
                        $exeFiles = ls -recurse -path $Args[0] -Include @("*.exe","*.dll") | select-object -ExpandProperty VersionInfo 
                        $exeFiles
                    } -Args $installPath -ErrorVariable remoteErr -ErrorAction SilentlyContinue

                    # $remoteErr contains any error message from the remote system
                    if ($remoteErr)
                    {
                        write-warning $remoteErr
                        $props = [ordered]@{'PSComputerName'=$server;'FileName'=$remoteErr ;'FileVersion'="ERROR"}
                        $AllBinaries += New-object -TypeName PSObject -Prop $props
                    }
                    else
                    {
                        $AllBinaries += $files
                    }
                }
                else
                {
                    write-warning "**** Ps Remoting is not enabled on remote $server ******"
                    $props = [ordered]@{'PSComputerName'=$server;'FileName'='NA' ;'FileVersion'="Unreachable - Powershell remoting not enabled"}
                    $AllBinaries += New-object -TypeName PSObject -Prop $props
                }
            }
        }
        catch 
        {
            Write-Warning "Error Reading registry on machine : $server"
            Write-Warning "Make sure the machine is up and reachable on the network"
            $props = [ordered]@{'PSComputerName'=$server;'FileName'=$_.Exception.Message ;'FileVersion'="NA"}
            $AllBinaries += New-object -TypeName PSObject -Prop $props

            continue
        } 

    } 

    #$AllBinaries | select-object PSComputerName, FileName, FileVersion | Format-Table -AutoSize #| Out-String -Width 10000
    
    # Now that POSH 4 or greater is required the [ordered] type above should mean the select to order things is not needed anymore
    
    $AllBinaries | Format-Table -AutoSize #| Out-String -Width 10000
}
end{}

}

<#
.SYNOPSIS
 Gets a list of S1 machines and the S1 installed executables and DLL
files in the S1 installation directory
.DESCRIPTION
Gets a list of S1 machines and the S1 installed executables and DLL
files in the S1 installation directory
.OUTPUTS

.EXAMPLE

#>

function Get-ES1Executables
{
[CmdletBinding()]
param( )

begin{}
process {
    [bool] $onMaster = Test-IsOnS1Master
    $scriptComputerName = [environment]::MachineName

    #-------------------------------------------------------------------------------
    # Get Activity Database
    #-------------------------------------------------------------------------------

    Get-ES1ActivityDB | out-null

    #-------------------------------------------------------------------------------
    # Get List known of SourceOne Servers
    #-------------------------------------------------------------------------------
    $cServers = @()
    $cServers += $scriptComputerName

    # Get SourceOne Worker Servers
    $dtResults = Get-ES1Workers 
    foreach ($row in $dtResults)
    {
        $cServers += ($row[0].Split("."))[0]
    }


    $dtResults = @(Get-ES1Archivers)
    foreach ($row in $dtResults)
    {
        $cServers += ($row.Split("."))[0]
    } 


    # Remove Duplicates from SourceOne Server List
    $cServers = @($cServers | Select -uniq | Sort)
    $AllBinaries = @()

    Write-Debug "Server Count is: $($cServers.Count)"
    $local = hostname

    # Process each Server
    foreach ($server in $cServers)
    {
        # Write-Host 'Getting binaries from server : ' $server

        try {
            $installPath = S1Dir $server

            # Append * so the -Include filter works...
            $installPath += '\*'

            if ($server -eq $local)
            {
                $exeFiles = ls -recurse -path $installpath -Include @("*.exe","*.dll") | select-object -ExpandProperty VersionInfo 
                $AllBinaries += $exeFiles
            }
            else
            {

                if (Test-PsRemoting $server)
                {

                    $files = Invoke-Command -Cn $server -ScriptBlock{
                        $exeFiles = ls -recurse -path $Args[0] -Include @("*.exe","*.dll") | select-object -ExpandProperty VersionInfo 
                        $exeFiles
                    } -Args $installPath -ErrorVariable remoteErr -ErrorAction SilentlyContinue

                    # $remoteErr contains any error message from the remote system
                    if ($remoteErr)
                    {
                        write-warning $remoteErr
                        $props = [ordered]@{'PSComputerName'=$server;'FileName'=$remoteErr ;'FileVersion'="ERROR"}
                        $AllBinaries += New-object -TypeName PSObject -Prop $props
                    }
                    else
                    {
                        $AllBinaries += $files
                    }
                }
                else
                {
                    write-warning "**** Ps Remoting is not enabled on remote $server ******"
                    $props = [ordered]@{'PSComputerName'=$server;'FileName'='NA' ;'FileVersion'="Unreachable - Powershell remoting not enabled"}
                    $AllBinaries += New-object -TypeName PSObject -Prop $props
                }
            }
        }
        catch 
        {
            Write-Warning "Error Reading registry on machine : $server"
            Write-Warning "Make sure the machine is up and reachable on the network"
            $props = [ordered]@{'PSComputerName'=$server;'FileName'=$_.Exception.Message ;'FileVersion'="NA"}
            $AllBinaries += New-object -TypeName PSObject -Prop $props

            continue
        } 

    } 

    
    $AllBinaries

}
end{}

}

<#
.SYNOPSIS
 Returns a string containing the S1 install directory from the machine specified (defaults to current machine)

.DESCRIPTION
 Returns a string containing the S1 install directory from the machine specified
 The Value is retrieved from the machine registry.

.PARAMETER server
 server or host Name to get the S1 install directory from

.OUTPUTS
 Set a session variable $S1InstallDir

.EXAMPLE
    Get-ES1InstallDir
    D:\Program Files\EMC SourceOne
.EXAMPLE
    Get-ES1InstallDir | out-null
    D:\Program Files\EMC SourceOne
#>

function Get-ES1InstallDir
{
[CmdletBinding()]
param( 
    [string] $server = $env:computername
)

begin{}
process {

    try {
        $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $server)
    }
    catch {

        Throw $_
    }

    # Try the 64 bit location first as 64 bit OS's are most common these days.
    $keypath = 'SOFTWARE\Wow6432Node\EMC\SourceOne'
    $regkey = $reg.OpenSubkey($keypath)
    if ($regkey -eq $null)
    {
        $keypath = 'SOFTWARE\EMC\SourceOne'
        $regkey = $reg.OpenSubkey($keypath)
    }

    if ($regkey -ne $null)
    {
        #
        # Get the install dir
        #
        $valuename ='InstallDir' 

        $readvalue = $regkey.GetValue($valuename) 
        if ($readvalue -ne 0)
        {
            Write-Debug "$server`t$regkey`t$valuename`t$readvalue" 
        }

        $reg.Close()
    }

    # Return the value from the registry...
    $readvalue
    $Script:S1InstallDir = $readvalue
}
end {}
}

$s1JobLogDir = ''
$emcRegEntry = ''
$emcRegLoc = ''
$s1ActServer = ''
$s1ActDb = ''
$s1ActObject = @{}

$s1Archivers = @()
$s1serverList = @()
$s1servers = @()
$S1RegBase = ''
$s1ServerInfoObjects = @()
$s1InstallObjects = @()


$AgentTable = @{'EMC SourceOne Console' = 'Console';
    'EMC SourceOne Native Archive Services' = 'Archive';
    'EMC SourceOne Master Services' = 'Master';
    'EMC SourceOne Search' = 'Search';
    'EMC SourceOne Worker Services' = 'Worker';
    'EMC SourceOne Web Services' = 'WebServices';
    'EMC SourceOne Mobile Services' = 'Mobile';
    'EMC SourceOne Discovery Manager Server' = 'DiscoveryManagerServer';
    'EMC SourceOne Discovery Express Manager Server' = 'DiscoveryManagerExpressServer';
    'EMC SourceOne Business Component Extensions for File Archiving' = 'FilearchiveBCE';
    'EMC SourceOne Business Component Extensions for Microsoft SharePoint' = 'SharepointBCE';
    'EMC SourceOne Discovery Manager Web' = 'DiscoveryManagerWeb'}


<#
.SYNOPSIS
  Returns a string containing the HKLM base path in the windows registry where SourceOne settings are found based on the
  OS architecture (64 bit or 32 bit)

.DESCRIPTION
   Returns a string containing the HKLM base path in the windows registry where SourceOne settings are found based on the
   OS architecture (64 bit or 32 bit). Depending on the OS either "HKLM:\SOFTWARE\Wow6432Node" or "HKLM:\SOFTWARE" will be returned.

.OUTPUTS
  <TBD>

.EXAMPLE
   $OSRegBase = Get-ES1RegBase
#>

function Get-ES1RegBase
{

[CmdletBinding()]
Param()

Begin{}
Process {
if ($Script:s1RegBase -eq '')
{
    if (Test-Path -Path HKLM:\SOFTWARE\Wow6432Node\EMC\SourceOne)
        {

            $Script:s1RegBase = "HKLM:\SOFTWARE\Wow6432Node"

        }
        else
        {
            $Script:s1RegBase = "HKLM:\SOFTWARE"

        } 

    }
    $script:S1RegBase
}

END {}

}

<#
.SYNOPSIS
  Returns a string containing the HKLM full path in the windows registry where SourceOne settings are found based on the
  OS architecture (64 bit or 32 bit).

.DESCRIPTION
  Returns a string containing the HKLM full path in the windows registry where SourceOne settings are found based on the
  OS architecture (64 bit or 32 bit). Depending on the OS architecture either "HKLM:\SOFTWARE\Wow6432Node\EMC\SourceOne\"
  or "HKLM:\SOFTWARE\EMC\SourceOne\" will be returned.

.OUTPUTS
  <TBD>

.EXAMPLE

#>

function Get-ES1RegEntry
 {
    [CmdletBinding()]
    param()
    Get-ES1RegBase | out-null
    if ($Script:emcRegEntry -eq '')
    {
        $Script:emcRegEntry = $script:S1RegBase + "\EMC\SourceOne\"
    }

    $Script:emcRegEntry
} 

<#
.SYNOPSIS
  Returns a string containing full provider name and HKLM path in the windows registry where SourceOne settings are found
  based on the OS architecture (64 bit or 32 bit).

.DESCRIPTION
  Returns a string containing full provider name and HKLM path in the windows registry where SourceOne settings are found
  based on the OS architecture (64 bit or 32 bit). Either "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\EMC\SourceOne\"
  or "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\EMC\SourceOne\"

.OUTPUTS
  <TBD>

.EXAMPLE
  $s1Registry= Get-ES1RegLocation

#>

function Get-ES1RegLocation
{
 [CmdletBinding()]
param()
get-ES1RegEntry | Out-Null
$Script:emcRegLoc = $Script:emcRegEntry.Replace("HKLM:","HKEY_LOCAL_MACHINE")
$Script:emcRegLoc = "Registry::" + $Script:emcRegLoc

$Script:emcRegLoc

}

<#
.SYNOPSIS
   Returns a string containing the full path of the SourceOne install directory on the current machine. This is obtained from the
   Windows registry.

.DESCRIPTION
   Returns a string containing the full path of the SourceOne install directory on tghe current machine. This is obtained from the
   Windows registry.

.OUTPUTS
  <TBD>

.EXAMPLE
    $S1InstallDir=Get-ES1InstallFolders
#>

function Get-ES1InstallFolders
 {
    [CmdletBinding()]
    param()

    get-ES1RegLocation | Out-Null

    $Node = get-itemproperty -path $Script:emcRegEntry -name installdir
    $Script:s1InstallDir = $Node.InstallDir
    $Script:s1LogDir = $Script:s1InstallDir + "logs\"
    $Script:s1InstallDir

}

<#
.SYNOPSIS
   Get-ES1JobLogDir
.DESCRIPTION
   Retrieve the location of the SourceOne JobLogs share
.OUTPUTS
 Sets a session variable $s1JobLogDir
.EXAMPLE
   Get-ES1JobLogDir
   \\master\JobLogs
#>

function Get-ES1JobLogDir
 {
    [CmdletBinding()]
    param()

    if ($Script:s1JobLogDir -eq '')
    {
        get-ES1RegLocation | Out-Null

        $Node = get-itemproperty -path $Script:emcRegEntry -name joblogdir -ErrorAction SilentlyContinue
        $Script:s1JobLogDir = $Node.JobLogDir

        if ($Script:s1JobLogDir -ne $null)
        {
            $Script:s1JobLogDir = $Node.JobLogDir
        }
        else
        {
            $Script:s1JobLogDir = Read-Host "JobLogDir entry not found $Script:emcRegEntry - Enter location "
            Write-Verbose $Script:s1JobLogDir
            if (!(Test-Path $Script:s1JobLogDir)) 
            {
                # this statement is not viewable if this function is called indirectly.
                Write-Host "Job share location is not valid"
                $Script:s1JobLogDir = ''
            }
        }
    } 
    $Script:s1JobLogDir

}



<#
.SYNOPSIS
   <A brief description of the script>
.DESCRIPTION
   <A detailed description of the script>
.PARAMETER <paramName>
   <Description of script parameter>
.EXAMPLE
   <An example of using the script>
#>



function Get-ES1ActivityDatabase
{
<#
.SYNOPSIS
  Gets the SourceOne SQL server and activity DB Name and if not already set, sets the session global
  variables $s1ActServer and $s1actDb
.DESCRIPTION
 Gets the SourceOne SQL server and activity DB Name and if not already set, sets the session global
  variables $s1ActServer and $s1actDb

.PARAMETER Force
    the Force parameter will cause the session global values to be updated/refreshed
.EXAMPLE
    $activityDB=Get-ES1ActivityDatabase

.EXAMPLE
    Get-ES1ActivityDatabase -force
    
DBName DBServer
---------- --------------
ES1Activity SQL2008

.OUTPUTS

#>

[CmdletBinding()]
param(
    [switch]$force
)
try
{
    if ($force -or ($Script:s1ActServer -eq '') -or ($Script:s1ActDb -eq ''))
    {

        $s1R = get-ES1RegLocation 
        #$s1RegVersion = $s1R + "versions"

        $script:s1ActServer = (Get-ItemProperty -Path $s1R).Server_JDF
        $script:s1actDb = (Get-ItemProperty -Path $s1R).DB_JDF

        if (!($script:s1ActServer))
        {
            $script:s1ActServer = Read-Host "Information cannot be retrieved from the registry, enter the name of the SourceOne SQL server"
            $script:s1ActDb = Read-Host "enter the name of the SourceOne Activity Database"
        }

        $script:s1ActInfo = @{'DBServer'=$script:S1ActServer;'DBName'=$script:s1ActDb}
        $script:s1ActObject = New-Object -TypeName psobject -Property $s1ActInfo
        $script:s1ActObject
    }
    else
    {

        $script:s1ActObject
    }

}
catch
{
    Write-Warning "Unable to access SourceOne registry information?"

}
}

<#
.SYNOPSIS
  Get-ES1Archivers
.DESCRIPTION
  Retrieve information from SQL about SourceOne Archive servers
.OUTPUTS
 Sets session array $s1Archivers
.EXAMPLE
   Get-ES1Archivers
   
   Archive01
   IPMArchive
   
#>

function Get-ES1Archivers
{
 [CmdletBinding()]
param()
#-------------------------------------------------------------------------------
# Get Activity Database
#-------------------------------------------------------------------------------
Get-ES1ActivityDB | out-null

$sqlQuery = @'
Select Name AS Connection,
       xConfig.value('(/ExASProviderConfig/DBServer)[1]','nvarchar(max)') AS DBServer,
       xConfig.value('(/ExASProviderConfig/DBName)[1]','nvarchar(max)') AS DBName
From ProviderConfig (nolock)
Where ProviderTypeID <> 5 AND State = 1
'@


$dtConnections = Invoke-ES1SQLQuery $Script:s1ActServer $Script:S1Actdb $sqlQuery


$cServers = @() 

# Get SourceOne Archiver Servers
foreach ($row in $dtConnections)
{
    $dbname = $row.DBName
    $dbserver = $row.DBServer 

    $dtResults = Get-ES1NAServers $dbServer $dbName
    #$dtResults

    foreach ($row in $dtResults)
    {
        $cServers += ($row[0].Split("."))[0]
    } 
} 

# Remove Duplicates from SourceOne Server List
$cServers = $cServers | Select -uniq | Sort
$cServers
$Script:s1Archivers = $cServers

}


#-------------------------------------------------------------------------------
# Function: Get-ES1NAServers
#-------------------------------------------------------------------------------
function Get-ES1NAServers
{
 [CmdletBinding()]

param
(
    [Parameter(Position=0,Mandatory=$true)]
    [string] $dbServer,

    [Parameter(Position=1,Mandatory=$true)]
    [string] $dbName
)

#
# Define SQL Query
#
$sqlQuery = @'
SELECT DISTINCT UPPER(ServerName) AS ServerName FROM ServerInfo (NOLOCK) WHERE LEN(MacAddress) > 0
'@


$dtResults = Invoke-ES1SQLQuery $dbServer $dbName $sqlQuery

$dtResultsMod = New-Object system.Data.DataTable 'Archivers'
$col1 = New-Object system.Data.DataColumn HostName,([string])
$dtResultsMod.columns.add($col1)

if ($dtResults -ne $null)
{
    foreach ($row in $dtResults)
    {
        $rowMod = $dtResultsMod.NewRow()
        if ($row.ServerName.Contains('.'))
        {
            $rowMod.HostName = $row.ServerName.Split('.')[0]
        }
        else
        {
            $rowMod.HostName = $row.ServerName 
        }
        $dtResultsMod.Rows.Add($rowMod)
    } 
}

$dtResultsMod 
}

<#
.SYNOPSIS
   Gets a list of all the SourceOne workers and archive servers
.DESCRIPTION
   Gets a list of all the SourceOne workers and archive servers using direct SQL queries.
   Does not return machine names which are in the "deleted" state (state=32767).

.EXAMPLE
   Get-ES1ServerList
 
 .EXAMPLE
   $allServers=Get-ES1ServerList

#>

function Get-ES1ServerList
{
 [CmdletBinding()]
param()
$serverList = @()

Write-verbose "Start - Number of Archivers $($Script:s1Archivers.count) "

if ($Script:s1Archivers.count -eq 0)
{
    Write-Verbose "Getting archive servers..."
    $Script:s1Archivers = @(Get-ES1Archivers)
}

Write-verbose "Number of Archivers found : $($Script:s1Archivers.count) "

foreach ($server in $Script:s1Archivers)
{
    Write-Verbose "Archiver Server : $($server)"
    $props = @{computername=$server}
    $obj = New-Object -TypeName psobject -Property $props
    $serverList += $obj
}

#
# s1Workers is exported from ES1_WorkerRolesUtils.psm1
#
Write-Verbose "Number of workers: $($Script:s1workers.count)"
if ($Script:s1Workers.count -eq 0)
{
    Write-Verbose "Getting worker servers..."
    $Script:s1Workers = @(Get-ES1Workers)
}

foreach ($s in $Script:s1Workers)
{

    $server = $s.servername.tostring()
    Write-Verbose "Worker Server: $($s | out-string )"

    $parts = $server.split('.')
    $props = @{computername=$parts[0]}
    $obj = New-Object -TypeName psobject -Property $props
    $serverList += $obj

}

write-verbose "Server List before dedup $($serverlist | Out-String)" 

$Script:s1serverList = $serverList | Select-Object computername -uniq 
$Script:s1serverList

} 

<#
.SYNOPSIS
   Retrieve a list/array of all SourceOne servers (workers and archivers)
.DESCRIPTION
   Retrieve a list/array of all SourceOne servers (workers and archivers)
.OUTPUTS s1servers
  Sets a session (global) array called $s1Servers with machine name of all workers and archiver servers

.EXAMPLE
   Get-ES1Servers
   
   master
   worker01
   IPMArchive
   Worker02
#>

function Get-ES1Servers
{
 [CmdletBinding()]
param()
$Script:s1servers = @()
if ($Script:s1serverList.Count -eq 0)
{
    write-verbose "Updating S1ServerList"
    Get-ES1ServerList | out-null
}
foreach ($s in $Script:s1serverlist)
{

    write-verbose $s.computername
    $Script:s1servers += $s.computername

}
$Script:s1servers
}

<#
.SYNOPSIS
   Get-ES1ServerSoftwareInfo
.DESCRIPTION
   Get a list of the EMC Sourceone Software on the specified server
   The uninstall registry key is queried
.PARAMETER computername
   name or IP of the server to query
.OUTPUTS
  a session array $s1SWObjects is populated and displayed
.EXAMPLE
   Get-ES1ServerSoftwareInfo master
   
  DisplayName Version
  EMC SourceOne Native Archive Services 7.20.2524
  EMC SourceOne Console 7.20.2524
  EMC SourceOne Web Services 7.20.2524
   
#>

function Get-ES1ServerSoftwareInfo
{
[CmdletBinding()]
param
(
 [string] $computername)



$Script:s1SWObjects = @()



$b = get-ES1RegBase
$b = $b.replace('HKLM:\','')
$entry = $b + "\Microsoft\Windows\CurrentVersion\Uninstall"
write-verbose $ComputerName

$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $ComputerName)
$Key = $Reg.OpenSubKey($entry)

if ($Key)
{

    foreach ($prop in $Key.GetSubKeyNames())
    {

        $KeyObj = $key.OpenSubKey($prop)
        if ($keyobj)
        {
            foreach ($entry in $KeyObj.GetValueNames())
            {


                if ($entry -eq "DisplayName")
                {

                    $dname = $keyobj.Getvalue("DisplayName")
                    #$dname
                    if ($dname -match "EMC")
                    {

                        write-verbose "$prop.ToString()"
                        $dvers = $keyobj.Getvalue("DisplayVersion")
                        $agentname = ''
                        if ($AgentTable.Contains($dname))
                        {
                            $agentname = $AgentTable.$dname
                        }

                        $swInfo = [ordered]@{'DisplayName'=$dname;'Version'=$dvers;'AgentName'=$agentname}
                        $swobj = New-Object -TypeName psobject -Property $swinfo
                        $Script:s1SWObjects += $swobj

                    }

                }
            }
        }
    }
}


$Script:s1SWObjects 


}


<#
.SYNOPSIS
  Returns an array of all the SourceOne services, software and version number installed on all
   discoverable machines in a SourceOne implementation

.DESCRIPTION
   Returns an array of all the SourceOne services, software and version number installed on all
   discoverable machines in a SourceOne implementation

.EXAMPLE
   $s1serversinfo = Get-ES1AllServerInfoObjects

#>

function Get-ES1AllServerInfoObjects
{

[CmdletBinding()]
param
()

if ($Script:s1servers.count -eq 0)
{
    get-ES1servers | out-null

} 



$Script:s1ServerInfoObjects = @()

foreach ($comp in $Script:s1servers)
{
    $swObjects = @()
    $srvObjects = @()
    Write-Verbose $comp


    try
    {
        $srvObjects = @(get-es1Services $comp)
        $swObjects = @(get-ES1ServerSoftwareInfo $comp)

        $mainprops = [ordered] @{servername=$comp;
            Software = $swObjects;
            Services = $srvObjects}
        $mainobject = New-Object -Type psobject -Property $mainprops
        Write-Verbose $mainobject
        $Script:s1ServerInfoObjects += $mainobject
    }
    catch
    {
        Write-Error $_
    }

}


$Script:s1ServerInfoObjects
}

<#
.SYNOPSIS
   Shows all the SourceOne services, software and version number installed on all
   discoverable machines in a SourceOne implementation
.DESCRIPTION
   Shows all the SourceOne services, software and version number installed on all
   discoverable machines in a SourceOne implementation

.EXAMPLE
 Show-ES1ServerInfo

Information for SourceOne server IPMARCHIVE2
Services on SourceOne server IPMARCHIVE2

Status Name DisplayName
------ ---- -----------
Running ES1AddressResolutionService EMC SourceOne Address Resolution
Running ES1InPlaceMigService EMC SourceOne Inplace Migration
Running ExAsAdmin EMC SourceOne Administrator
Stopped ExAsArchive EMC SourceOne Archive
Stopped ExAsIndex EMC SourceOne Indexer
Running ExAsQuery EMC SourceOne Query
Running ExJobDispatcher EMC SourceOne Job Dispatcher

Software Installed on SourceOne server IPMARCHIVE2

DisplayName Version AgentName
----------- ------- ---------
EMC SourceOne Native Archive Services 7.13.3054 Archive
EMC SourceOne In Place Migration Services 7.30.0084
EMC SourceOne Worker Services 7.13.3054 Worker


#>

function Show-ES1ServerInfo
{
[CmdletBinding()]
param
()

if ($Script:s1ServerInfoObjects.count -eq 0)
{

    Get-ES1AllServerInfoObjects > $null
}

foreach ($obj in $Script:s1ServerInfoObjects)
{

    write-output "Information for SourceOne server $($obj.servername)"
    write-output "Services on SourceOne server $($obj.servername)"
    $obj.services | Format-Table
    write-output "Software Installed on SourceOne server $($obj.servername)"
    $obj.software | Format-Table
}


}


<#
.SYNOPSIS
   Gets a list of objects containing simplified name for each installed service
   for each discoverable SourceOne machine.
.DESCRIPTION
   Gets a list of objects containing simplified name for each installed service
   for each discoverable SourceOne machine. The simple name if derived from an internal table
   lookup.

.EXAMPLE
   Get-ES1AgentListObjs

#>

function Get-ES1AgentListObjs
{
[CmdletBinding()]
param
([Parameter(Mandatory=$false,
        ValueFromPipeLine=$true, 
        ValueFromPipeLineByPropertyName=$true)]
    [string[]]$ComputerArray )

# TODO - Finish implementing the $ComputerArray ...

$Script:s1InstallObjects=@()

$S1InfoObjs = Get-ES1AllServerInfoObjects



foreach ($s in $S1InfoObjs)
{
    $rolestr = ""
    $mname = $s.servername
    Write-Verbose $mname
    Write-Verbose $s.software.count 
    if ($s.Software.count -gt 0)
    {
        foreach ($c in $s.Software)
        {
            Write-Verbose $c.agentname
            if ($c.agentname -ne '')
            {
                $role = $c.agentname
                $rolestr += "$role"
                $rolestr += ","
            }

        }
        if ($rolestr.length -gt 4)
        {
            $rolestr = $rolestr.Trim(",")
            # $rolestr += "`""
        }
    }

    $installInfo = [ordered]@{'MachineName'=$mname;'Role'=$RoleStr}
    $installObj = New-Object -TypeName psobject -Property $installInfo

    $Script:s1InstallObjects += $installObj

}

$Script:s1InstallObjects

}


<#
.SYNOPSIS
   Sets the SourceOne logging trace verbosity level in the Windows registry for the specified component
   on the specified computer. The component name is the same value as shown in the registry.
   Setting or changing a trace verbosity level will force logging to be enabled and set the maximum number
   of split files.
.DESCRIPTION
   Sets the SourceOne logging trace verbosity level in the Windows registry for the specified component
   on the specified computer. The component name is the same value as shown in the registry.
   Setting or changing a trace verbosity level will force logging to be enabled and set the maximum number
   of split files.

.PARAMETER Computer
    Name of the computer to change the trace settings on
.PARAMETER component
    Name of the component. Should be an exact match to the value in the "TraceLogs" registry hive.
.PARAMETER level
    Logging/trace level. Valid range is 0 - 7
.PARAMETER split
    Maximum number of "split" logfiles to keep on disk
.PARAMETER disable
    Disable logging for the component


.EXAMPLE
   Set-ES1Trace -level 0 -component exarchivejbc.exe

#>

function Set-ES1Trace 
{
[CmdletBinding()]
PARAM([Parameter(Mandatory=$true)]
    [string] $component,
    [Parameter(Mandatory=$false)] 
    [ValidateRange(0,7)] [int] $level = 4,
    [Parameter(Mandatory=$false)]
    [int]$split = 10,
    [Parameter(Mandatory=$false)]
    [switch] $disable,
    [Parameter(Mandatory=$false,
        ValueFromPipeLine=$true, 
        ValueFromPipeLineByPropertyName=$true)]
    [string[]]$ComputerArray =$env:COMPUTERNAME)
    

BEGIN {
    $Results=@()
}

PROCESS {

    Write-Host ""

    $ON = '1'
    if ($disable) 
    {
        $ON = '0'
    }

    foreach ($Computer in $ComputerArray )
    {
        $b = get-ES1RegBase
        $b = $b.replace('HKLM:\','')
        $entry = $b + "\EMC\SourceOne\Tracelogs"

        if ($component -ne $null)
        {
            $EMCTraceSettings = $entry + "\$component\Settings"
            write-verbose $EMCTraceSettings
            #$EMCTraceEnable = $EMCTraceSettings + "\Listeners\File"

            try
            {
                $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
                if ($Reg)
                {
                    $Key = $Reg.OpenSubKey("$EMCTraceSettings",$true)

                }
            }
            catch 
            {
                write-error "Error accessing registry on $($Computer)"
                $props = [ordered]@{'Computer'=$Computer;'Component'=$component ;'OldVerbosity'= 'NA'; 'TraceVerbosity'='NA';'Enabled'='NA'; 'Splits'='NA'}
                $Results += New-object -TypeName PSObject -Prop $props

                return
            }

            if ($key -ne $null)
            {

                if ($level.length -gt 0)
                {
                    $x = $key.GetValue("TraceVerbosity")

                    $key.SetValue("TraceVerbosity",$level,[Microsoft.Win32.RegistryValueKind]::DWORD) 
                    #write-host "Modified tracesetting on $($Computer) for $component from $x to $level"

                }
                #ensure that MaxFileSplits are set and Tracing is enabled.
                $FileKey = $Reg.OpenSubKey("$EMCTraceSettings\\Listeners\\File",$true)
                if ($FileKey)
                {
                    $FileKey.SetValue("Enabled",$ON,[Microsoft.Win32.RegistryValueKind]::DWORD) 
                    $FileKey.SetValue("MaxFileSplits",$split,[Microsoft.Win32.RegistryValueKind]::DWORD) 

                    #Write-Host "Logging Enabled = $ON, Max File Spilts set to $split"
                
                    $props = [ordered]@{'Computer'=$Computer;'Component'=$component ;'OldVerbosity'= $x; 'TraceVerbosity'=$level;'Enabled'=$ON; 'Splits'=$split}
                }
                else
                {
                    $props = [ordered]@{'Computer'=$Computer;'Component'=$component ;'OldVerbosity'= $x; 'TraceVerbosity'=$level;'Enabled'='NA'; 'Splits'='NA'}
                }

            }
            else
            {
                $props = [ordered]@{'Computer'=$Computer;'Component'=$component ;'OldVerbosity'= 'NA'; 'TraceVerbosity'='NA';'Enabled'='NA'; 'Splits'='NA'}
                write-host "Error reading Trace Setting for $component on $($Computer)" -ForegroundColor Red
            }
            
        }
            
        $Results += New-object -TypeName PSObject -Prop $props
        
    }

}  # end PROCESS

END{
    $Results
}

}


<#
.SYNOPSIS
   Sets the SourceOne logging trace level in the Windows registry for the all installed components
   on the specified computer to the specified level. Default level is 0 if none is specified.
.DESCRIPTION
   Sets the SourceOne logging trace level in the Windows registry for the all installed components
   on the specified computer to the specified level. Default level is 0 if none is specified.

.EXAMPLE
   Set-ES1ResetTraceAll
#>

function Set-ES1ResetTraceAll 
{
    [CmdletBinding()]
    PARAM(
    [Parameter(Mandatory=$false)] 
    [string] $level = 0,
    [Parameter(Mandatory=$false)]
    $split = 10,
    [Parameter(Mandatory=$false)]
    [switch] $disable,
    [Parameter(Mandatory=$false)]
    [string] $Computer = $env:COMPUTERNAME )

    $ON = '1'
    if ($disable) 
    {
        $ON = '0'
    }

    $b = get-ES1RegBase
    $b = $b.replace('HKLM:\','')
    $EMCTrace = $b + "\EMC\SourceOne\Tracelogs"

    try
    {
        $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
        if ($Reg)
        {
            $Key = $Reg.OpenSubKey("$EMCTrace",$true)

        }
    }
    catch 
    {
        write-error "Error accessing registry on $($Computer)"
        return
    }
    if ($key)
    {

        $TraceLogKeys = @($key.GetSubKeyNames())
        foreach ($entry in $TraceLogKeys)
        {

            Set-ES1Trace -component $entry -level $level -computer $Computer

        }

    }
    else
    {
        write-host "No trace setting found $($Computer)"

    }

}



$s1InstallDir = ''
$s1LogDir = ''

<#
.SYNOPSIS
   Gets a list of the SourceOne logs files from the SourceOne Logs directory

.DESCRIPTION
   Gets a list of the SourceOne logs files from the SourceOne Logs directory.
   The return list contains System.IO.FileInfo objects.

.PARAMETER filespec
   If provided only, that file if returned.
.EXAMPLE
   Get-ES1TraceLogs
   
    Directory: C:\Program Files (x86)\EMC SourceOne\logs

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 1/25/2017 2:55 PM 2 CExNotesInit.log
-a--- 12/14/2017 2:33 PM 75552228 EmailXtenderSystemTrace.log
-a--- 9/7/2017 2:17 PM 1071092 ES1AddressResolutionService.exe.log
-a--- 8/3/2015 3:01 PM 36644 ExArchiveJBC.exe.log
-a--- 8/3/2015 3:09 PM 83478 ExArchiveJBS.exe.log
-a--- 12/14/2017 2:33 PM 59876752 ExJBJournal.exe.log
-a--- 12/14/2017 1:51 PM 2076570 ExJournalJBS.exe.log
-a--- 4/12/2017 5:36 PM 152446 ExMMCAdmin.dll.log
-a--- 1/25/2017 2:55 PM 2 ExNotesApi.DLL.log


#>

function Get-ES1TraceLogs
{
[CmdletBinding()]

param([Parameter(Mandatory = $false)]
       [string] $fileSpec)

$eLoc = Get-ES1InstallFolders
$eLog = $eLoc + "logs\"
$Script:S1LogDIr = $eLog
$eLogSpec = $eLog + $fileSpec
gci $eLogSpec -ErrorAction SilentlyContinue



}


$WaitZipTime = 1

<#
.SYNOPSIS
   Compress a list of files into the named zip file. Uses the Windows Shell.Application COM object
.DESCRIPTION
    Compress a list of files into the named zip file. Uses the Windows Shell.Application COM object

.PARAMETER zipspec
    name of the zip file to create/update
   
.PARAMETER filespec
    list of files to zip

.EXAMPLE
   dir $s1JobLogDir\*28*.log | Compress-FileListToZip l28.zip
#>

function Compress-FileListToZip
 { 
    [CmdletBinding()]
    param(
    [string]$zipspec,
    [Parameter(ValueFromPipeLine=$true, 
    ValueFromPipeLineByPropertyName=$true)]
    [string[]]$filelist) 

BEGIN {

    $zipname = $zipspec

    if (-not $zipname.EndsWith('.zip')) {$zipname += '.zip'} 

    if (-not (test-path $zipname)) { 
        set-content $zipname ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) 
    } 
    else
    {
        Write-Verbose "adding to current zip file"
    }
    
    # The NameSpace method needs a FQ path to work
    $zipname = $zipname | get-item -ErrorAction Stop
    $shell = new-object -ComObject Shell.Application
    $ZipFile = $shell.NameSpace($zipname.FullName)
    #$ZipFile = (new-object -com shell.application).NameSpace($zipname)
}

    #
    # Process is called for each item in the pipeline !
    #
PROCESS {
    if ($ZipFile -ne $null)
    {
        foreach ($c in $filelist)
        {
            write-output $c
            $shortname=Split-Path -Path $c -Leaf
            $ZipFile.CopyHere($c)
            #$size = $ZipFile.Items().Item($shortname).Size

            # CopyHere is Asynchronous, need to wait before adding another....
            while($ZipFile.Items().Item($shortname) -Eq $null)
            {
                start-sleep -seconds $WaitZipTime
                write-verbose "." #-nonewline
            }

        }

    }
    else
    {
        Write-Output "unable to create NameSpace for $($zipname)"
    }
}

END {}

} 


<#
.SYNOPSIS
  Use the Windows Shell.Application COM object to unzip a file into a directory
.DESCRIPTION
   Use the Windows Shell.Application COM object to unzip a file into a directory

.PARAMETER zipspec
   Path of zip file to unzip

.PARAMETER destination
   Destination folder

.PARAMETER overwrite
   Overwrite the target file if it exists

.EXAMPLE
    TBD
#>

function Expand-ZipFile
{
[CmdletBinding()]
param([Parameter(Mandatory = $true)] [string] $zipspec, 
      [Parameter(Mandatory = $true)] [string] $destination,
      [Parameter(Mandatory = $false)] [switch] $overwrite
)


if (!(Test-Path $destination))
{
    mkdir $destination
}

$zipfile = (gci $zipspec).fullname

if (!(Test-Path $zipfile))
{
    Write-Host "$($zipfile) does not exit"
    return
}

$shell = new-object -com shell.application
$zip = $shell.NameSpace($zipfile)
foreach($item in $zip.items())
{

    $destFolder = $shell.Namespace($destination)
    if ($overwrite)
    {
        $destFolder.copyhere($item,16) #option to overwrite without asking?
    }
    else
    {
        $destFolder.copyhere($item)

    }

}
}

<#
.SYNOPSIS
   Compress a series of SourceOne logfiles into a single zip file.
.DESCRIPTION
   Compress a series of SourceOne logfiles into a single zip file.

.EXAMPLE
   <An example of using the script>
#>

function Compress-ES1TraceLogs
{
[CmdletBinding()]
param(
 [Parameter(Mandatory=$true)] 
[string] $filespec,
[Parameter(Mandatory=$true)]
[string] $zipfile )

$f = @(Get-ES1TraceLogs $filespec )
if ($f.count -gt 0)
{
    Compress-FileListToZip $zipfile $f
}
else
{
    Write-Host "No files found to compress"
}

}

<#
.SYNOPSIS
    Compress all logfiles in the SourceOne JobLogs into a single zip file.
.DESCRIPTION
    Compress all logfiles in the SourceOne JobLogs into a single zip file.

.EXAMPLE
   <An example of using the script>
#>

function Compress-ES1JobLogs
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string] $zipfile )

$f = @(Get-ES1JobLogs )
if ($f.count -gt 0)
{
    Compress-FileListToZip $zipfile $f 
}
else
{
    write-output "No files found to compress"
}

}

<#
.SYNOPSIS
   Gets the SourceOne logging trace verbosity level in the Windows registry for the specified component
   on the specified computer. The component name is the same value as shown in the registry.
   
.DESCRIPTION
   Gets the SourceOne logging trace verbosity level, logging enabled state, and number of log files to keep on disk
   fromm the Windows registry for the specified componenton the specified computer. The component name is the same
   value as shown in the registry. If Component is not provided info for all component values in the registry are returned.
   
.PARAMETER Computer
    Name of the computer to change the trace settings on
.PARAMETER Component
    Name of the component. Should be an exact match to the value in the "TraceLogs" registry hive.
    If not provided info for all component values in the registry are returned.

.EXAMPLE
   Get-ES1Trace -Component ES1ObjectViewer

Computer : IPMWORKER3
Component : ES1ObjectViewer
TraceVerbosity : 0
Enabled : 1
Splits : 10

.EXAMPLE
   Get-ES1Workers | foreach {$_.servername} | Get-ES1Trace | ft -AutoSize
   Computer Component TraceVerbosity Enabled Splits
-------- --------- -------------- ------- ------
IPMARCHIVE2.QAGSXPDC.COM CExNotesInit 0 1 10
IPMARCHIVE2.QAGSXPDC.COM CReportManager 0 1 10
IPMARCHIVE2.QAGSXPDC.COM ES1AddressResolutionService.exe 0 1 10
IPMARCHIVE2.QAGSXPDC.COM ES1DocConverter.exe 0 1 10
IPMARCHIVE2.QAGSXPDC.COM ES1InPlaceMigService.exe 4 1 10
IPMARCHIVE2.QAGSXPDC.COM ES1InPlaceMigValidation 0 1 10
IPMARCHIVE2.QAGSXPDC.COM ExAsAdmin.exe 0 1 10
IPMARCHIVE2.QAGSXPDC.COM ExAsArchive.exe 0 1 10
IPMARCHIVE2.QAGSXPDC.COM ExAsIndex.exe 0 1 10
IPMARCHIVE2.QAGSXPDC.COM exaslock 0 1 10
IPMARCHIVE2.QAGSXPDC.COM ExAsQuery.exe 0 1 10
IPMARCHIVE2.QAGSXPDC.COM ExAsSrch.exe 0 1 10
IPMARCHIVE2.QAGSXPDC.COM ExJBJournal.exe 0 1 10
IPMARCHIVE2.QAGSXPDC.COM ExJBQuery.exe 0 1 10
IPMARCHIVE2.QAGSXPDC.COM ExJobDispatcher.exe 0 1 10
IPMARCHIVE2.QAGSXPDC.COM ExJournalJBS.exe 0 1 10
IPMARCHIVE2.QAGSXPDC.COM System 0 1 10
IPMWORKER3.QAGSXPDC.COM CExNotesInit 0 1 10
IPMWORKER3.QAGSXPDC.COM CReportManager 0 1 10
IPMWORKER3.QAGSXPDC.COM ES1AddressResolutionService.exe 0 1 10
IPMWORKER3.QAGSXPDC.COM ES1InPlaceMigService.exe 0 1 10
IPMWORKER3.QAGSXPDC.COM ES1InPlaceMigValidation 0 1 10
IPMWORKER3.QAGSXPDC.COM ES1ObjectViewer 0 1 10
IPMWORKER3.QAGSXPDC.COM Ex2ES1MigrationCmd 0 1 10
IPMWORKER3.QAGSXPDC.COM ExArchiveJBC.exe 0 1 10
IPMWORKER3.QAGSXPDC.COM ExArchiveJBS.exe 0 1 10
IPMWORKER3.QAGSXPDC.COM ExJBJournal.exe 0 1 10
IPMWORKER3.QAGSXPDC.COM ExJobDispatcher.exe 0 1 10
IPMWORKER3.QAGSXPDC.COM ExJournalJBS.exe 0 1 10
IPMWORKER3.QAGSXPDC.COM ExMMCAdmin.dll 0 1 10
IPMWORKER3.QAGSXPDC.COM ExNotesApi.DLL 0 1 10

#>

function Get-ES1Trace 
{
[CmdletBinding()]
PARAM([Parameter(Mandatory=$false)]
    [string] $Component=$null,
    [Parameter(Mandatory=$false,
        ValueFromPipeLine=$true, 
        ValueFromPipeLineByPropertyName=$true)]
    [string[]]$ComputerArray =$env:COMPUTERNAME)
    

BEGIN {
    $Results=@()
}

PROCESS {

    Write-Host ""

    foreach ($Computer in $ComputerArray )
    {
        $b = get-ES1RegBase
        $b = $b.replace('HKLM:\','')
        $EMCTrace = $b + "\EMC\SourceOne\Tracelogs"
        
        if ($Component -ne $null -and $Component.Length -gt 0)
        {
            $TraceLogKeys = @($Component)
            write-verbose "Command line component name: $($TraceLogKeys)"
        }
        else
        {
            try
            {
                $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
                if ($Reg)
                {
                    $Key = $Reg.OpenSubKey("$EMCTrace",$true)
                    $Reg.Close()
                }
            }
            catch 
            {
                write-error "Error accessing registry on $($Computer)"
                return
            }

            if ($Key)
            {
                    $TraceLogKeys = @($Key.GetSubKeyNames())
                    $Key.Close()
                    write-verbose "All subkey names: $($TraceLogKeys)"

            }

        }    

        foreach ($TRentry in $TraceLogKeys)
        {
            $EMCTraceSettings = $EMCTrace + "\$TRentry\Settings"
            write-verbose $EMCTraceSettings
            #$EMCTraceEnable = $EMCTraceSettings + "\Listeners\File"

            try
            {
                $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
                if ($Reg)
                {
                    $Key = $Reg.OpenSubKey("$EMCTraceSettings",$true)

                }
            }
            catch 
            {
                write-error "Error accessing registry on $($Computer)"
                $props = [ordered]@{'Computer'=$Computer;'Component'=$TRentry ;'TraceVerbosity'='NA';'Enabled'='NA'; 'Splits'='NA'}
                $Results += New-object -TypeName PSObject -Prop $props

                continue
            }

            if ($key -ne $null)
            {
                $level = $key.GetValue("TraceVerbosity")
                $key.Close()

                $FileKey = $Reg.OpenSubKey("$EMCTraceSettings\\Listeners\\File",$true)

                if ($FileKey)
                {
                    $ON = $FileKey.GetValue("Enabled")
                    $split = $FileKey.GetValue("MaxFileSplits")
                
                    $props = [ordered]@{'Computer'=$Computer;'Component'=$TRentry ;'TraceVerbosity'=$level;'Enabled'=$ON; 'Splits'=$split}
                    $FileKey.Close()

                }
                else
                {
                    $props = [ordered]@{'Computer'=$Computer;'Component'=$TRentry ;'TraceVerbosity'=$level;'Enabled'='NA'; 'Splits'='NA'}
                }

            }
            else
            {
                $props = [ordered]@{'Computer'=$Computer;'Component'=$TRentry ;'TraceVerbosity'='NA';'Enabled'='NA'; 'Splits'='NA'}
                write-host "Error reading Trace Setting for $component on $($Computer)" -ForegroundColor Red
            }
                
            $Results += New-object -TypeName PSObject -Prop $props
        }
        
    }

}  # end PROCESS

END{
    $Results
}

}


Export-ModuleMember -Variable s1InstallDir
Export-ModuleMember -Variable s1JobLogDir
Export-ModuleMember -Variable s1LogDir
Export-ModuleMember -Variable s1servers

Export-ModuleMember -Variable s1archivers
Export-ModuleMember -Variable s1actdb
Export-ModuleMember -Variable s1actServer
Export-moduleMember -Variable s1serverinfoobjects


New-Alias -Name S1Dir -Value Get-ES1InstallDir
New-Alias -Name ES1Dir -Value Get-ES1InstallDir
New-Alias -Name S1Binaries -Value Get-ES1Executables
New-Alias -Name Get-S1Binaries -Value Get-ES1Executables

New-Alias Get-S1RegBase Get-ES1RegBase
New-Alias Get-S1RegEntry Get-ES1RegEntry
New-Alias Get-S1RegLocation Get-ES1RegLocation
New-Alias Get-S1InstallDir Get-ES1InstallDir
New-Alias Get-S1JobLogDir Get-ES1JobLogDir
#New-Alias Set-S1JobLogDir Set-ES1JobLogDir
New-Alias Set-S1ActivityInfo Set-ES1ActivityInfo
New-Alias Get-S1AgentListObjs Get-ES1AgentListObjs 
New-Alias Get-S1AllServerInfoObjects Get-ES1AllServerInfoObjects
New-Alias Get-S1Archivers Get-ES1Archivers
New-Alias Get-S1NAServers Get-ES1NAServers 
New-Alias Get-S1ServerList Get-ES1ServerList 
New-Alias Show-S1Servers Get-ES1ServerList 
New-Alias Show-ES1Servers Get-ES1ServerList 
New-Alias Get-S1Servers Get-ES1Servers 
New-Alias Get-S1ServerSoftwareInfo Get-ES1ServerSoftwareInfo 

New-Alias Show-S1ServerInfo Show-ES1ServerInfo
New-Alias Get-ES1ActivityDB Get-ES1ActivityDatabase

Export-ModuleMember -Function * -Alias *