Назад | Перейти на главную страницу

Как я могу использовать PowerShell, чтобы включить сжатие NTFS на месте для файлов журнала старше x дней?

У меня есть сервер приложений под управлением Windows 2012 R2, который генерирует большой объем файлов журналов до такой степени, что он периодически запускает том приложения из свободного места. Из-за ограничений самого приложения я не могу перемещать или переименовывать файлы журнала или включать дедупликацию данных NTFS, и из-за того, что этого больше не было десять лет назад, я не хочу использовать пакет или vbscript для этого для меня.

Все файлы журнала находятся в различных подпапках каталога установки приложения с разными расширениями (один компонент добавляет дату в качестве расширения файла журнала), а в каталоге установки приложения есть свободное место, поскольку разработчики приложения недоброжелательны. Подпапки, в которые записываются журналы, используются исключительно для записи журналов, по крайней мере. Это приложение также сильно зависит от ЦП, поэтому я не хочу сжимать сами папки журналов и нести потери ЦП, связанные с записью сжатых файлов для журналов.

Как с помощью PowerShell включить сжатие NTFS на месте для файлов журналов старше x дней?

Самое простое решение, поскольку поддержка PowerShell для файловых операций по-прежнему отсутствует, - это создать сценарий PowerShell для вызова compact.exe утилиту и настроить ее как запланированное задание. Из-за пробела в имени пути вы хотите вызвать compact.exe напрямую, вместо использования Invoke-WMIMethod и CIM_DataFile class (что потребует дополнительных усилий, чтобы справиться с пространством на пути).

Предполагая, что возраст X составляет 3 дня, ваш сценарий PowerShell будет выглядеть примерно так:

$logfolder="[location of the first logging subfolder]"
$age=(get-date).AddDays(-3)

Get-ChildItem $logfolder | where-object {$_.LastWriteTime -le $age -AND $_.Attributes -notlike "*Compressed*"} | 
ForEach-Object {
compact /C $_.FullName
}

$logfolder="[location of the next logging subfolder]"

Get-ChildItem $logfolder | where-object {$_.LastWriteTime -le $age -AND $_.Attributes -notlike "*Compressed*"} | 
ForEach-Object {
compact /C $_.FullName
}

...

Второе условие - ускорить выполнение скрипта, пропуская уже сжатые файлы (которые будут присутствовать после первого запуска этого скрипта). Если бы вы хотели или у вас было много разных подпапок для журналирования, вероятно, имело бы смысл сделать функцию из этого повторяющегося кода PowerShell, что было бы довольно тривиальным упражнением.

Повторного кода можно избежать, используя массив и цикл foreach:

$logfolders=("D:\Folder\One","D:\Folder\Two")
$age=(get-date).AddDays(-3)

foreach ($logfolder in $logfolders) {
    Get-ChildItem $logfolder | where-object {$_.LastWriteTime -le $age -AND $_.Attributes -notlike "*Compressed*"} | 
    ForEach-Object {
    compact /C $_.FullName
    }
}

.....

Если эти файлы журналов находятся не на C: используйте функцию дедупликации Server 2012 R2. Затем вы можете настроить его на удаление файлов .log только трехдневной давности (по умолчанию). Второй способ получить это под контролем, или когда он находится на C: переместите каталог журнала на другой диск и используйте JUNCTION, чтобы указать на новое место, проще всего создать с помощью Hardlink-Shell-Extension из https://schinagl.priv.at/nt/hardlinkshellext/linkshellextension.html - а затем используйте дедупликацию 2012 R2 поверх. Я видел, что показатели дедупликации намного превышают 90% для файлов журналов и дисков SQl-dump-for-backup.

Invoke-WmiMethod -Path "Win32_Directory.Name = 'C: \ FolderToCompress'" -Name compress