===== Вариант PowerShell скрипта для создания HTML отчёта по данным Web API SquidARM =====
{{:squid:pasted:20240501-160005.png }} Здесь рассмотрен пример **PowerShell** скрипта, использующего функционал **Web API** в составе **SquidARM** для построения отчёта об использовании Интернет-ресурсов пользователями прокси сервера **Squid**.
Данный вариант скрипта является черновым и может быть изменён со временем.
$startDate = "01.03.2024"
$endDate = "15.03.2024"
$URLUsers = @("icanfly01")
#
$URLBase = "https://squidarm.holding.com/api/user/"
[int]$LimitLines = 100
$htmlLogo = $PSScriptRoot + "\MyCompany-Logo.png"
$htmlOutDir = "C:\Temp\"
[bool]$echoScript = $false
#
$printsDate = $([datetime]::parseexact($startDate,"dd.MM.yyyy",$null)).GetDateTimeFormats()[5]
$printeDate = $([datetime]::parseexact($endDate,"dd.MM.yyyy",$null)).GetDateTimeFormats()[5]
#
# Адаптация Logo для HTML-отчётов
#
$ImageBits = [Convert]::ToBase64String((Get-Content $htmlLogo -Encoding Byte))
$ImageFile = Get-Item $htmlLogo
$ImageType = $ImageFile.Extension.Substring(1) #strip off the leading
$ImageTag = ""
#
# Функция получения из AD полного имени пользователя
#
Function GetADUserName() {
Param ($useracc)
Try {
(Get-ADUser $useracc).Name
} Catch {}
}
#
#
# Функция преобразования байт в читаемый вид
#
Function BytesToHRF() {
Param ([int64]$size)
If ($size -gt 1TB) {[string]::Format("{0:0.00} TB", $size / 1TB)}
ElseIf ($size -gt 1GB) {[string]::Format("{0:0.00} GB", $size / 1GB)}
ElseIf ($size -gt 1MB) {[string]::Format("{0:0.00} MB", $size / 1MB)}
ElseIf ($size -gt 1KB) {[string]::Format("{0:0.00} kB", $size / 1KB)}
ElseIf ($size -gt 0) {[string]::Format("{0:0.00} B", $size)}
Else { " - " }
}
#
# Основной блок скрипта в цикле по каждому пользователю
#
ForEach ($URLUser in $URLUsers) {
#
$scriptStart = Get-Date
$UserName = GetADUserName $URLUser
$pintUser = If ($UserName){$UserName + " (" + $URLUser + ")"} Else { $URLUser }
#
# Получение данных через веб-API
#
$Result = @()
$sDate = [datetime]::parseexact($startDate, 'dd.MM.yyyy', $null).AddDays(-1)
$eDate = [datetime]::parseexact($endDate, 'dd.MM.yyyy', $null)
While ($sDate -lt $eDate) {
$sDate = $sDate.AddDays(1)
$URL = $URLBase + $URLUser + "/" + $sDate.ToString("yyyy") + "/" + $sDate.ToString("MM") + "/" + $sDate.ToString("dd") + ".json"
Try{
$JArrs = @()
$JSON = Invoke-WebRequest $URL -UseDefaultCredentials | ConvertFrom-Json
$JArrs = $JSON.data
ForEach ($Arr in $JArrs) {
#
# Пример одного извлекаемого массива: {arc.msn.com, 0, 4638, 1, 0}
#
$Item = New-Object System.Object
$Item | Add-Member -MemberType NoteProperty -Name "Domain" -Value $Arr[0]
$Item | Add-Member -MemberType NoteProperty -Name "BytesFromCache" -Value $Arr[1]
$Item | Add-Member -MemberType NoteProperty -Name "BytesDownloaded" -Value $Arr[2]
$Item | Add-Member -MemberType NoteProperty -Name "Requests" -Value $Arr[3]
$Item | Add-Member -MemberType NoteProperty -Name "Refuses" -Value $Arr[4]
$Result += $Item
}
}
Catch {}
}
#
# Предварительная группировка результата в разрезе доменов
#
$gResult = @()
$gResult = $Result | Group-Object -Property Domain
$fResult = @()
$fResult += ForEach($gItem in $gResult){
$gItem.Group | Select -Unique Domain,
@{Name = 'gBytesFromCache';Expression = {(($gItem.Group) | Measure -Property BytesFromCache -sum).Sum}},
@{Name = 'gBytesDownloaded';Expression = {(($gItem.Group) | Measure -Property BytesDownloaded -sum).Sum}},
@{Name = 'gRequests';Expression = {(($gItem.Group) | Measure -Property Requests -sum).Sum}},
@{Name = 'gRefuses';Expression = {(($gItem.Group) | Measure -Property Refuses -sum).Sum}}
}
#
# Подсчёт общих итоговых значений
#
$totalBytesFromCache = BytesToHRF $(($fResult | Measure-Object 'gBytesFromCache' -Sum).Sum)
$totalBytesDownloaded = BytesToHRF $(($fResult | Measure-Object 'gBytesDownloaded' -Sum).Sum)
#$totalRequests = ($fResult | Measure-Object 'gRequests' -Sum).Sum
#$totalRefuses = ($fResult | Measure-Object 'gRefuses' -Sum).Sum
#
# Вывод результата на консоль
#
If ($echoScript) {
Write-Host "Отчёт о посещаемости Интернет-ресурсов пользователя : $pintUser"
Write-Host "В отчёте выведены данные за период с $printsDate по $printeDate"
Write-Host "Сформировано $('{0:dd.MM.yyyy в HH:mm}' -f (get-date))"
$fResult | Sort-Object 'gBytesDownloaded' -Descending | Select-Object -First $LimitLines | Format-Table -Autosize `
@{Name="Имя домена";Expression = { $_.Domain }; Alignment="Center"},
@{Name="Загружено из Интернет";Expression = { BytesToHRF $_.gBytesDownloaded };Alignment="Center"},
@{Name="Загружено из кеша";Expression = { BytesToHRF $_.gBytesFromCache }; Alignment="Center"},
@{Name="Запросов";Expression = { $_.gRequests };Alignment="Right"},
@{Name="Ошибок";Expression = { $_.gRefuses };Alignment="Right"}
}
#
# Генерация HTML отчёта
#
$fragments = @()
#
# Шапка отчёта
#
$fragments+= $ImageTag
$fragments+= "Отчёт об использовании Интернет-ресурсов
"
$TableTop = @{"User" = $pintUser; "Period" = "$printsDate - $printeDate"}
$fragments+= $TableTop |
Select @{Name = "Пользователь";Expression = {$_.User}},
@{Name = "Период отчёта";Expression = {$_.Period}},
@{Name = "Всего загружено из Интернет";Expression = {$totalBytesDownloaded}},
@{Name = "Всего загружено из кеша прокси";Expression = {$totalBytesFromCache}} |
ConvertTo-Html -Fragment -As List
#
$fragments+= "
"
#
# Вёрстка табличного контента HTML
#
[xml]$html = $fResult | Sort-Object 'gBytesDownloaded' -Descending |
Select-Object -First $LimitLines @{Name="Имя домена"; Expression={$_.Domain}},
@{Name="Загружено из Интернет";Expression = { BytesToHRF $_.gBytesDownloaded}},
@{Name="Загружено из кеша";Expression = { BytesToHRF $_.gBytesFromCache}},
@{Name="Запросов";Expression = {$_.gRequests}},
@{Name="Ошибок";Expression = {$_.gRefuses}} | ConvertTo-Html -Fragment
#
# Дополнительное HTML форматирование основной таблицы
#
For ($i=1; $i -le $html.table.tr.count-1; $i++) {
[int64]$refusesCount = $html.table.tr[$i].td[4]
$tclass = $html.CreateAttribute("class")
$tclass.value = "maintable"
$html.table.tr[$i].attributes.append($tclass) | Out-null
If ($refusesCount -gt 0) {
$class = $html.CreateAttribute("class")
$class.value = "alert"
$html.table.tr[$i].attributes.append($class) | Out-null
}
}
#
$fragments+= $html.InnerXml
#
# Вёрстка нижней части отчёта
#
$fragments+= "
"
#
# Подсчёт основного времени извлечения данных и первичной HTML верстки
#
$scriptEnd = Get-Date
$tt = new-timespan -seconds $(($scriptEnd - $scriptStart).TotalSeconds)
If (($tt.TotalSeconds) -lt 60) {$scriptTime = '{0:0} сек.' -f $tt.seconds}
ElseIf (($tt.TotalSeconds) -gt 3599) {$scriptTime = '{0:0} ч. {1:0} мин. {2:0} сек.' -f $tt.Hours,$tt.Minutes,$tt.Seconds}
Else {$scriptTime = '{1:0} мин. {2:0} сек.' -f $tt.Hours,$tt.Minutes,$tt.Seconds}
#
$TableBot = @{"BuildTime"="$('{0:dd.MM.yyyy в HH:mm}' -f (get-date))";"sTime" = $scriptTime}
$fragments+= $TableBot |
Select @{Name="Дата и время формирования отчёта";Expression = {$_.BuildTime}},
@{Name="Время построения отчёта";Expression = {$_.sTime}} |
ConvertTo-Html -Fragment -As List
#
$fragments+= ""
#
# Формирование имени файла HTML-отчёта
#
$htmlPath = $htmlOutDir + "Интернет отчёт " + $UserName + " за " + $printsDate + " - " + $printeDate + ".htm"
#
# Выгрузка HTML-отчёта
#
$convertParams = @{
head = @"
Отчёт об использовании Интернет-ресурсов пользователя $pintUser
"@
body = $fragments
}
ConvertTo-Html @convertParams | Out-File $htmlPath
#
# Открываем браузер
#
#$IE = New-Object -COM internetexplorer.application
#$IE.navigate2($htmlPath)
#$IE.visible = $true
}
----
Проверено на следующих конфигурациях:
^ Версия ОС ^ Версия PowerShell ^ Версия SquidARM ^
| Windows 10 22H2 | 5.1.19041.4046 | 0.04-1 |
----
{{:user:blogroot.png?50&nolink |}} Автор первичной редакции:\\ [[user:blogroot|Алексей Максимов]] \\ Время публикации: 01.05.2024 15:34
{{tag>PowerShell Squid SquidARM}}
~~DISCUSSION~~