НАЗНАЧЕНИЕ СКРИПТА
Идея сценария состоит в том, чтобы рекурсивно извлечь текст из большого количества документов и обновить поле в базе данных SQL Azure, используя извлеченный текст.В основном мы переходим от поиска документов по содержимому Windows к полнотекстовому поиску SQL для повышения скорости.
ВЫПУСК
Когда сценарий сталкивается с проблемой открытия файлатакой как защищенный паролем, он терпит неудачу для каждого следующего документа.Вот раздел скрипта, который обрабатывает файлы:
foreach ($list in (Get-ChildItem ( join-path $PSScriptRoot "\FileLists\*" ) -include *.txt )) {
## Word object
$word = New-Object -ComObject word.application
$word.Visible = $false
$saveFormat = [Enum]::Parse([Microsoft.Office.Interop.Word.WdSaveFormat], "wdFormatText")
$word.DisplayAlerts = 0
Write-Output ""
Write-Output "################# Parsing $list"
Write-Output ""
$query = "INSERT INTO tmp_CachedText (tCachedText, tOID)
VALUES "
foreach ($file in (Get-Content $list)) {
if ($file -like "*-*" -and $file -notlike "*~*") {
Write-Output "Processing: $($file)"
Try {
$doc = $word.Documents.OpenNoRepairDialog($file, $false, $false, $false, "ttt")
if ($doc) {
$fileName = [io.path]::GetFileNameWithoutExtension($file)
$fileName = $filename + ".txt"
$doc.SaveAs("$env:TEMP\$fileName", [ref]$saveFormat)
$doc.Close()
$4ID = $fileName.split('-')[-1].replace(' ', '').replace(".txt", "")
$text = Get-Content -raw "$env:TEMP\$fileName"
$text = $text.replace("'", "''")
$query += "
('$text', $4ID),"
Remove-Item -Force "$env:TEMP\$fileName"
<# Upload to azure #>
$query = $query.Substring(0,$query.Length-1)
$query += ";"
Invoke-Sqlcmd @params -Query $Query -ErrorAction "SilentlyContinue"
$query = "INSERT INTO tmp_CachedText (tCachedText, tOID)
VALUES "
}
}
Catch {
Write-Host "$($file) failed to process" -ForegroundColor RED;
continue
}
}
}
Remove-Item -Force $list.FullName
Write-Output ""
Write-Output "Uploading to azure"
Write-Output ""
<# Upload to azure #>
Invoke-Sqlcmd @params -Query $setQuery -ErrorAction "SilentlyContinue"
$word.Quit()
TASKKILL /f /PID WINWORD.EXE
}
По сути, он анализирует папку с файлами .txt, которые содержат x количество путей к документам, создает инструкцию обновления T-SQL и работает сБаза данных SQL Azure после полного анализа каждого файла.Файлы генерируются следующим образом:
if (!($continue)) {
if ($pdf){
$files = (Get-ChildItem -force -recurse $documentFolder -include *.pdf).fullname
}
else {
$files = (Get-ChildItem -force -recurse $documentFolder -include *.doc, *.docx).fullname
}
$files | Out-File (Join-Path $PSScriptRoot "\documents.txt")
$i=0; Get-Content $documentFile -ReadCount $interval | %{$i++; $_ | Out-File (Join-Path $PSScriptRoot "\FileLists\documents_$i.txt")}
}
Переменная $ interval определяет, сколько файлов должно быть извлечено для каждой конкретной загрузки в Azure.Первоначально у меня был объект слова, созданный вне цикла, и никогда не закрывался до конца.К сожалению, это, похоже, не работает, так как каждый раз, когда скрипт попадает в файл, который он не может открыть, каждый последующий файл завершится ошибкой, пока не достигнет конца внутреннего цикла foreach foreach ($file in (Get-Content $list)) {
.
Это означает, что для получения ожидаемого результата мне нужно запустить его с интервалом 1, который занимает слишком много времени.