Глава 8. Отчёты
Содержание
Отчёты это важная сторона повседневного системного администрирования. Порой мы представляем отчёты своим управляющим, а в прочих ситуациях мы пользуемся ими и улучшаем свою собственную работу.
Отчёты могут предоставляться в виде CSV, HTML, Excel и прочего. Наиболее распространённой формой отчёта выступает отчёт CSV по причине своей универсальности и способности преобразования в иные виды, например в Excel из самого приложения.
Export-CSV это встроенный командлет PowerShell, которым можно пользоваться для 
   экспорта необходимых сведений в файл CSV. Вы можете просто выбрать 
   конвейер и затем экспортировать, как это показано в приводимом далее коде, который отображает экспорт 
   определённых атрибутов почтовых ящиков пользователя из Exchange Server (что следует исполнять в оболочке Exchange):
Get-Mailbox -ResultSize unlimited | Select Name,identity, WindowsEmailAddress,Database,ProhibitSendQuota,ProhibitSendReceiveQuota,IssueWarningQuota | export-csv c:\mailboxes.csv -notypeinfo
		
   Имеется множество сложных обстоятельств, при которых вам требуется записывать код сценария в формате необходимых данных правильным образом. Листинг 8-1 и Рисунок 8-1 отображают ту, когда у вас имеется перечень пользователей в неком текстовом файле и вы желаете экспортировать их атрибуты Active Directory и некоторые из атрибутов Exchange в файл CSV. В таком случае, не возможны get, select и export. Данный код может применяться во всех тех случаях, когда вы хотите экспортировать необходимые данные в соответствующую форму CSV, но простая операция не возможна.
Вы желаете воспользоваться атрибутами Name, 
   identity, WindowsEmailAddress, 
   Database, ProhibitSendQuota, 
   ProhibitSendReceiveQuota и IssueWarningQuota, а 
   также атрибутами employeeid, l, 
   C из Active Directory.
	   ![]()  | Замечание | 
|---|---|
| 
	    Требуются оба модуля, и Exchange, и AD. Вам необходимо соединение с ними. Если они не загружены, этот сценарий завершится неудачей.  | 
Для их загрузки воспользуйтесь познаниями из предыдущих глав.
Загрузите оболочку Exchange площадки при помощи  vsadmin launchexonprem:
LaunchEXOnprem -ComputerName ExchangeServer
		
   Для Active Directory вы можете применить
Import-Module Activedirectory
		
   Листинг 8-1. Экспорт в CSV при выборке из множества источников
$collection=@() #массив для сборки данных отчёта
$data = get-content .\users.txt #read samaccountname from text file
$data | foreach-object{
  $coll = "" | Select Name,identity,WindowsEmailAddress,Database,ProhibitSendQuota,ProhibitSendReceiveQuota,IssueWarningQuota,employeeid, l,C  #необходимые в отчёте значения
  $getmbx = get-mailbox -identity $_
  $getaduser = get-aduser -identity $_ -properties employeeid, l,C
  $coll.Name = $getmbx.Name
  $coll.identity = $getmbx.identity
  $coll.WindowsEmailAddress = $getmbx.WindowsEmailAddress
  $coll.Database= $getmbx.Database
  $coll.ProhibitSendQuota = $getmbx.ProhibitSendQuota
  $coll.ProhibitSendReceiveQuota = $getmbx.ProhibitSendReceiveQuota
  $coll.IssueWarningQuota = $getmbx.IssueWarningQuota
  $coll.employeeid = $getaduser.employeeid #note difference here
  $coll.l = $getaduser.l
  $coll.c = $getaduser.c
  $collection+=$coll #add the collected values to the collecttion array
}
#теперь выполняем экспорт в файл CSV
$collection | Export-Csv .\report.csv -NoTypeInformation
 	   
   Другой важной стороной отчёта CSV выступает экспорт атрибутов со множеством значений. Вот некий образец выделения получателя (который является атрибутом со множеством значений) в журналах отслеживания Exchange:
@{Name="Recipents";Expression={$_.recipients}}
		
   Относительно образца выделения значений получателя из журнала транспорта Exchange обратитесь к Листингу 8-2.
Листинг 8-2. Пример кода, отображающего как экспортировать атрибуты со множеством значений
Get-transportserver | Get-MessageTrackingLog -Start"03/09/2015 00:00:00 AM" -End"03/09/2015 11:59:59 PM" -sender "vikas@lab.com" -resultsize unlimited | `
select-object Timestamp,clientip,ClientHostname,ServerIp,ServerHostname,sender,EventId,MessageSubject, TotalBytes , SourceContext,ConnectorId,Source, `
InternalMessageId , MessageId ,@{Name="Recipents";Expression={$_.recipients}} | `
export-csv c:\track.csv
 	   
   Хотя отчёты CSV прекрасно подходят для большинства целей, имеются случаи, при которых вы пожелаете поделиться имеющимися сведениями со своими менеджерами, а потому преобразование своего файл CSV Excel это очень нужный сценарий. Для выполнения одного и того же я поделюсь двумя методами.
Первый метод имеется в нашем модуле vsadmin, которым я поделился в главе о модулях.
	   ![]()  | Замечание | 
|---|---|
| 
	    Для применения данного метода в вашей машине должен иметься установленным Excel.  | 
Листинг 8-3
   отображает код нашей функции Save-CSV2Excel в случае, когда вы не обладаете установленным 
   модулем vsadmin или не желаете его устанавливать.
Листинг 8-3. Шпаргалка кода для функции Save-CSV2Excel
Function Save-CSV2Excel
{
  [CmdletBinding()]
  Param(
    [Parameter(Mandatory = $true,Position = 1)]
    [ValidateScript({
          if(-Not ($_ | Test-Path) ){throw "File or folder does not exist"}
          if(-Not ($_ | Test-Path -PathType Leaf) ){throw "The Path argument must be a file. Folder paths are not allowed."}
          if($_ -notmatch "(\.csv)"){throw "The file specified in the path argument must be either of type csv"}
          return $true
    })]
    [System.IO.FileInfo]$CSVPath,
    [Parameter(Mandatory = $true)]
    [ValidateScript({
          if($_ -notmatch "(\.xlsx)"){throw "The file specified in the path argument must be either of type xlsx"}
          return $true
    })]
    [System.IO.FileInfo]$Exceloutputpath
  )
  ####### Заимствованная у Lloyd Watkinson из галереи сценариев функция##
  Function Convert-NumberToA1
  {
    Param([parameter(Mandatory = $true)]
    [int]$number)
    $a1Value = $null
    While ($number -gt 0)
    {
      $multiplier = [int][system.math]::Floor(($number / 26))
      $charNumber = $number - ($multiplier * 26)
      If ($charNumber -eq 0) { $multiplier-- ; $charNumber = 26 }
      $a1Value = [char]($charNumber + 64) + $a1Value
      $number = $multiplier
    }
    Return $a1Value
  }
  ##################Начинаем преобразовывать excel#######################
  $importcsv = Import-Csv $CSVPath
  $countcolumns = ($importcsv |
    Get-Member |
  Where-Object{$_.membertype -eq "Noteproperty"}).count
  #################вызов объекта com Excel ##############
  $xl = New-Object -comobject excel.application
  $xl.visible = $false
  $Workbook = $xl.workbooks.open($CSVPath)
  $Workbook.SaveAs($Exceloutputpath, 51)
  $Workbook.Saved = $true
  $xl.Quit()
  #############Теперь форматируем свой Excel###################
  timeout.exe 10 #wait for 10 seconds before saving
  $xl = New-Object -comobject excel.application
  $xl.visible = $false
  $Workbook = $xl.workbooks.open($Exceloutputpath)
  $worksheet1 = $Workbook.worksheets.Item(1)
  for ($c = 1; $c -le $countcolumns; $c++) {$worksheet1.Cells.Item(1, $c).Interior.ColorIndex = 39}
  $colvalue = (Convert-NumberToA1 $countcolumns) + "1"
  $headerRange = $worksheet1.Range("a1", $colvalue)
  $null = $headerRange.AutoFilter()
  $null = $headerRange.entirecolumn.AutoFit()
  $worksheet1.rows.item(1).Font.Bold = $true
  $Workbook.Save()
  $Workbook.Close()
  $xl.Quit()
  $Null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl)
  #######################################################################
}#Write-CSV2Excel
 	   
   Давайте воспользуемся отчётом CSV из Листинга 8-1 и 
   преобразуем его в Excel при помощи Save-CSV2Excel. Смотрите на 
   Рисунок 8-2.
Save-CSV2Excel -CSVPath c:\temp\report.csv -Exceloutputpath c:\temp\report.xlsx
		
	Имеется модуль с названием ImportExcel. Это один из наиболее популярных модулей из 
   Галереи PowerShell. Вы можете воспользоваться этим модулем непосредственно преобразовывая переменные в Excel. 
   Получите его из http://www.powershellgallery.com/packages/ImportExcel. Установите этот модуль в своей машине и затем 
   импортируйте его для применения:
Install-Module -Name ImportExcel
		
   Давайте воспользуемся тем же самым отчётом, который мы применяли в этом новом модуле для его преобразования в Excel. Основное преимущество применения данного модуля состоит в том, что он не требует установленного Excel в вашей машине. Обращаем ваше внимание на Рисунок 8-3.
Import-Module -Name ImportExcel
$data = Import-Csv .\report.csv
$data | Export-Excel -Path c:\temp\report.xlsx
		
	Внутри данной функции существует великое множество прочих параметров, как форматировать Excel, которые я оставляю вам для изучения!
Было бы замечательно если бы вы могли создавать информационные панели HTML при помощи PowerShell ☺, которые были бы способны отображать сигналы светофора. Например, когда служба не работает, она отображается красным цветом. В противном случае она показана зелёным цветом. Обратитесь к Рисунку 8-4.
Листинг 8-4 представляет шаблон для кодирования HTML, которым вы можете пользоваться внутри сценариев и выполнять операции подсветки светофора на основе условий.
Листинг 8-4. Шаблон для кодирования HTML
$report = $reportpath
Clear-Content $report
#################Содержимое отчётаHTml############################
Add-Content $report "<html>"
Add-Content $report "<head>"
Add-Content $report "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>"
Add-Content $report '<title>Exchange Status Report</title>'
add-content $report '<STYLE TYPE="text/css">'
add-content $report  "<!--"
add-content $report  "td {"
add-content $report  "font-family: Tahoma;"
add-content $report  "font-size: 11px;"
add-content $report  "border-top: 1px solid #999999;"
add-content $report  "border-right: 1px solid #999999;"
add-content $report  "border-bottom: 1px solid #999999;"
add-content $report  "border-left: 1px solid #999999;"
add-content $report  "padding-top: 0px;"
add-content $report  "padding-right: 0px;"
add-content $report  "padding-bottom: 0px;"
add-content $report  "padding-left: 0px;"
add-content $report  "}"
add-content $report  "body {"
add-content $report  "margin-left: 5px;"
add-content $report  "margin-top: 5px;"
add-content $report  "margin-right: 0px;"
add-content $report  "margin-bottom: 10px;"
add-content $report  ""
add-content $report  "table {"
add-content $report  "border: thin solid #000000;"
add-content $report  "}"
add-content $report  "-->"
add-content $report  "</style>"
Add-Content $report "</head>"
Add-Content $report "<body>"
add-content $report  "<table width='100%'>"
add-content $report  "<tr bgcolor='Lavender'>"
add-content $report  "<td colspan='7' height='25' align='center'>"
add-content $report  "<font face='tahoma' color='#003399' size='4'><strong>DAG Active Manager</strong></font>"
add-content $report  "</td>"
add-content $report  "</tr>"
add-content $report  "</table>"
add-content $report  "<table width='100%'>"
Add-Content $report  "<tr bgcolor='IndianRed'>"
Add-Content $report  "<td width='10%' align='center'><B>Identity</B></td>"
Add-Content $report  "<td width='5%' align='center'><B>PrimaryActiveManager</B></td>"
Add-Content $report  "<td width='20%' align='center'><B>OperationalMachines</B></td>"
Add-Content $report "</tr>"
##############################Шаблон отчёта##################################
add-content $report  "<tr bgcolor='Lavender'>"
add-content $report  "<td colspan='7' height='25' align='center'>"
add-content $report  "<font face='tahoma' color='#003399' size='4'><strong>DAG Database Backup Status</strong></font>"
add-content $report  "</td>"
add-content $report  "</tr>"
add-content $report  "</tr>"
add-content $report  "</table>"
add-content $report  "<table width='100%'>"
Add-Content $report "<tr bgcolor='IndianRed'>"
Add-Content $report  "<td width='10%' align='center'><B>Database</B></td>"
Add-Content $report  "<td width='5%' align='center'><B>BackupInProgress</B></td>"
Add-Content $report  "<td width='10%' align='center'><B>SnapshotLastFullBackup</B></td>"
Add-Content $report  "<td width='5%' align='center'><B>SnapshotLastCopyBackup</B></td>"
Add-Content $report  "<td width='10%' align='center'><B>LastFullBackup</B></td>"
Add-Content $report  "<td width='5%' align='center'><B>RetainDeletedItemsUntilBackup</B></td>"
$dbst= Get-MailboxDatabase | where{$_.MasterType -like "DatabaseAvailabilityGroup"}
$dbst | foreach{$st=Get-MailboxDatabase $_ -status
  $dbname =  $st.Name
  $dbbkprg = $st.BackupInProgress
  $dbsnpl = $st.SnapshotLastFullBackup
  $dbsnplc= $st.SnapshotLastCopyBackup
  $dblfb = $st.LastFullBackup
  $dbrd = $st.RetainDeletedItemsUntilBackup
    Add-Content $report "<tr>"
    Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$dbname</B></td>"
          Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$dbbkprg</B></td>"
    Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$dbsnpl</B></td>"
          Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$dbsnplc</B></td>"
  if($dblfb -lt $hrs)
  {
    Add-Content $report "<td bgcolor= 'Red' align=center>  <B>$dblfb</B></td>"
  }
  else
  {
      Add-Content $report "<td bgcolor= 'Aquamarine' align=center>  <B>$dblfb</B></td>"
  }
    Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$dbrd</B></td>"
    Add-Content $report "</tr>"
}
##############################################################
Add-content $report  "</table>"
Add-Content $report "</body>"
Add-Content $report "</html>"
 	   
   по приводимым далее ссылкам вы можете увидеть примеры, в которых этот шаблон успешно применялся для служб Exchange Health Check, AD Health Check и Monitor Remote:
Как уже упоминалось, для создания HTML и его применения в сценариях PowerShell, вы можете воспользоваться Интернет редактором HTML.
![[Замечание]](/common/images/admon/note.png)



