AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / server / Perguntas / 773696
Accepted
HopelessN00b
HopelessN00b
Asked: 2016-04-29 11:00:55 +0800 CST2016-04-29 11:00:55 +0800 CST 2016-04-29 11:00:55 +0800 CST

Como posso usar o PowerShell para habilitar a compactação NTFS, no local, em arquivos de log com mais de x dias?

  • 772

Eu tenho um servidor de aplicativos, executando o Windows 2012 R2, que gera um grande volume de arquivos de log, a ponto de executar o volume do aplicativo sem espaço livre semi-regularmente. Devido a restrições do próprio aplicativo, não posso mover ou renomear os arquivos de log ou habilitar a desduplicação de dados NTFS e, como não faz mais dez anos, não quero usar um lote ou vbscript para fazer isso para mim.

Os arquivos de log estão todos em várias subpastas do diretório de instalação do aplicativo, com diferentes extensões (um componente adiciona a data como a extensão do arquivo de log), e o diretório de instalação do aplicativo tem um espaço nele, porque os desenvolvedores do aplicativo são malévolos. As subpastas onde os logs são gravados são usadas exclusivamente para fins de gravação de logs, pelo menos. Este também é um aplicativo fortemente vinculado à CPU, portanto, não quero compactar as próprias pastas de log e incorrer na penalidade de CPU associada à gravação de arquivos compactados para os logs.

Como posso usar o PowerShell para habilitar a compactação NTFS, in-loco, em arquivos de log com mais de x dias?

windows powershell ntfs windows-server-2012-r2 powershell-v4.0
  • 5 5 respostas
  • 7758 Views

5 respostas

  • Voted
  1. Best Answer
    HopelessN00b
    2016-04-29T11:00:55+08:002016-04-29T11:00:55+08:00

    A solução mais fácil, já que o suporte do PowerShell para operações de arquivo ainda é escasso, é criar um script do PowerShell para chamar o compact.exeutilitário e configurá-lo como uma tarefa agendada. Por causa do espaço no nome do caminho, você deseja chamar compact.exediretamente, em vez de usar Invoke-WMIMethode a CIM_DataFileclasse (o que causará muito esforço extra para lidar com o espaço no caminho).

    Assumindo uma idade de 3 dias para X, seu script do PowerShell seria algo como:

    $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
    }
    
    ...
    

    A segunda condição é acelerar a execução do script ignorando os arquivos já compactados (que estariam presentes após a primeira execução do script). Se você quisesse, ou tivesse muitas subpastas de log diferentes, provavelmente faria sentido criar uma função a partir desse código repetido do PowerShell, o que seria um exercício bastante trivial.

    • 9
  2. boossy
    2016-05-24T23:04:06+08:002016-05-24T23:04:06+08:00

    O código repetido pode ser evitado usando um array e um loop 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
        }
    }
    

    .....

    • 5
  3. Andrew Vawter
    2019-12-25T02:49:40+08:002019-12-25T02:49:40+08:00

    Invoke-WmiMethod -Path "Win32_Directory.Name='C:\FolderToCompress'" -Compactação de nome

    • 0
  4. Joachim Otahal
    2022-05-17T13:54:44+08:002022-05-17T13:54:44+08:00

    É possível fazer isso sem precisar depender do compact.exe, um método "puro powershell" chamando a compactação NTFS diretamente. Isso também lida com espaços em nomes de arquivos e nomes de arquivos unicode do Japão, os últimos são difíceis de fornecer a uma linha de comando compact.exe. Consulte https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ni-winioctl-fsctl_set_compression também.

    $MethodDefinition= @'
    public static class FileTools
    {
      private const int FSCTL_SET_COMPRESSION = 0x9C040;
      private const short COMPRESSION_FORMAT_DEFAULT = 1;
      private const short COMPRESSION_FORMAT_DISABLE = 0;
    
      [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
      private static extern int DeviceIoControl(
          IntPtr hDevice,
          int dwIoControlCode,
          ref short lpInBuffer,
          int nInBufferSize,
          IntPtr lpOutBuffer,
          int nOutBufferSize,
          ref int lpBytesReturned,
          IntPtr lpOverlapped);
    
      public static bool Compact(IntPtr handle)
      {
        int lpBytesReturned = 0;
        short lpInBuffer = COMPRESSION_FORMAT_DEFAULT;
    
        return DeviceIoControl(handle, FSCTL_SET_COMPRESSION,
            ref lpInBuffer, sizeof(short), IntPtr.Zero, 0,
            ref lpBytesReturned, IntPtr.Zero) != 0;
      }
      public static bool Uncompact(IntPtr handle)
      {
        int lpBytesReturned = 0;
        short lpInBuffer = COMPRESSION_FORMAT_DISABLE;
    
        return DeviceIoControl(handle, FSCTL_SET_COMPRESSION,
            ref lpInBuffer, sizeof(short), IntPtr.Zero, 0,
            ref lpBytesReturned, IntPtr.Zero) != 0;
      }
    }
    '@
    
    $Kernel32 = Add-Type -MemberDefinition $MethodDefinition -Name ‘Kernel32’ -Namespace ‘Win32’ -PassThru
    
    $logfilespec = "c:\Logfolder\*.log"
    
    # compact anything older than three days
    foreach ($File in (Get-ChildItem -Path $logfilespec -Recurse -File).Where({$_.LastWriteTime -lt (Get-Date).AddDays(-3) -and $_.Attributes  -notmatch [System.IO.FileAttributes]::Compressed})) {
        $FileObject = [System.IO.File]::Open($File.FullName,'Open','ReadWrite','None')
        $Method = [Win32.Kernel32+FileTools]::Compact($FileObject.Handle)
        $FileObject.Close()
    }
    
    # decompact
    foreach ($File in (Get-ChildItem -Path $logfilespec -Recurse -File).Where({$_.Attributes  -match [System.IO.FileAttributes]::Compressed})) {
        $FileObject = [System.IO.File]::Open($File.FullName,'Open','ReadWrite','None')
        $Method = [Win32.Kernel32+FileTools]::Uncompact($FileObject.Handle)
        $FileObject.Close()
    }
    
    • 0
  5. Joachim Otahal
    2020-01-31T20:52:24+08:002020-01-31T20:52:24+08:00

    Se esses arquivos de log não estiverem em C: use o recurso de desduplicação do Server 2012 R2. Você pode então configurá-lo para desfazer a duplicação apenas de arquivos .log com três dias (o padrão). O segundo método para controlar isso, ou quando estiver em C: Mova o diretório de log para uma unidade diferente e use uma JUNÇÃO para apontar para o novo local, mais fácil de criar com Hardlink-Shell-Extension de https://schinagl .priv.at/nt/hardlinkshellext/linkshellextension.html - e, em seguida, use a desduplicação 2012 R2 na parte superior. Eu vi taxas de desduplicação muito acima de 90% em arquivos de log e nas unidades SQL-dump-for-backup.

    • -1

relate perguntas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Você pode passar usuário/passar para autenticação básica HTTP em parâmetros de URL?

    • 5 respostas
  • Marko Smith

    Ping uma porta específica

    • 18 respostas
  • Marko Smith

    Verifique se a porta está aberta ou fechada em um servidor Linux?

    • 7 respostas
  • Marko Smith

    Como automatizar o login SSH com senha?

    • 10 respostas
  • Marko Smith

    Como posso dizer ao Git para Windows onde encontrar minha chave RSA privada?

    • 30 respostas
  • Marko Smith

    Qual é o nome de usuário/senha de superusuário padrão para postgres após uma nova instalação?

    • 5 respostas
  • Marko Smith

    Qual porta o SFTP usa?

    • 6 respostas
  • Marko Smith

    Linha de comando para listar usuários em um grupo do Windows Active Directory?

    • 9 respostas
  • Marko Smith

    O que é um arquivo Pem e como ele difere de outros formatos de arquivo de chave gerada pelo OpenSSL?

    • 3 respostas
  • Marko Smith

    Como determinar se uma variável bash está vazia?

    • 15 respostas
  • Martin Hope
    Davie Ping uma porta específica 2009-10-09 01:57:50 +0800 CST
  • Martin Hope
    kernel O scp pode copiar diretórios recursivamente? 2011-04-29 20:24:45 +0800 CST
  • Martin Hope
    Robert ssh retorna "Proprietário incorreto ou permissões em ~/.ssh/config" 2011-03-30 10:15:48 +0800 CST
  • Martin Hope
    Eonil Como automatizar o login SSH com senha? 2011-03-02 03:07:12 +0800 CST
  • Martin Hope
    gunwin Como lidar com um servidor comprometido? 2011-01-03 13:31:27 +0800 CST
  • Martin Hope
    Tom Feiner Como posso classificar a saída du -h por tamanho 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich O que é um arquivo Pem e como ele difere de outros formatos de arquivo de chave gerada pelo OpenSSL? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent Como determinar se uma variável bash está vazia? 2009-05-13 09:54:48 +0800 CST

Hot tag

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve