Содержание

Microsoft Office 2016

setup.exe /admin запускает средство подготовки дистрибутива к административной установке.

GPO - включить обновления

$prop = @{
Path = 'HKLM:\software\policies\microsoft\office\16.0\common\OfficeUpdate'
Value = 1
PropertyType = 'DWORD'
Force = $true
Confirm = $false
}
New-Item $prop.path -Force
New-ItemProperty -Name EnableAutomaticUpdates @prop
New-ItemProperty -Name HideEnableDisableUpdates @prop

Обновления

Установка обновлений при установке Офиса.

Here is an article which lists the latest updates for MSI versions of Office: Latest updates for versions of Office that use Windows Installer (MSI).
Then you need to extract the MSP files from these updates, and put them into the Updates folder within your Office installation files.
If needed, you may refer to the references below for more detailed information about this process.
Updates folder
Deploying software updates with an initial Office 2013 installation

Вывести список обновлений

Если ставить Офис сразу с обновлениями (из папке Updates), то они не покажутся в списке через GUI, но их можно вывести через Powershell.

$PatchRegPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\*\Patches\*'
(Get-ItemProperty -Path $PatchRegPath).DisplayName

Скрипт извлечения обновлений из установленного Офиса

Подходит для 2010/2013/2016, после извлечения эти обновления кладутся в каталог Updates, чтобы они ставились прямо сразу при установке Офиса.

CollectOfficeUpdates.vbs

Looking for the best way to streamline updates for our MS Office 2016 install
Distribute updates for Office 2013 products

Microsoft Office 2016 Click to Run

Штатными средствами WSUS не обновляется, используется Office Deployment Tool, она скачивает дистрибутив с обновлениями в расшаренную папку, с этой папки обновляются клиенты.

C:\Scripts\office2016\setup.exe /download "C:\Scripts\office2016\Download-64-bit-Office-2016.xml"
C:\Scripts\office2016\setup.exe /download "C:\Scripts\office2016\Download-32-bit-Office-2016.xml"
Download-64-bit-Office-2016.xml
<Configuration>
  <Add SourcePath="C:\distrib\Office2016-updates" OfficeClientEdition="64" >
    <Product ID="O365ProPlusRetail">
      <Language ID="ru-ru" />
    </Product>
      </Add>  
  <Updates Enabled="TRUE" UpdatePath="\\wsus\distrib\Office2016-updates" /> 
  <Display Level="None" AcceptEULA="TRUE" />  
  <Logging Level="Standard" Path="%temp%" /> 
</Configuration>

Excel

Модули для Powershell для работы с .xls(x): PSExcel и ImportExcel. Установленный Excel не требуется, используется механизм .NET.

PSExcel: Excel automation without Excel

# Установить для пользователя (путь $env:userprofile\Documents\WindowsPowerShell\Modules\ImportExcel)
Install-Module -Name ImportExcel -Scope CurrentUser -SkipPublisherCheck
# Примеры работы
Import-Excel c:\temp\all.xlsx -WorksheetName processes -StartColumn 1 -EndColumn 1 |select -expand name -Unique
Get-Service |Export-Excel -Show

.xls → .xlsx:

& "(gci "${env:ProgramFiles(x86)}\Microsoft Office" -recurse |? name -eq excelcnv.exe).fullname" -oice "$xls" "$($xls.FullName -replace '.xls','.xlsx')"

ImportExcel

Using the Import-Excel module: Part 1 Importing
Using the Import Excel module part 2: putting data into .XLSx files
Using the import Excel Module: Part 3, Pivots and charts, data and calculations
More tricks with PowerShell and Excel

Excel reports using ImportExcel module from Powershell gallery

# Раньше Эксель надо было использовать через ком-объект, имея установленный Эксель на компьютере:
$xl = New-Object -ComObjext excel.application
$xl.Visible = $true # чтобы запустить эксель и видеть изменения
$wb = $xl.workbooks.add() # добавить пустую книгу
$ws = $wb.worksheets["Sheet1"] # выбрать лист
$ws.cells[1, 1].value = "ID" # прописать значение [строка, столбец]
$ws.cells[2, 5].formula = "=C2*D2" # прописать формулу
# Заполнение таблиц таким образом трудоёмкое
 
# ImportExcel не требует установленного Экселя на компьютере и автоматизирует работу
# Список команд модуля
(Get-Module importexcel).ExportedCommands.Keys |sort
 
# Запустит Эксель с заполненной данными ячейкой
"Hello world" |Export-Excel
# Data будет заголовком уже с фильтром, данные - со второй строки
[pscustomobject]@{Data="Hello world"} |Export-Excel
# Выгрузятся ВСЕ свойства процессов
Get-Process |Export-Excel .\demo.xlsx
# Export-Excel всегда выгружает все доступные свойства, поэтому перед экспортом их надо фильтровать
# -show - сразу открыть созданный файл, -ClearSheet - очистить лист (по умолчанию данные добавляются)
Get-Process |select company,pm,handles |Export-Excel .\demo.xlsx -show -ClearSheet
# Помимо таблички, сделать сводную таблицу и диаграмму
$ps = Get-Process |select company,pm,handles
$ps |Export-Excel .\demo.xlsx -show -IncludePivotTable -IncludePivotChart -PivotRows company -PivotData @{handles='sum'}
# Выбор вида диаграммы (-ChartType)
$ps |Export-Excel .\demo.xlsx -show -IncludePivotTable -IncludePivotChart -PivotRows company -PivotData @{handles='sum'} -ChartType PieExploded3D
# Убрать расшифровку (легенду), показать проценты и категории
$ps |Export-Excel .\demo.xlsx -show -IncludePivotTable -IncludePivotChart -PivotRows company -PivotData @{handles='sum'} -ChartType PieExploded3D -NoLegend -ShowCategory -ShowPercent
# Задать имя таблице, автовыравнивание по ширине
$ps |Export-Excel .\demo.xlsx -show -TableName Processes -AutoSize
# Автоприсвоение имён диапазону значений столбцов
$ps |Export-Excel .\demo.xlsx -show -AutoSize -AutoNameRange
# Построение диаграммы на основании автодиапазонов
$ChartDefinition = New-ExcelChart -XRange company -YRange handles
$ps |Export-Excel .\demo.xlsx -show -AutoNameRange -ExcelChartDefinition $ChartDefinition
# Задать больше параметров для диаграмм, сделать их две
$barChart = New-ExcelChart -XRange company -YRange handles -Height 250
$pieChart = New-ExcelChart -ChartType PieExploded3D -Row 15 -Height 250 -XRange company -YRange pm -NoLegend -ShowCategory -ShowPercent
$ps |Export-Excel .\demo.xlsx -show -AutoNameRange -ExcelChartDefinition $barChart, $pieChart
# Задать параметры Export-Excel предварительно, диаграмма нарисуется после 9-го столбца
$chart = New-ExcelChart -XRange company -YRange handles -Height 600 -Width 500 -Column 9
$excelparams = @{show=$true; autosize=$true; autonamerange=$true; tablename="Sales"}
$ps |Export-Excel @excelparams .\demo.xlsx -ExcelChartDefinition $chart
# Подсветка ячеек по условию (New-ConditionalText условие, цвет текста, цвет фона)
$data = Get-Service |select Status,Name,DisplayName,StartType
$text1 = New-ConditionalText stop
$text2 = New-ConditionalText runn Blue Cyan
$data |Export-Excel .\demo.xlsx -Show -AutoSize -ConditionalText $text1, $text2
# Значки в ячейках столбца С
$data = (Get-Process).where{$_.company} |select Company,Name,PM,Handles,*mem*
$cfmt = New-ConditionalFormattingIconSet -Range "C:C" -ConditionalFormat ThreeIconSet -IconType Arrows
$data |Export-Excel .\demo.xlsx -Show -AutoSize -ConditionalFormat $cfmt
# Импорт таблицы из HTML (в данном случае - Профессорско-преподавательский состав академии Гнесиных)
$url = 'https://gnesin-academy.ru/wp-content/documents/documents/main/pps_actual_short_spec_1.html'
Import-Html $url -FirstDataRow 3 -Header '№ п/п','ФИО','Должность','Ученая степень или звание','Статус','Уровень образования, специальность, направление, квалификация','Стаж'
# Если входящие данные несложные, можно делать диаграммы сразу.
# Модуль анализирует тип данных и предполагает, как нужно строить диаграмму
$data |BarChart -Title 'A bar chart'
$data |PieChart -Title 'A pie chart'
$data |LineChart -Title 'A line chart'
$data |ColumnChart -Title 'A column chart'
# Диаграмма-график, заданы значения оси Y (X будет нумероваться сам с 0)
$plt = New-Plot
$null = $plt.plot((1,2,3,4))
$plt.show()
# Теперь нумеруются и X, и Y
$plt = New-Plot
$null = $plt.plot((1,2,3,4),(1,4,9,16))
$plt.show()
# Мат. фильтр, ещё более красивый график (реально запустить не получилось)
filter pow ($n){[math]::Pow($_.$n)}
$t = Get-Range 0 5 .2
$t2 = $t |pow 2
$t3 = $t |pow 3
$plt = New-Plot
$null = $plt.plot($t,$t, $t,$t2, $t,$t3)
$null = $plt.SetChartSize(500,300)
$plt.show()

Также см. папку Examples модуля.
Doug Finke on Using the ImportExcel PowerShell Module

# Добавление строки в файл Excel с порядковым номером
$order = (read-host "Заказ").Trim()
$name = (read-host "ФИО").Trim()
 
$path = "C:\temp\orders.xlsx"
$xlsx = (import-excel "$path") |? 'Заказ' -match '\d'
$c = $xlsx[-1].'Заказ' + 1
$obj = [PSCustomObject]@{
'Заказ' = $c
Тема = $order
Фамилия = $name
}
$xlsx += $obj
$xlsx |Export-Excel -Path $path -WorksheetName 'Лист1' -AutoSize -BoldTopRow
 
<# По идее, надо добавлять строки, типа
$excel = Open-ExcelPackage $path
$sheet1 = $excel.Workbook.Worksheets["Лист1"]
$newRowNum = $sheet1.Dimension.Rows + 1
Set-Row -ExcelPackage $excel -WorksheetName $sheet1 -Row $newRowNum -StartColumn 1 -Value "123"
Set-Row -ExcelPackage $excel -WorksheetName $sheet1 -Row $newRowNum -StartColumn 2 -Value "456"
Set-Row -ExcelPackage $excel -WorksheetName $sheet1 -Row $newRowNum -StartColumn 3 -Value "789"
Export-Excel -ExcelPackage $excel
#>

Outlook

$Outlook = New-Object -ComObject Outlook.Application
$Namespace = $Outlook.getNamespace("MAPI")
 
$all_psts = $Namespace.Stores | Where-Object {($_.ExchangeStoreType -eq '3') -and ($_.FilePath -like '*.pst') -and ($_.IsDataFileStore -eq $true)}
 
ForEach ($pst in $all_psts){
    $Outlook.Session.RemoveStore($pst.GetRootFolder())
}

How to disconnect PST file from Outlook using Powershell?

Add-type -assembly "Microsoft.Office.Interop.Outlook" | out-null
$outlook = new-object -comobject outlook.application
$namespace = $outlook.GetNameSpace("MAPI")
dir “c:mypath*.pst” | % { $namespace.AddStore($_.FullName) }

Using PowerShell to attach PST files to Outlook

PST Collection tool

Outlook не подключается к серверу из-за старого протокола шифрования

Проблема наблюдается:

  1. На Windows 7. Необходимо установить обновление KB3140245 и затем MicrosoftEasyFix51044, который включает TLS 1.2 в реестре. Работает даже с Outlook 2010.
  2. На Windows 8. Надо править реестр и убедиться, что установлен .NET 4.6.2 (это максимальная версия для Win8).
taskkill /F /IM OUTLOOK.EXE /T
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp" /v DefaultSecureProtocols /t REG_DWORD /d 0x00000A00 /f
reg add "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp" /v DefaultSecureProtocols /t REG_DWORD /d 0x00000A00 /f

rem В документации почему-то 0xA80.
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v SecureProtocols /t REG_DWORD /d 0xA00 /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings" /v SecureProtocols /t REG_DWORD /d 0xA00 /f
 
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" /v DisabledByDefault /t REG_DWORD /d 0 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" /v DisabledByDefault /t REG_DWORD /d 0 /f

https://bidhankhatri.com.np/windows/windows7-enable-tls12/
https://support.microsoft.com/en-us/topic/update-to-enable-tls-1-1-and-tls-1-2-as-default-secure-protocols-in-winhttp-in-windows-c4bd73d2-31d7-761e-0178-11268bb10392
https://www.ryadel.com/en/enable-tls-1-1-1-2-windows-7-8-os-regedit-patch-download/
https://docs.microsoft.com/ru-ru/mem/configmgr/core/plan-design/security/enable-tls-1-2-client

При запуске Outlook постоянно спрашивает логин и пароль

Файл → Параметры → Центр управления безопасностью → Параметры центра управления безопасностью → Параметры конфиденциальности → снять галку с пункта Разрешить подключение Office к веб-службам, чтобы предоставлять доступ к функциям, соответствующим вашим предпочтениям
File → Options → Trust Center → Trust Center Settings → Privacy Options → Let Office connect to online services from Microsoft to provide functionality that's relevant to your usage

GPO: Конфигурация пользователя → Административные шаблоны → Microsoft Office 2016 → Сервис | Общие | Параметры | Параметры служб → Содержимое в сети → Параметры контента в интернете → Не разрешать Office подключаться к интернету

https://docs.microsoft.com/en-us/outlook/troubleshoot/authentication/password-prompt-at-every-start-or-cannot-create-profile

Outlook не открывает ссылки DFS

Внести нужный ресурс в доверенные сайты, например, через GPO:
Конфигурация пользователя → Политики → Административные шаблоны → Компоненты Windows → Internet Explorer → Панель управления браузером → Вкладка «Безопасность» → Список назначений зоны для веб-сайтов
file:///\\example.com 2

The syntax for adding a URL for files on FQDN or IP address paths to a GPO is different than manually adding a file URL to Internet Options | Security | Trusted Sites. You need to add three forward slashes /// in front of the \\<ipaddress>.

For example:

  • Manually adding \\10.123.452.37 enters file://10.123.452.37 in Trusted Sites list, this allows the file link to not be blocked.
  • But for GPO you need to use the following syntax: file:///\\10.123.452.37. This also enters file://10.123.452.37 in Trusted Sites list and allows the file link to not be blocked.

Снять галку "Для всех сайтов этой зоны требуется проверка серверов (https:)"
Конфигурация пользователя → Политики → Настройка → Конфигурация Windows → Реестр

Reg Key: HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2
Value Name: Flags
Value Type: REG_DWORD
Value Data (in decimal): 67 (to uncheck) or 71 (to check)

Убрать предупреждение в Outlook про опасную ссылку:

HKCU\software\policies\microsoft\office\16.0\common\security
DWORD: DisableHyperlinkWarning
Value: 1

Outlook blocks opening FQDN and IP address hyperlinks after installing protections for Microsoft Outlook Security Feature Bypass Vulnerability released July 11, 2023
Use Group Policy + Registry to Toggle IE Trusted Sites HTTPS Check Box

Word

Поиск в таблицах

Необходим установленный Word.

$filename = "D:\temp\Табличный документ.doc"
$search = 'слово'
 
$wd = New-Object -ComObject Word.Application
$doc = ($wd).Documents.Open($filename)
$report = @()
 
$cTable = 1
foreach ($table in $doc.Tables) {
    $cRows = $table.Rows.Count
    $cColumns = $table.Columns.Count
 
    $cColumn = 1
    do {
    $cRow = 1
        do {
            if ($table.Cell($cRow, $cColumn).range.text -match "$search") {
                $obj = [PSCustomObject]@{
                    '№ таблицы' = $cTable
                    '№ cтолбца' = $cColumn
                    '№ строки' = $cRow
                    Строка = $table.Cell($cRow, $cColumn).range.text
                }
                $report += $obj
            }
            $cRow++
        } until ($cRow -gt $cRows)
    $cColumn++
    } until ($cColumn -gt $cColumns)
$cTable++
}
$wd.Quit()
 
$report

Поиск и замена

Необходим установленный Word, а также исходный файл, где нужно вставить уникальные значения для замены.

function Replace-Word {
param($FindText, $ReplaceWith)
    $Word.Selection.Find.Execute($FindText,$MatchCase,$MatchWholeWord, ` 
    $MatchWildcards,$MatchSoundsLike,$MatchAllWordForms,$Forward,` 
    $Wrap,$Format,$ReplaceWith,$ReplaceAll) 
}
 
# -AsText - чтобы при импорте значения не интерпретировались (дроби не становились десятичными и т. п.)
$reestr = import-excel "C:\temp\from\2023-03-06 Реестр собственников.xlsx" -AsText * |? ФИО -match '\w'
 
$reestr |% {
    $_.Доля = $_.Доля -replace '\s'
    if ($_.Доля -eq 2) {$_.Доля = 1} # ImportExcel почему-то 1 читает из таблицы как 2
    $_.ФИО = ($_.ФИО -replace '\s+',' ').trim()
}
 
#$str = $reestr |? фио -eq 'Петров Дмитрий Вадимович, Петрова Ольга Николаевна'
#$str = $reestr |? фио -eq 'Сидорова Анна Михайловна'
 
foreach ($str in $reestr) {
$path = "D:\temp\to\$($str.'№ кв') $($str.ФИО).docx"
cp "C:\temp\from\blanc_source.docx" $path
 
$Word = new-object -ComObject Word.Application
$Word.Visible = $False
$doc = $Word.Documents.Open($path,$true)
 
$wdFindContinue = 1
$MatchCase = $False 
$MatchWholeWord = $true
$MatchWildcards = $False 
$MatchSoundsLike = $False 
$MatchAllWordForms = $False 
$Forward = $True 
$Wrap = $wdFindContinue 
$Format = $False 
$wdReplaceNone = 0 
$wdFindContinue = 1 
$ReplaceAll = 2
 
Replace-Word 'r-fio' $str.ФИО
Replace-Word 'r-flat' $str.'№ кв'
Replace-Word 'r-egrn' $str.'Номер записи в ЕГРН'
Replace-Word 'r-m' $str.Площадь
Replace-Word 'r-part' $str.Доля
 
$doc.Save()
$doc.SaveAs([ref]$($path -replace 'docx$','pdf'), [ref]17) # also make PDF
$doc.Close() 
 
$Word.Application.Quit()
 
}
 
# Сжать полученные файлы в архив
Compress-Archive -Path "D:\temp\to\*.docx" -DestinationPath "D:\temp\to\Бланки ОСС Word.zip" #-WhatIf
Compress-Archive -Path "D:\temp\to\*.pdf" -DestinationPath "D:\temp\to\Бланки ОСС PDF.zip" #-WhatIf

Hey, Scripting Guy! How Can I Use Windows PowerShell to Look for and Replace a Word in a Microsoft Word Document?
Basic Powershell - batch convert Word Docx to PDF

Модуль PSWriteOffice для Powershell

Модуль PSWriteOffice для Powershell создаёт документы без установленного Office.

# Создание документа
$docFile = "C:\temp\doc.docx"
rm $docFile
$doc = New-OfficeWord $docFile
 
# Параграф
$p1 = New-OfficeWordText -Document $doc -Alignment Center -Text "Первая строка параграфа" -ReturnObject
$p1 = $p1.AddBreak() # Перенос строки в том же параграфе
New-OfficeWordText -Document $doc -Paragraph $p1 -Text "`t`tПодчёркнуто, а вокруг TABs`t`t", " Не подчёркнуто" -Underline 'Double', $null

Замена текста в документе

$from = "Было"
$to = "Будет"
 
$doc = Get-OfficeWord "C:\temp\doc.docx"
 
$doc.Paragraphs |% {
    if ($_.text -match "$from") {
        $_.text = $_.text -replace "$from","$to"
    }
}
 
Save-OfficeWord -Document $doc -FilePath "C:\temp\docChanged.docx" #-Show

Альтернативные офисные приложения

Abiword is a free word processing program similar to Microsoft® Word. It is suitable for a wide variety of word processing tasks.
Gnumeric is an open-source spreadsheet program.
Libreoffice - офисный пакет.
Onlyoffice - офисный пакет.
pandoc - не совсем офисное приложение, но мощный конвертер между текстовыми форматами, включая pdf и docx.