Экспорт данных из Avaya с использованием Powershell - PullRequest
0 голосов
/ 03 октября 2019

У меня был макрос в базе данных Access (32 бита), который использовался для загрузки данных из Avaya CMS, но из-за некоторых изменений программного обеспечения я больше не могу его использовать. Я подумал об использовании Powershell (в 32-битном режиме) для получения необходимых данных, но по какой-то причине он не работает ...

Макрос в базе данных Access раньше выглядел так:

Option Compare Database
Option Explicit
    Dim cvsApp As cvsApplication
    Dim cvsCon As cvsConnection
    Dim cvsSrv As cvsServer
    Dim cvsacd As cvsacd
    Dim cvsCatalog As cvsCatalog
    Dim cvsRpt As cvsReport
    Dim b As Object
    Dim Info As Object
    Global Const myAppName As String = "CMS Agent Data"
    Global Const myPath As String = "\\Data\Avaya\TempFiles\"

Sub AvayaLogin()
    Set cvsApp = CreateObject("acsup.cvsApplication")
    If cvsApp.CreateServer("login", "password", "", "server", False, "ENU", cvsSrv, cvsCon) Then
        If cvsCon.Login("login", "password", "server", "ENU") Then
        End If
    End If
End Sub

Sub AvayaLogout()
    On Error Resume Next
     'Closes out all Avaya
    cvsCon.Logout
    cvsCon.Disconnect
    Set cvsSrv = Nothing
    Set cvsCon = Nothing
    Set cvsApp = Nothing
End Sub

Sub AbnCallsData()
On Error Resume Next

Dim MyStartDate, MyStartTime(4), MyStopDate, MyStopTime(4), LastUpdateDate, LastUpdateTime, TimeZoneCounter As Integer, NNow, CNow
Dim TEXT1 As String
Dim FSO
Const TimeZone = 4

'Mop up previous days with this query
LastUpdateDate = DMin("Date", "SQL_LastUpdate")
LastUpdateTime = DMin("Time", "SQL_LastUpdate")
If LastUpdateDate = Date Then
    LastUpdateDate = DMax("Date", "SQL_LastUpdate")
    LastUpdateTime = DMax("Time", "SQL_LastUpdate")
End If
NNow = Format(Now(), "yyyy/mm/dd hh:nn:ss")
    MyStartDate = LastUpdateDate
    MyStartTime(1) = "00:00:00"
     MyStopTime(1) = "10:00:00"
    MyStartTime(2) = "10:00:00"
     MyStopTime(2) = "12:00:00"
    MyStartTime(3) = "12:00:00"
     MyStopTime(3) = "15:00:00"
    MyStartTime(4) = "15:00:00"
     MyStopTime(4) = "23:59:59"

    DoCmd.OpenForm "FrmPleaseWait"
    'Forms!FrmUpdatecms.Visible = False
    DoCmd.RepaintObject acForm, "FrmPleaseWait"

Do Until MyStartDate = Date + 1
    MyStopDate = MyStartDate

    For TimeZoneCounter = 1 To TimeZone
        If LastUpdateDate = Date And Format(LastUpdateTime, "hh:mm:ss") > MyStopTime(TimeZoneCounter) Then
        'Skip first few time zones if applicable
        Else
            CNow = Format(MyStartDate, "yyyy/mm/dd") & " " & MyStartTime(TimeZoneCounter)
            'End if after last time zone
            If NNow < CNow Then
                cvsRpt.Quit
                Exit For
            End If

            If LastUpdateDate = Date And Format(LastUpdateTime, "hh:mm:ss") >= MyStartTime(TimeZoneCounter) And Format(LastUpdateTime, "hh:mm:ss") <= MyStopTime(TimeZoneCounter) Then
'               Go back 30 minutes from latest record for same day
                MyStartTime(TimeZoneCounter) = (Format(LastUpdateTime - 1 / 48, "hh:mm:ss"))
            End If

            cvsSrv.Reports.ACD = "1"
            Set cvsCatalog = cvsSrv.Reports

    'OPENS THE AVAYA REPORT FOR CALL RECORDS
            Set cvsRpt = New cvsReport
            'cvsCatalog.CreateReport cvsCatalog.Reports.Item("Historical\Other\Call Records"), cvsRpt
            Set Info = cvsSrv.Reports.Reports("Historical\Designer\Call Records SL")
            b = cvsSrv.Reports.CreateReport(Info, cvsRpt)

                 'INPUTS THE REPORT CRITERIA
                 'STARTDATE
                If cvsRpt.SetProperty("Start Date", MyStartDate) Then
                Else
                End If
                'STARTTIME
                If cvsRpt.SetProperty("Start Time", MyStartTime(TimeZoneCounter)) Then
                Else
                End If
                'STOP DATE
                If cvsRpt.SetProperty("Stop Date", MyStopDate) Then
                Else
                End If
                'STOP TIME
                If cvsRpt.SetProperty("Stop Time", MyStopTime(TimeZoneCounter)) Then
                Else
                End If

                'Exports the Avaya report
                cvsRpt.FastLoad = True
                cvsRpt.ExportData myPath & "CallRecords" & ".CSV", 44, 0, True, True, True
                'Copy to SQL Server Box
                Set FSO = CreateObject("Scripting.FileSystemObject")
                If (FSO.FileExists(TSQLPath & "CallRecords" & ".CSV")) Then FSO.DeleteFile (TSQLPath & "CallRecords" & ".CSV")
                If (FSO.FileExists(myPath & "CallRecords" & ".CSV")) Then FSO.CopyFile myPath & "CallRecords" & ".CSV", TSQLPath & "CallRecords" & ".CSV"

                'Update Data in TSQl Server
                Call Update_SQL1

                If (FSO.FileExists(TSQLPath & "CallRecords" & ".CSV")) Then FSO.DeleteFile (TSQLPath & "CallRecords" & ".CSV")

                cvsRpt.Quit
            End If
        Next TimeZoneCounter

        MyStartDate = MyStartDate + 1
        Loop
        DoCmd.Close acForm, "FrmPleasewait"
        Call Update_SQL2
        Call AvayaLogout
End Sub

Я превратил это в что-то подобное в Powershell:

$cvsApp = New-Object -ComObject "ACSUP.cvsApplication"
$cvsCon = New-Object -ComObject "ACSCN.cvsConnection"
$cvsSrv = New-Object -ComObject "ACSUPSRV.cvsServer"
$Rep = New-Object -ComObject "ACSREP.cvsReport"

function Get-CallRecordDates {
some sql queries to get the dates I need to run it for
}

$dates = Get-CallRecordDates

$cvsCon.bAutoRetry = $true

$cvsApp.CreateServer("", "", "", "", $False, "ENU", [ref] $cvsSrv, [ref] $cvsCon) #Thank you HAL9256
$cvsCon.Login("", "", "", "ENU")
$cvsSrv.Reports.ACD = "1"

for($i=0; $i -lt $dates.Table.Rows.Count; $i++)
{
    $maindate = Get-Date "$(Get-Date $dates.Table.Rows.Item($i).Date -Format 'dd/MM/yyyy') $(Get-Date $dates.Table.Rows.Item($i).Time -Format 'HH:mm')"

    if($dates.Item($i).Commentary -eq "Last"){
        $startdatetime = $maindate.AddHours(-2)
        $enddatetime = Get-Date
        }else{
        $startdatetime = $maindate.AddHours(-1)
        $enddatetime = $maindate.AddHours(1)
    }

    $startdate = Get-Date $startdatetime -Format "dd/MM/yyyy"
    $starttime = Get-Date $startdatetime -Format "HH:mm"
    $enddate = Get-Date $enddatetime -Format "dd/MM/yyyy"
    $endtime = Get-Date $enddatetime -Format "HH:mm"

    $Info = $cvsSrv.Reports.Reports("Historical\Designer\Call Records SL")

    If($cvsSrv.Reports.CreateReport($Info,$Rep)){
        $Rep.TimeZone = "default"
        $Rep.SetProperty("Start Date",$startdate)
        $Rep.SetProperty("Start Time",$starttime)
        $Rep.SetProperty("Stop Date",$enddate)
        $Rep.SetProperty("Stop Time",$endtime)
        $Rep.FastLoad = $True
        $Rep.ExportData("C:\Users\me\Desktop\CallRecords$($i).csv", 44, 0, $True, $True, $True)
    }
    $dates = Get-CallRecordDates
}
$Rep.Quit()
$cvsCon.Logout()
$cvsCon.Disconnect()

Объект $ cvsSrv просто не видит соединения вообще. Он завершается с ошибкой в ​​строке $ cvsSrv.Reports.ACD = "1", говоря "Свойство 'ACD' не может быть найдено в этом объекте. Убедитесь, что свойство существует и его можно установить."Любые строки, в которых сценарий использует $ cvsSrv, просто возвращают ошибку.

Я пытался искать в Интернете, но я чувствую, что я единственный человек на Земле, который пытался жениться на Avaya и Powershell ...

Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 10 октября 2019

После многих проб и ошибок я не мог заставить это работать, поэтому я сдался и попробовал другой подход. Вот весь сценарий, который я запускаю для загрузки данных из Avaya на SQL Server с помощью PowerShell:

if(Get-Module -ListAvailable -Name SqlServer) {} else {Install-Module -Name SqlServer -AllowClobber -Confirm:$False -Force} #installs SqlServer module if not installed

function Get-CallRecordDates {
Invoke-Sqlcmd -Query “SELECT [Date],[Time],[Commentary] FROM [CallRecords].[dbo].[ForSQLload] order by [Date],[Time]” -ServerInstance "myserver"
}

$dates = @(Get-CallRecordDates)

#declare where the csv files will be saved
$csv = "G:\SQLDataLoad\Avaya"

#declare where the .acsauto file will be saved
$acsauto = "G:\SQLDataLoad\Avaya\CallRecordsJS.acsauto"

#These will format the acsauto file just right
$blockstart = "'LANGUAGE=ENU
'SERVERNAME=AvayaServerAddress
Public Sub Main()

On Error Resume Next

cvsSrv.Reports.ACD = 1
Set Info = cvsSrv.Reports.Reports(`"Historical\Designer\Call Records SL`")

If Info Is not Nothing Then
"

$blockend = "If Not cvsSrv.Interactive Then cvsSrv.ActiveTasks.Remove Rep.TaskID
Set Rep = Nothing

End If
Set Info = Nothing

End Sub"

#Start creating the content for acsauto file
$contentacsauto = $blockstart

#looping through the missing records. If there are none, it will only download the latest data.
for($i=0; $i -lt $dates.Count; $i++)
{
    $maindate = Get-Date "$(Get-Date $dates.Item($i).Date -Format 'dd/MM/yyyy') $(Get-Date $dates.Item($i).Time -Format 'HH:mm')"

    if($dates.Item($i).Commentary -eq "Last"){
        $startdatetime = $maindate.AddHours(-3)
        $enddatetime = Get-Date
        Write-Host "Adding time range to the script; from $startdatetime to $enddatetime `nIt will be exported to $csv\CallRecords-$i.csv`nTime is $(Get-Date) now."
        }else{
        $startdatetime = $maindate.AddHours(-1)
        $enddatetime = $maindate.AddHours(1)
        Write-Host "Adding time range to the script as some CallID is missing in that period; from $startdatetime to $enddatetime `nIt will be exported to $csv\CallRecords-$i.csv"
    }

    #formating the dates and times for the parameters
    $startdate = Get-Date $startdatetime -Format "dd/MM/yyyy"
    $starttime = Get-Date $startdatetime -Format "HH:mm"
    $enddate = Get-Date $enddatetime -Format "dd/MM/yyyy"
    $endtime = Get-Date $enddatetime -Format "HH:mm"

    $MiddleBlock = "
If cvsSrv.Reports.CreateReport(Info,Rep) Then
Rep.TimeZone = `"default`"
Rep.SetProperty `"Start Date`",`"$startdate`"
Rep.SetProperty `"Start Time`",`"$starttime`"
Rep.SetProperty `"Stop Date`",`"$enddate`"
Rep.SetProperty `"Stop Time`",`"$endtime`"
b = Rep.ExportData(`"$csv\CallRecords-$i.csv`", 44, 0, True, True, True)
Rep.Quit
End If
"

    $contentacsauto = $contentacsauto + $MiddleBlock
}

$contentacsauto = $contentacsauto + $blockend

$contentacsauto | Out-File $acsauto -Encoding ascii

& $acsauto

$stop = (Get-Date).AddMinutes(10)

while (((Get-ChildItem $csv -Filter "CallRecord*.csv").Count -lt $i) -and ($(Get-Date) -lt $stop)) {Start-Sleep -Seconds 2}

if($(Get-Date) -ge $stop) {
    Write-Host "This thing timed out as it took longer than 10 minutes to export, at $(Get-Date)"
    Get-Process "acs*" | Stop-Process -PassThru | Out-Null}
else{
Write-Host "Saved $((Get-ChildItem $csv -Filter "CallRecord*.csv").Count) file(s) at $(Get-Date)"

Start-Sleep -Seconds 2

$csvfiles = Get-ChildItem $csv -Filter "CallRecord*.csv"

$callrecords = Import-Csv -Path $csvfiles | Sort-Object 'Call ID','Segment' -Unique

Remove-Item $csvfiles -Force | Out-Null

Invoke-Sqlcmd -Query "delete from CallRecords.dbo.TempCallDataTemp" -ServerInstance "myserver"

Write-SqlTableData -InputData $callrecords -ServerInstance "myserver" -DatabaseName "CallRecords" -SchemaName "dbo" -TableName "TempCallDataTemp" -force
}

В основном я создаю файл "CallRecords.acsauto", который затем запускаю, подождите, пока все файлы будутготов (с проверкой, если он замерзает на 10 минут, он выключается), импортировать их и загрузить на сервер sql. Затем я вызываю кучу команд sql, чтобы отформатировать его и скопировать в основную таблицу.

0 голосов
/ 04 октября 2019

Из сообщения следует, что $csvSrv никогда не присваивается какое-либо значение

. При создании объектов COM они пусты. Когда вы вызываете функцию и передаете ей переменные в качестве параметров, вы должны передать переменные по ссылке , чтобы функция взяла объект и заполнила его. т.е.

$cvsApp = New-Object -ComObject "ACSUP.cvsApplication"
$cvsCon = New-Object -ComObject "ACSCN.cvsConnection"
$cvsSrv = New-Object -ComObject "ACSUPSRV.cvsServer"
$Rep = New-Object -ComObject "ACSREP.cvsReport"

...

$cvsApp.CreateServer("login", "password", "", "server", $False, "ENU", [ref] $cvsSrv, [ref] $cvsCon)

И аналогично (из комментариев) вам придется сделать то же самое с объектом $Rep:

...

$Info = $cvsSrv.Reports.Reports("Historical\Designer\Call Records SL")

...

If($cvsSrv.Reports.CreateReport($Info, [ref] $Rep)){
    $Rep.TimeZone = "default"
    ...

Обратите внимание, в этом случае у вас нетпередать $Info по ссылке. Это потому, что вы напрямую присваиваете возвращаемое значение из функции переменной $Info. Но для $Rep, поскольку он передается в качестве параметра, вам придется передать его на [ref], чтобы использовать его.

...