첫 번째 PowerShell 스크립트 작성하는 방법: 파일 정리 자동화

가장 중요한 코딩 방법론 중 하나는 코드가 “흐르는” 모든 방법을 알고 관리하는 것입니다. 코드를 흐름으로 생각하면, 코드는 여러 지점으로 분기하고, 다양한 지점으로 돌아가며, 많은 조건을 만날 수 있습니다.

오류 처리는 예상치 못한 일이 발생했을 때 코드가 흐를 수 있는 “망” 또는 기본 위치를 설정하도록 보장합니다.

실제 상황을 사용해 보겠습니다. PowerShell 오류 처리와 관련된 상황입니다.

파일 정리를 위한 초기 스크립트 작성하기

우리는 오래된 파일을 정리해야 합니다. 우리의 파일 서버는 오래되었고, 공간을 정리할 필요가 있습니다. 관리 측에서는 특정 일 수보다 오래된 모든 파일을 제거하기로 결정했습니다. 특정 일 수보다 오래된 모든 파일을 찾고, 이를 제거하는 스크립트를 작성해야 합니다.

작업은 꽤 간단하게 들리지만, 이는 오류 처리 섹션이므로 어떤 일이 잘못될 것임을 알고 있습니다!

먼저 오류 처리의 문제를 보여주기 위해 오류 처리가 없는 시나리오의 데모 스크립트를 작성하여 오류 처리를 이해해 봅시다.오류 처리 없이.

  1. 먼저 새로운 VS Code 탭을 엽니다.

    지금은 몇 가지를 시도하고 있으므로 스크립트를 아직 저장하지 않겠습니다. VS Code에 PowerShell을 작성할 것임을 일시적으로 알려줍니다.

    Ctrl-Shift-P를 누르고 ‘lang’을 입력한 다음 언어 모드 선택을 선택하고 ‘power’를 입력한 후 PowerShell을 선택합니다. 이제 VS Code는 PowerShell을 작성할 것이라는 것을 알고 있습니다.

  2. 다음으로, 문제를 작업으로 나누고 가장 명백한 작업부터 해결합니다.

    이번 경우, 작업은 디렉터리의 파일을 읽는 명령을 제공합니다.

    Get-ChildItem -Path C:\OldForgottenFolder
    
  3. Get-ChildItem은 우리가 필요하지 않은 디렉터리도 반환하므로, 이를 파일로만 제한하겠습니다.

    Get-ChildItem -Path C:\OldForgottenFolder -File
    
  4. 그 하위 디렉터리에 파일이 있다면, Recurse를 사용하여 이를 가져와야 합니다.

    Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse
    
  5. 이제 명령어와 매개변수를 가지고 있으니, 모든 파일을 반환하고 있습니다. 우리는 특정 일수보다 오래된 파일만 찾아야 합니다.

    Get-ChildItem은 각 파일을 LastWriteTime 객체 속성과 함께 반환하므로, 해당 속성으로 필터링해야 합니다. 우리는 LastWriteTime이 특정 날짜보다 이전인 파일을 찾기 위해 Where 필터를 사용할 것입니다.

    (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    
  6. 날짜는 동적이어야 합니다. 오늘의 “오래된” 파일은 내일의 “오래된” 파일과 다를 것입니다.

    우리는 이 줄을 주석 처리해야 합니다. 왜냐하면 나중에 필요할 것이고 날짜 문제를 해결해야 하기 때문입니다.

    ## (Get-ChildItem -Path C:\\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    $Now = Get-Date
    $Now
    
  7. 오늘 날짜를 가지고 특정 일 수 전의 날짜를 찾아봅시다. 파일 중에서 다섯 일 이상이 지난 파일이 있음을 알고 있어서 단순한 테스트를 하기 위해 일단 30을 여기에 넣어둘게요.

    ## (Get-ChildItem -Path C:\\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le ?????}
    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    $LastWrite
    
  8. 완료되었습니다! 지금까지 한 것들을 모아봅시다.

    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite}
    

    이제 특정 일 수 이전에 만들어진 모든 파일을 찾는 작은 스크립트가 생겼습니다.

  9. 다음으로, 이전 파일들을 제거할 수 있는 능력을 추가해야 합니다. 이는 Remove-Item cmdlet과 파이프라인을 사용하면 간단합니다.

    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite} | Remove-Item
    
  10. 완료되었습니다! 하지만 잠깐, 어떤 파일이 삭제되었는지 전혀 모르겠어요. 몇 분 후에 해결할 오류도 있었습니다. 기본 기능을 추가해 봅시다.

    $VerbosePreference = '계속'
    
    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    $oldFiles = (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite}
    foreach ($file in $oldFiles) {
        Remove-Item -Path $file.FullName
        Write-Verbose -Message "성공적으로 삭제되었습니다 [$($file.FullName)]."
    }
    
  11. 각 파일에 대해 코드를 실행하기 위해 이와 같은 루프를 포함해야 합니다. 여기서는 파이프라인을 사용하지 않고 발견된 모든 파일을 oldFiles 변수에 저장하고, 파일 객체의 배열로 만듭니다. 그런 다음 이전처럼 각 파일에 대해 Remove-Item을 실행하지만, 이번에는 어떤 파일이 삭제되고 있는지를 알려주는 자세한 메시지를 포함합니다.

  12. 이제 이 코드를 실행해 보고 어떤 일이 일어나는지 확인해 봅시다.

    자세한 메시지를 통해 몇 개의 파일이 삭제된 것을 볼 수 있습니다. 현재 가지고 있는 코드는 스크립트를 만들기 위해 필요한 핵심입니다. 이제 다음 섹션에서 이것을 바탕으로 실제 스크립트를 만들어 봅시다.

매개변수를 통한 유연성 및 재사용성 극대화

스크립트를 만들었지만, 여전히 유연하고 재사용 가능할 잠재력이 있습니다. 어떻게? 매개변수를 사용하면 우리가 타겟으로 삼고자 하는 디렉터리와 파일의 나이를 지정할 수 있어 스크립트가 더 유연해집니다.

  1. 더 진행하기 전에, 작업을 저장합시다. 이름은 Remove-FileOlderThan.ps1로 하세요.

    하이픈이 있는 동사/명사 형식을 주목하세요. 가능하다면 일관성과 가독성을 위해 PowerShell 명령어와 동일한 방식으로 스크립트 이름을 항상 생성하도록 하세요.

  2. 먼저, 스크립트는 재사용 가능하도록 설계되었습니다. 아마도 이 스크립트를 서로 다른 디렉토리와 다양한 연령에 사용하고 싶을 것입니다. 일부 매개변수를 도입해야 합니다. 그렇게 하기 위해서 무엇이 변경될지를 파악합니다. 디렉토리와 일 수입니다. 알겠습니다.

    param (
        [Parameter(Mandatory)]
        [string]$FolderPath,
    [Parameter(Mandatory)]
    [int]$DaysOld
    

    )

    $Now = Get-Date
    $LastWrite = $Now.AddDays(-30)
    $oldFiles = (Get-ChildItem -Path C:\OldForgottenFolder -File -Recurse).Where{$_.LastWriteTime -le $LastWrite}
    foreach ($file in $oldFiles) {
    Remove-Item -Path $file.FullName
    Write-Verbose -Message "성공적으로 제거했습니다 [$($file.FullName)]."
    }

    스크립트가 작동하려면 경로와 숫자가 필요하므로 맨 위에 param 블록을 추가하고 각 매개변수를 필수로 정의하세요. 또한, 모범 사례로 여기서 유형을 지정하세요.

  3. 이전 코드에서 사용했던 정적 항목을 매개변수 값으로 교체하십시오.

    param (
        [Parameter(Mandatory)]
        [string]$FolderPath,
    [Parameter(Mandatory)]
    [int]$DaysOld
    

    )

    $Now = Get-Date
    $LastWrite = $Now.AddDays(-$DaysOld)
    $oldFiles = (Get-ChildItem -Path $FolderPath -File -Recurse).Where{$_.LastWriteTime -le $LastWrite}
    foreach ($file in $oldFiles) {
    Remove-Item -Path $file.FullName
    Write-Verbose -Message "성공적으로 제거되었습니다 [$($file.FullName)]."
    }

  4. 이제 스크립트를 실행하고 무슨 일이 일어나는지 봅시다.

    C:\Scripts\Remove-FileOlderThan.ps1 -FolderPath C:\OldForgottenFolder -DaysOld 30 -Verbose

    폴더의 경로와 며칠이 지났는지를 매개변수로 지정해야 하는 방법을 볼 수 있습니다. Write-Verbose 라인을 보려면 Verbose 매개변수를 사용하세요.

    PowerShell은 이전과 정확히 동일하게 스크립트를 실행했지만, 이제는 어떤 디렉터리나 파일의 나이에 사용할 수 있는 매개변수화된 스크립트가 생겼습니다!

    출력을 살펴보면 빨간 글자가 일부 나타났습니다. 권한이 없거나 파일이 읽기 전용입니다. 그런데 어떤 파일에서 실패했을까요? 그리고 이러한 파일도 삭제되도록 하려면 어떻게 해야 할까요?

    결론

    이번 튜토리얼에서는 디렉터리에서 오래된 파일을 정리하는 스크립트를 작성하였고, 매개변수를 추가하여 유연성을 보장했습니다. 스크립트는 의도한 대로 작동했지만, 실제 환경에서 중요한 오류 처리에 대해서는 아직 다루지 않았습니다.

    앞으로 나아가면서 오류 관리를 추가하면 cmdlet이 오류를 발생시키거나 파일에 접근할 수 없는 경우와 같은 문제를 처리할 수 있어 스크립트 종료를 피하고 무엇이 잘못되었는지에 대한 자세한 통찰력을 제공할 수 있습니다.

    다음 데모를 기대해 주세요! PowerShell 101: 종료 오류, 비종료 오류 및 Try/Catch.

Source:
https://adamtheautomator.com/powershell-file-cleanup-script/