서버 및 시스템을 관리할 때는 여유 디스크 공간을 유지하는 것이 중요합니다. 관리자로서 ‘디스크가 가득 찼습니다’라는 상황을 예기치 않게 당하지 않으려면 PowerShell을 사용하여 파일을 삭제하는 방법을 익혀야 합니다!
이 문서에서는 PowerShell을 사용하여 시스템에서 파일을 제거하는 방법을 거의 모두 배우게 될 것입니다.
시작해봅시다!
전제 조건
이 문서에서는 PowerShell을 사용한 예제를 제시하며, 따라하기를 원한다면 다음이 필요합니다.
- A computer that is running Windows 10 or above.
- Windows PowerShell 5.1 또는 PowerShell 7.0
- A script editor such as Visual Studio Code, Atom, or Notepad++.
파일 삭제를 위해 Remove-Item Cmdlet 사용
PowerShell을 사용하여 파일을 삭제해야 할 때, 아마도 바로 Remove-Item cmdlet에 대해 알게 될 것입니다. 이 cmdlet은 PowerShell을 사용한 파일 삭제의 사실상의 표준입니다.
Remove-Item을 Get-ChildItem cmdlet과 결합하여 파일 및 폴더를 읽고 강력한 PowerShell 파이프라인을 활용하면 매우 편리해집니다.
관련 정보: Get-ChildItem: 파일, 레지스트리, 인증서 등 목록 표시
Remove-Item cmdlet에는 ‘del’이라는 별칭이 있다는 사실을 알고 계셨나요? PowerShell에서는 Remove-Item 또는 del을 사용하면 동일한 명령이 실행됩니다.
파일을 삭제하기 위해 PowerShell 사용
가장 유용한 첫 번째 예는 가장 기본적인 것입니다. 즉, 단일 파일을 삭제하는 것입니다. 하나의 파일을 삭제하려면 아래의 명령어를 사용하기만 하면 됩니다. 아래의 코드는 파일 C:\temp\random.txt를 삭제합니다.
PowerShell에서 위의 코드를 실행하면 오류가 발생하지 않는 한 화면에 아무것도 표시되지 않습니다.
PowerShell을 사용하여 폴더의 모든 파일 삭제하기
이 예제에서는 아래의 코드로 폴더의 모든 파일을 삭제합니다. Get-ChildItem
cmdlet은 -Path
매개변수와 함께 C:\temp을 대상으로 합니다. -File
매개변수는 포함할 항목 유형이 파일만인 것을 나타냅니다. Get-ChildItem
은 폴더를 무시합니다.
출력은 아래 스크린샷과 같아야 합니다.

PowerShell을 사용하여 모든 파일 재귀적으로 삭제하기
이전 예제는 C:\temp 폴더의 파일만 삭제했습니다. 하위 디렉토리 내의 파일도 삭제해야 하는 경우, Get-ChildItem
cmdlet에 -Recurse
스위치를 추가하여 모든 파일을 재귀적으로 가져와야 합니다.
위의 코드를 실행하면 PowerShell이 모든 하위 폴더를 확인하고 파일 목록을 가져오도록 강제합니다. 아래 출력에서는 코드가 최상위 폴더의 파일을 삭제할 수 있었지만, 하위 폴더의 파일을 가져오지 못했습니다.

긴 경로 문제 해결하기
위의 오류는 PowerShell이 경로의 일부를 찾을 수 없다는 것을 나타냅니다. 이 오류는 cmdlet이 존재하지 않는 경로를 찾으려고 시도하고 있음을 나타내며, 잘못된 정보를 제공합니다.
이 경우에는 Get-ChildItem
이 읽으려는 경로가 260자의 최대 경로 길이를 초과하기 때문에 오류가 발생했습니다.
아래 스크린샷은 경로 또는 디렉토리와 해당 하위 디렉토리가 존재하며 하위 디렉토리의 하단에 InTooDeep.txt라는 텍스트 파일이 위치함을 보여줍니다. 중첩된 디렉토리 이름을 구성하는 모든 문자의 조합은 긴 경로 문제를 발생시킵니다.

Windows PowerShell 5.1에서는 긴 경로 이름 문제에 대한 해결책이 있습니다. 해당 해결책은 경로의 유니코드 버전을 사용하는 것입니다. C:\temp와 같이 경로를 지정하는 대신에 로컬에 위치한 폴더의 경우에는 ‘ \\?\C:\temp’ 와 같이 유니코드 버전을 사용하거나, UNC 경로에 폴더가 위치한 경우에는 ‘\\?\UNC\<컴퓨터 이름>\<공유>\Temp’와 같이 사용합니다.
긴 경로 이름에 대응하는 수정된 코드를 사용하면 PowerShell이 깊게 중첩된 경로 이름을 성공적으로 읽고 파일을 삭제하는 것을 아래 출력에서 확인할 수 있습니다.

긴 경로 이름 문제는 PowerShell 7.0에는 영향을 미치지 않습니다. PowerShell 7.0에서는 이미 긴 경로 이름을 지원하기 때문에 유니코드 버전의 경로를 사용할 필요가 없습니다.
폴더도 삭제해야 하는 경우에는 Get-ChildItem
cmdlet에서 -File
매개변수를 제거하면 PowerShell이 파일과 폴더를 포함한 모든 항목을 삭제해야 합니다.
x일보다 오래된 파일을 삭제하기 위해 PowerShell 사용하기
디스크 공간 관리의 또 다른 전형적인 예시는 특정 일수보다 오래된 파일을 삭제하는 것입니다. 이 예시는 IIS 웹 서버에서 생성되는 로그 파일과 같은 오래된 로그 파일을 삭제하여 디스크 공간을 확보하는 데 유용합니다.
이 예시에서는 c:\temp에 14일 이상된 파일이 있습니다. 아래 스크립트를 사용하여 c:\temp에 있는 각 파일의 Name
, CreationTime
, AgeInDays
가 표시됩니다.
아래 스크린샷에서 볼 수 있듯이, 15일, 7일, 0일 전의 파일이 있습니다.

이제 삭제할 파일을 알았으므로, 특정 일수보다 오래된 파일 – 이 경우 14일보다 오래된 파일 – 만 삭제하는 스크립트를 작성할 수 있습니다.
아래 예시 스크립트에서는 C:\temp에 있는 CreationTime
값이 설정한 임계값보다 오래된 파일이 삭제됩니다.
첫 번째 줄은 Get-ChildItem
이 검색할 경로를 정의합니다. 경로는 $path
변수에 저장됩니다. 그 다음, 두 번째 줄에서 임계값이 지정됩니다. $threshold
의 값은 삭제할 파일의 나이(일)를 나타냅니다.
$threshold
변수 다음의 코드 줄은 다음 작업을 수행합니다:
$path
변수에 지정된 폴더에 있는 파일 컬렉션을 가져옵니다. 이 예시에서는 경로가 C:\temp입니다.- 출력을 필터링하여
CreationTime
값이$threshold
변수에 저장된 일 수보다 오래된 파일만 포함됩니다. 이 예시에서는 임계값이 14일입니다. Remove-Item
값으로 필터링된 파일 목록을 전달하여 해당 파일을 삭제합니다.
위의 코드를 실행하면 아래와 같은 출력이 표시됩니다.

위의 스크린샷에서 verbose 메시지에 따라 스크립트는 14일 이전의 파일만 삭제했습니다. 14일 이전의 파일이 아직 존재하는지 확인하기 위해 아래 코드를 실행하여 다시 목록을 나열하십시오.
아래 결과에서 Remove-Item
이 최신 파일을 삭제하지 않았음을 확인할 수 있습니다.

파일 패턴 일치 및 삭제를 위해 PowerShell 사용
파일 이름, 유형 또는 확장자와 관계없이 모든 파일을 삭제하는 것은 항상 최선이 아닙니다. 때로는 삭제 프로세스에서 특정 파일을 명시적으로 제외하거나 포함해야 할 필요가 있습니다.
다음 예제는 *.LOG 파일 이름과 일치하는 파일을 삭제하는 방법을 보여줍니다. Remove-Item
cmdlet을 사용하여 -Include
매개변수를 사용하는 방법이 있습니다.
또 다른 방법은 아마도 조심스러운 접근법으로 먼저 Get-ChildItem
을 사용하여 삭제할 파일 목록을 수집하는 것입니다. 삭제할 파일 목록에 만족할 때만 마지막으로 컬렉션을 Remove-Item
cmdlet에 파이프할 수 있습니다.
예를 들어, 아래 코드에서는 c:\temp에서 *.LOG 파일을 가져옵니다.
위의 코드 결과로 Get-ChildItem
이 *.LOG 파일 이름과 일치하는 파일 목록을 반환합니다.

하지만 이름에 숫자 5가 포함된 파일을 제외하고 싶다면 다음 코드처럼 -Exclude
매개변수를 추가할 수 있습니다.
숫자 5가 포함된 파일을 제외했기 때문에 결과가 달라집니다. 특히 아래에 표시된 것처럼 파일 File_5.log은 더 이상 목록에 없습니다.

코드로 생성된 파일 컬렉션에 만족하면, 파일 컬렉션을 Remove-Item
cmdlet에 파이프하여 이제 파일을 최종적으로 삭제할 수 있습니다.
최종 코드를 실행한 후에는 선택한 파일만 삭제하는 목표를 달성하게 됩니다.

PowerShell에서 WMI를 사용하여 파일 삭제하기
파일을 삭제하기 위해 일반적인 Remove-Item
cmdlet을 사용하는 방법에 대해 충분히 이해했으므로, 좀 더 고급 사용 사례인 WMI를 사용해보겠습니다.
PowerShell에는 WMI를 지원하는 기능이 있습니다. WMI 지원은 PowerShell 내부에서 WMI 쿼리와 메서드를 호출할 수 있음을 의미합니다. 네, WMI는 이전 Windows의 관리자가 사용한 Visual Basic 스크립트만을 위한 것은 아닙니다.
Microsoft는 PowerShell 3.0에서 WMI에 특화된 CIM cmdlet을 출시했습니다. 파일을 삭제하는 데 사용될 CIM cmdlet은 Get-CimInstance
와 Invoke-CimMethod
입니다.
PowerShell과 WMI를 사용하여 파일 삭제하기
이 예제에서는 삭제할 특정 파일의 경로를 알고 있다고 가정합니다. Get-CimInstance
cmdlet과 Cim_DataFile
클래스를 사용하여 삭제할 파일에 대한 정보를 검색합니다. 이 경우에는 C:\Temp\random.txt입니다.
위의 코드에서 -Filter
매개변수는 WQL 형식의 쿼리를 허용합니다. WQL을 사용하려면 백슬래시를 포함한 일부 문자를 이스케이프해야 합니다. 그리고 WQL 이스케이프 문자도 백슬래시이므로, 두 개의 백슬래시 문자인 \\
로 결과가 생성됩니다.
위의 코드를 실행하면 아래의 데모에서 보여지는 결과가 생성됩니다. C:\Temp\random.txt에 대한 정보가 $file2delete
변수에 저장됩니다.

이제 파일 C:\Temp\random.txt에 대한 정보를 검색했으므로, $file2delete
변수에 있는 결과 객체를 Invoke-CimMethod
cmdlet에 파이프로 전달할 수 있습니다. Invoke-CimMethod
cmdlet에는 -Name
이라는 매개변수가 있으며, 이는 Cim_DataFile
클래스의 메서드 이름을 나타냅니다.
아래 스크린샷에서 볼 수 있듯이, ReturnValue
가 0인 것은 명령이 성공했음을 의미합니다.

가능한 ReturnValue 코드에 대한 자세한 내용은 다음 링크를 참조하십시오 – CIM_DataFile 클래스의 Delete 메서드
또한 아래 스크린샷은 Invoke-CimMethod
의 Delete()
메서드를 실행한 후, CIM이 C:\Temp\random.txt 파일만 삭제했음을 보여줍니다. 다른 파일은 삭제되지 않았습니다.

PowerShell과 WMI를 사용하여 폴더의 모든 파일 삭제하기
다음 예제에서는 PowerShell과 WMI를 사용하여 폴더의 모든 파일을 삭제하는 방법을 보여줍니다. 이전 예제에서 사용한 cmdlet인 Get-CimInstance
와 Invoke-CimMethod
를 사용할 것입니다. 그러나 이번에는 WQL 쿼리가 특정 파일 하나 대신 폴더의 모든 파일을 검색할 것입니다.
다음 코드에서는 Get-CimInstance
cmdlet을 사용하여 C:\temp에 위치한 모든 파일을 검색합니다. 아래에서 볼 수 있듯이, 쿼리는 Cim_DataFile
클래스의 Drive
와 Path
속성을 필터링합니다.
위의 코드를 실행하면 C:\temp의 파일에 대한 정보가 $file2delete
변수에 저장됩니다. $file2delete
변수의 값은 아래의 출력을 보여줍니다.

이제 $file2delete
변수에 저장된 값은 c:\temp의 모든 파일을 삭제하기 위해 Invoke-CimMethod
에 파이프될 수 있습니다.
기억하세요. 0의 ReturnValue
코드는 성공을 의미하며, 삭제 메서드가 호출된 각 파일은 고유의 ReturnValue
코드를 갖게 됩니다.

PowerShell과 WMI를 사용하여 확장자별로 파일 삭제하기
이전 예제에서는 확장자에 관계없이 폴더 내의 모든 파일을 삭제하는 방법을 보았습니다. 그러나 확장자에 따라 삭제될 파일을 제어할 수도 있습니다.
아래 코드에서 확인할 수 있듯이 이번에는 쿼리에 추가 조건(Name LIKE '%.log
)이 있습니다. 이 추가된 조건은 .LOG 확장자와 일치하는 파일만 반환한다는 의미입니다. 퍼센트(%
) 기호는 WQL LIKE 연산자로서 “0개 이상의 문자열”을 의미합니다. 프로그래밍 용어로는 %
는 와일드카드를 나타내는 별표(*
)와 동일합니다.
아래의 데모에서는 위의 코드가 실행되기 전에 9개의 *.LOG 파일과 1개의 *.TXT 파일이 있는 것을 보여줍니다. 코드 실행 후에는 *.LOG 파일이 삭제되고 *.TXT 파일만 폴더에 남게 됩니다.

WMI와 Remove-Item 비교
지금까지 이 튜토리얼에서 PowerShell을 사용하여 파일을 삭제하는 방법에 대해 개요를 알아보았습니다. Remove-Item
과 WMI에 대해 알아보았습니다. 두 가지 방법 모두 유사한 기능을 수행하지만 매우 다릅니다.
파일을 삭제하는 데 어떤 방법을 사용해야 할까요? Remove-Item
또는 WMI?
PowerShell의 내장 cmdlet인 Get-ChildItem
과 Remove-Item
을 사용하여 파일을 검색하고 삭제하는 것은 WMI를 사용할 때보다 훨씬 빠릅니다.
아래 예시는 WMI와 내장 PowerShell cmdlet을 사용하여 C:\windows\web 디렉토리와 그 하위 디렉토리의 파일 목록을 가져오는 것을 비교한 것입니다.
위의 코드를 PowerShell에서 실행하면 아래와 유사한 출력 결과가 나타납니다.

위의 출력 결과에서 알 수 있듯이, Get-CimInstance
를 사용하여 C:\windows\web의 파일을 나열하는 데 걸리는 시간은 Get-ChildItem
보다 약 10배 더 오래 걸립니다!
또한, Get-ChildItem
라인이 Get-CimInstance
보다 훨씬 짧다는 것에 주목했나요? Get-ChildItem
을 사용하면 실행 시간이 더 빨라뿐만 아니라 코드도 더 깔끔하고 짧아집니다.
다음 단계
이 글에서는 내장된 cmdlet과 WMI/CIM을 사용하여 파일을 삭제하는 PowerShell의 두 가지 다른 방법을 살펴보았습니다.
항상 Get-ChildItem
과 Remove-Item
cmdlet을 사용하여 파일을 삭제해야 함을 알아두세요. 이러한 내장된 cmdlet은 WMI를 사용할 때보다 더 유연하고 쉽고 빠르게 사용할 수 있습니다.
당신을 위해 디스크 공간 정리를 수행할 수 있는 스크립트를 만들어보세요. 이미 그 목적으로 사용되는 몇 가지 스크립트가 있을 수 있습니다. 참고 자료로 사용해보세요. 그러나 실습과 학습을 하려는 의지가 있다면 직접 만들어보세요.
더 읽어보기
Source:
https://adamtheautomator.com/powershell-to-delete-files/