[Из песочницы] DLP система своими руками

Переменная $Body — содержит текст, который в дальнейшем будет вставлен в тело письма. В дальнейшем этот текст будет отправлен в письме конечному пользователю.

$Body =

", напоминаем Вам о действии приказа о запрете хранения служебной информации на локальных дисках ПК.
В прикрепленном к письму файле, Вы найдете список документов обнаруженных на Вашем ПК потенциально содержащих служебную информацию. 

Вам необходимо в кратчайшие сроки:

1) проверить указанные документы на предмет наличия служебной информации
2) переместить файлы содержащие служебную информацию на личный сетевой диск.


Начало функции, которой дано производное название Start-AuditFiles:

Function Start-AuditFiles {


Описание скрипта, сопроводительный текст справки. Позволяет использовать помощь, получить информацию о примерах и синтаксисе используя «Get-Help Start-AuditFiles»:

<#
.Synopsis
    Сканирует файлы на удаленной машине, в случае успеха отправляет отчет почтовым сообщением
.Description
    Сканер позволяет обнаружить искомые файлы на удаленной машине через административный ресурс (C$ D$ .. и т.д). 
    После выполнения скрипт: 
    1. Находит объекты комрьютер в опеределенной OU или заданый компьютер через параметр
    2. Проверяет доступность машины
    3. Выполняет поиск всех дисков
    4. Выполняет поиск искомых файлов с фильтрацией, формирует отчет
    5. Отправляет отчет администратору
    6. Получает активного пользователя, определяет его почтовый адрес, отправляет копию отчета
    7. Формирует списки результатов сканирования, опционально копирует результаты на удаленный ресурс
    
.Examples

    Пример 1
    Start-AuditFiles -OU "OU=Test,DC=root,DC=local" -SMTP smtp.server.com -AdminMail administrator@server.com -IncludeFile *.doc,*.docx,*.sys -ExclusionFile *File1*,*File2* -ExclusionFolder *Folder1*,*Folder2* -ReportPath \\server\reports\

    В этом примере осуществляется поиск на компьютерах из OU, файлы все с расширением (*.doc,*.docx,*.sys) кроме файлов (*File1*,*File2*), кроме каталогов (*Folder1*,*Folder2*), отчет дублируется в каталог (\\server\reports\)

    Пример 2
    Start-AuditFiles -RemoteComputer ws-pc-4902,ws-pc-0982 -SMTP smtp.server.com -AdminMail administrator@server.com -Include *.doc,*.docx,*.sys -ExclusionFile *New*,*au* -AdminOnly

    В этом примере осуществляется поиск на компьютерах (ws-pc-4902,ws-pc-098), файлы все с расширением (*.doc,*.docx,*.sys) кроме файлов (*File1*,*File2*), отчет отсылается только администратору
    
.Notes
    Следует использовать только один из ключей OU или RemoteComputer, OU указывает организационную единицу, RemoteComputer указывает один или несколько компьютер в качестве объектов сканирования
.Link
    ...
#>



Описываем переменные, которые в дальнейшем будем использовать в функции:

$OU — путь к Organization Unit в Active Directory
$ExclusionFile –перечень файлов, исключённых из поиска
$ReportPath — путь к каталогу, куда будут дублироваться отчеты
$AdminMail — адрес электронной администратора, от которого отправляются отчеты и куда будет приходить копия, предназначенная администратору
$IncludeFile — расширения файлов или имена файлов, поиск которых осуществляется
$ExclusionFolder — перечень папок, исключенных из поиска
$AdminOnly — параметр отвечающий, будут ли отчеты отправляться только администратору
$SMTP — адрес или имя SMTP сервера
$Throttle — количество параллельных потоков.

[CmdletBinding()]
        Param (
        [String]$OU,
        [String[]]$RemoteComputer,
        [String[]]$ExclusionFile,
        [String]$ReportPath,  
        [String]$AdminMail,       
        [String[]]$IncludeFile,
        [String[]]$ExclusionFolder,
        [Switch]$AdminOnly = $false,      
        [String]$SMTP,
        [String]$Throttle = 5

        )



Выполняется проверка, если использовался ключ «RemoteComputer», в таком случае сканирование пройдет только на определенном (заданном) компьютере, если указан ключ «OU» — в этом случае список будет получен из определённой OU AD, будут выбраны компьютеры с атрибутом HomePage — не равным «pass» (это выполняется, дабы исключить повторный поиск на машинах, на которых уже был проведен поиск).

If (!$RemoteComputer) {$Hosts = (Get-ADComputer -Filter * -SearchBase $OU -Properties * | where { ( $PSItem.HomePage  -notlike  'pass' )}  ).name} else { $Hosts = $RemoteComputer }


Начало выполнения скрипта, подставляется значение Host и число потоков:

invoke-parallel -InputObject $Hosts -throttle $Throttle -ImportVariables  -ScriptBlock {


Проверка доступности компьютера в сети:

if(Test-Connection -ComputerName $_ -BufferSize 16 -quiet -count 2) {


Присваиваются значения переменных, необходимых для выполнения поиска взятые из переменных описанных выше. Запоминается начало выполнения поиска.

                $Object = $_
                $ErrorActionPreference = 'SilentlyContinue'
                $ExclusionFolder2 = $ExclusionFolder -replace ",","|"

        $StartTime = (Get-Date).ToString()
        $Hosts        



Выполнение поиска:

  • получение списка физических дисков (Get-WMIObject Win32_LogicalDisk -filter «DriveType = 3» -ComputerName $Object)
  • формируется UNC путь с проставлением буквы диска (Get-ChildItem ('\\' + $Object + '\' + ($_.DeviceID).remove (1) + '$\*')
  • указывается ключ поиска включенных объектов и исключения (-Include $IncludeFile -Exclude $ExclusionFile -Recurse -Force)
  • исключение для каталогов, убираем из результатов поиска не нужные каталоги (?{$PSItem.FullName -notmatch $ExclusionFolder2}}).FullName)
  • формируется отчет во временном каталоге (Out-File -FilePath $env: TEMP\$Object.txt -Encoding unicode)
(Get-WMIObject Win32_LogicalDisk -filter "DriveType = 3" -ComputerName $Object | %{Get-ChildItem ('\\' + $Object + '\' + ($_.DeviceID).remove(1) + '$\*') -Include $IncludeFile -Exclude $ExclusionFile -Recurse -Force | ?{$PSItem.FullName -notmatch $ExclusionFolder2}}).FullName | Out-File -FilePath $env:TEMP\$Object.txt -Encoding unicode 



Если в момент запуска скрипта, был объявлен параметр «ReportPath», отчет копируется в заданный каталог.

        If (!$ReportPath) {} else {Copy-Item -Path $env:TEMP\$Object.txt -Destination $ReportPath -Force}


Запоминаем время завершения поиска.

    $EndTime = (Get-Date).ToString()


Добавляется запись в лог файл, с успешно завершенными операциями.

Write-Output ($Object) | Add-Content $env:TEMP\Online.txt


Вывод на экран таблицы с результатом поиска, начало поиска и его время его окончание, объект на котором производился поиск.

        Invoke-Item $env:TEMP\$Object.txt
        $Results = "" | Select ComputerName, "StartTime", "EndTime"
        $Results.ComputerName = $Object 
        $Results.StartTime = $StartTime
        $Results.EndTime =$EndTime 
        $Results



Открывает содержимое отчета, если он не пустой, выполняет действие (отправка отчета), если пустой ничего не выполняет. Предотвращает отправку пустых отчетов.

If ((Get-Content $env:TEMP\$Object.txt) -eq $Null) {}


Если файл отчета не оказался пустой, формируется сообщение с заданными параметрами SMTP сервера, адресом администратора, тестом сообщения, вложением отчета.

    else {
        Try {
                Send-MailMessage -SmtpServer $SMTP -to $AdminMail -Body $Object -From denis.pasternak@hotmail.com -Subject $Object -Attachments $env:TEMP\$Object.txt
            } Catch {''} 



Сообщает на экране о том, что включён решим отправки только администратору, если был указан соответствующий ключ.

If ($AdminOnly -eq $True) { Write-Host "Включен параметр AdminOnly - отчет отправлен только аминистратору" -ForegroundColor Yellow} else 


Получаем имя пользователя активного на удаленном компьютере.

{       
            $Username=((gwmi win32_computersystem -computer $Object -ErrorAction SilentlyContinue).UserName -split '\\')[1]
            if($username -ne $null)




Если значение пользователя не пустое, ищем пользователя в Active Directory, определяем его значение почтовый адрес из моля Email. Получаем так же ФИО из Active Directory.

            {
            $Body = $Body
            $dispalyname = (Get-AdUser $username -properties DisplayName).DisplayName 
            $email = (Get-AdUser $username -properties mail).mail
            sleep -Seconds 3



Отправляем сообщение пользователю, с телом письма указанным в переменной $Body с подстановкой ФИО взятого из Active Directory.

Send-MailMessage -SmtpServer  $SMTP -Body  ( 'Уважаемый ' + $Dispalyname + ' ' + $Body | out-string ) -To $email -From $AdminMail -Subject  $Object -Attachments $env:TEMP\$Object.txt -Encoding Unicode



Если компьютер не был доступен, записываем результат в лог файл, о том что он был не доступен.

            }
        }
    }

else{ }        
        
       
        }
         else {
        (Write-Output ($Object + ' ' + (Get-Date).ToString()) | Add-Content $env:TEMP\Offline.txt)}
        }



Сбрасываем переменные.

$OU= $null
 $RemoteComputer = $null
 $Hosts = $nul



Устанавливаем атрибут «HomePage» для объектов компьютеры в Active Directory. Что поможет нам не проводить повторный поиск на этих компьютерах, пока эти значения не будут сброшены.

Get-Content $env:TEMP\Online.txt | Set-ADComputer -HomePage 'pass'
 }



Функция позволяет, открыть файл, получить содержимое (путь к файлу на удаленном компьютере), по каждой строке удалить файл на удаленном компьютере. $TargetFile — задает путь к файлу в котором хранится список файлов на удаление.

Function Remove-AuditFiles {
[CmdletBinding(SupportsShouldProcess=$True)]
        Param (
        [String]$TargetFile
        
        )

           Get-Content -Path "$env:TEMP\$Path" | %{Remove-Item $PSItem}

}



Функция позволяет сбросить атрибут HomePage объектов в Active Directory. Берет список компьютеров из указанной OU. Удаляет список в лог-файле.

Function Reset-AuditComputers {


[CmdletBinding(SupportsShouldProcess=$True)]
        Param (
        [String]$TargetOU
        
        )

 Get-ADComputer -Filter * -SearchBase $TargetOU -Properties * | Set-ADComputer -HomePage 'notpass'
'' | Set-Content -Path $env:TEMP\Online.txt 


} 



© Habrahabr.ru