스크립트나 PowerShell cmdlet을 실행하면 아래와 같이 붉은 글자의 벽과 마주치게 될 때가 있었나요?

오류는 압도적이고 혼란스러울 수 있습니다. 무엇보다도 오류는 자주 읽기 어렵기 때문에 스크립트가 어디서 어떤 오류가 발생했는지 파악하기가 거의 불가능합니다.
다행히도 PowerShell에서는 이를 개선하기 위해 오류 처리를 통해 몇 가지 옵션을 제공합니다. 오류 처리를 사용하면 오류를 필터링하고 표시하는 방식을 조정하여 이해하기 쉬워집니다. 또한 오류를 이해하는 것은 오류 처리에 더 많은 논리를 추가하기 쉽게 만듭니다.
이 글에서는 PowerShell의 오류와 PowerShell의 Try Catch
블록(및 finally
블록)을 사용하여 오류 처리를 수행하는 방법에 대해 알아보겠습니다.
PowerShell에서 오류 처리하는 방법 이해하기
오류 처리에 대해 자세히 알아보기 전에 PowerShell의 오류에 대한 몇 가지 개념을 먼저 알아보겠습니다. 오류를 이해하면 더 나은 오류 처리 전략을 수립할 수 있습니다.
$Error
자동 변수
PowerShell에는 많은 자동 변수가 있으며, $Error
자동 변수가 그 중 하나입니다. PowerShell은 세션에서 발생한 모든 오류를 저장하기 위해 $Error
변수를 사용합니다. $Error
변수는 가장 최근에 발생한 오류를 기준으로 정렬된 오류 배열입니다.
PowerShell 세션을 처음 열 때, $Error
변수는 비어 있습니다. $Error
변수를 호출하여 확인할 수 있습니다.

보시다시피, $Error
변수는 처음에는 비어 있습니다. 그러나 오류가 발생하면 해당 오류가 $Error
변수에 추가되고 저장됩니다.
아래 예제에서는 일부러 존재하지 않는 서비스 이름을 가져와 오류를 생성합니다.

위의 출력에서 볼 수 있듯이, 생성된 오류가 $Error
변수에 추가되었습니다.
$Error 변수는 PowerShell 세션에서 생성된 오류의 컬렉션을 포함합니다. 각 오류는 배열 위치를 호출하여 액세스할 수 있습니다. 가장 최근의 오류는 항상 인덱스 0에 있습니다.
예를 들어, 최신 오류는
$Error[0]
을 사용하여 검색할 수 있습니다.
$Error
개체 속성
PowerShell의 모든 것이 개체이기 때문에, $Error
변수는 개체이며, 개체에는 속성이 있습니다. $Error
변수를 Get-Member
cmdlet에 파이핑하면 사용 가능한 속성 목록을 볼 수 있습니다.

오류의 원인을 확인하기 위해, 아래 명령을 사용하여 InvocationInfo
속성의 내용을 확인할 수 있습니다.

이제, 다른 속성들에 대해 동일한 작업을 수행하고 어떤 다른 정보를 찾을 수 있는지 알아볼 수 있습니다!
종료 오류
종료 오류는 PowerShell에서 실행 흐름을 중지시키는 오류입니다. 종료 오류가 발생하는 여러 가지 방법이 있습니다. 예를 들어, 존재하지 않는 매개변수를 사용하여 cmdlet을 호출할 때 종료 오류가 발생합니다.
아래 스크린샷에서 볼 수 있듯이, Get-Process notepad
명령이 실행되면 명령은 유효하며 notepad 프로세스의 세부 정보가 표시됩니다.

하지만 Get-Process notepad -handle 251
와 같이 존재하지 않는 매개변수를 사용하면, cmdlet은 handle
매개변수가 유효하지 않다는 오류를 표시합니다. 그런 다음, notepad
프로세스의 세부 정보를 표시하지 않고 cmdlet이 종료됩니다.

비종료 오류
비종료 오류는 스크립트나 명령의 실행을 중지시키지 않는 오류입니다. 예를 들어, 아래 코드를 살펴보십시오. 이 코드는 fileslist.txt 파일에서 파일 이름 목록을 가져옵니다. 그런 다음, 스크립트는 각 파일 이름을 확인하여 각 파일의 내용을 읽고 화면에 출력합니다.
filelist.txt 파일의 내용은 아래 목록에 표시된 파일 이름입니다.
하지만 File_6.log이 실제로 존재하지 않는다면 어떻게 될까요? 코드를 실행하면, 스크립트가 File_6.log을 찾을 수 없기 때문에 오류가 발생할 것으로 예상됩니다. 아래와 같은 유사한 출력을 볼 수 있습니다.

위의 결과 스크린샷에서 볼 수 있듯이, 스크립트는 목록에서 첫 다섯 개의 파일을 읽을 수 있었지만, 파일 File_6.txt을 읽으려고 할 때 오류가 발생합니다. 그런 다음 스크립트는 종료하기 전에 나머지 파일을 계속해서 읽습니다. 스크립트는 종료되지 않았습니다.
$ErrorActionPreference
변수
지금까지 종료되는 오류와 종료되지 않는 오류에 대해 배웠습니다. 그러나 종료되지 않는 오류를 종료되는 오류로 처리하도록 강제할 수 있다는 것을 알고 계셨나요?
PowerShell에는 p참조 변수라는 개념이 있습니다. 이러한 변수는 PowerShell의 동작을 다양한 방식으로 변경하는 데 사용됩니다. 이 변수 중 하나는 $ErrorActionPreference
입니다.
$ErrorActionPreference
변수는 PowerShell이 종료되지 않는 오류를 처리하는 방식을 변경하는 데 사용됩니다. 기본적으로 $ErrorActionPreference
값은 Continue
로 설정됩니다. $ErrorActionPreference
변수의 값을 STOP
으로 변경하면 PowerShell이 모든 오류를 종료되는 오류로 처리하도록 강제할 수 있습니다.
$ErrorActionPreference
값을 변경하려면 아래 코드를 사용하십시오.
다른 유효한 $ErrorActionPreference 변수 값에 대해 더 알아보려면 PowerShell ErrorActionPreference를 방문하십시오.
이제 이 문서의 비종료 오류 섹션에서 사용된 예제를 참조하십시오. 아래에 표시된 코드처럼 코드를 수정하여 $ErrorActionPreference
의 변경을 포함시킬 수 있습니다:
수정된 코드를 실행하면, $ErrorActionPreference
값이 기본값인 Continue
으로 설정되었을 때와는 다르게 동작합니다.

$ErrorActionPreference
variable위의 결과 스크린샷에서 볼 수 있듯이, 스크립트는 목록의 처음 다섯 개 파일을 읽을 수 있었지만, 파일 File_6.txt을 읽으려고 할 때 파일이 없어 오류가 반환됩니다. 그런 다음 스크립트가 종료되고 나머지 파일은 읽히지 않습니다.
$ErrorActionPreference
값은 현재 PowerShell 세션에서만 유효합니다. 새로운 PowerShell 세션을 시작하면 기본값으로 재설정됩니다.
ErrorAction
공통 매개변수
$ErrorActionPreference
값이 PowerShell 세션에 적용되면, ErrorAction
매개 변수는 공통 매개 변수를 지원하는 모든 cmdlet에 적용됩니다. ErrorAction
매개 변수는 $ErrorActionPreference
변수와 동일한 값을 허용합니다.
ErrorAction
매개 변수 값이 $ErrorActionPreference
값보다 우선합니다.
이전 예제에서와 같은 코드를 다시 사용해 보겠습니다. 하지만 이번에는 ErrorAction
매개 변수를 Get-Content
줄에 추가합니다.
수정한 코드를 실행한 후, $ErrorActionPreference
이 Continue
로 설정되었음에도 불구하고 스크립트가 오류를 만나면 종료되는 것을 확인할 수 있습니다. 스크립트가 PowerShell ErrorAction
매개 변수 값이 STOP
으로 설정된 Get-Content
때문에 종료되었습니다.

ErrorAction
parameterPowerShell Try Catch 블록 사용하기
이 시점에서 PowerShell 오류와 $ErrorActionPreference
변수 및 PowerShell ErrorAction
매개 변수의 동작 방식에 대해 배웠습니다. 이제 좋은 내용인 PowerShell Try Catch Finally
블록에 대해 알아보는 시간입니다.
PowerShell의 try catch
블록(및 선택적인 finally 블록
)은 코드 주위에 그물을 던져 오류를 잡는 방법입니다.
아래 코드는 Try
문의 구문을 보여줍니다.
Try
블록에는 PowerShell이 오류를 모니터링하고 처리하길 원하는 코드가 포함됩니다. Try
블록의 코드에서 오류가 발생하면 오류가 $Error
변수에 추가되고 Catch
블록으로 전달됩니다.
Catch
블록에는 Try
블록에서 오류를 받았을 때 실행할 동작이 포함됩니다. Try
문에는 여러 개의 Catch
블록이 있을 수 있습니다.
Finally
블록에는 Try
문의 끝에서 실행할 코드가 포함됩니다. 이 블록은 오류가 발생했든 발생하지 않았든 실행됩니다.
PowerShell ErrorAction을 사용하여 비구체적인 오류(전체 캐치) 잡기
A simple Try
statement contains a Try
and a Catch
block. The Finally
block is optional.
예를 들어, 비구체적인 예외를 잡기 위해 Catch
매개 변수를 비워둬야 합니다. 아래 예제 코드는 $ErrorActionPreference 변수 섹션에서 사용된 동일한 스크립트를 수정하여 Try Catch
블록을 사용합니다.
아래 코드에서 볼 수 있듯이 이번에는 foreach
문이 Try
블록으로 둘러싸여 있습니다. 그런 다음 Catch
블록에는 오류 발생 시 문자열 An Error Occurred
을 표시하는 코드가 포함됩니다. Finally
블록의 코드는 $Error
변수를 지웁니다.
PowerShell에서 위의 코드를 실행하면 아래에 표시된 출력이 나타납니다.

위의 출력은 스크립트가 오류를 발견하고 Catch
블록 내의 코드를 실행한 다음 종료되었음을 보여줍니다.
오류가 처리되었으며, 이것이 오류 처리의 목적이었습니다. 그러나 표시된 오류가 너무 일반적이었습니다. 더 구체적인 오류를 표시하려면, Try
블록에 의해 전달된 오류의 Exception
속성에 액세스할 수 있습니다.
아래의 코드는 수정되었으며, 특히 Catch
블록 내의 코드는 현재 오류로부터 전달된 예외 메시지를 표시하도록 수정되었습니다. – $PSItem.Exception.Message
이번에 수정된 코드를 실행하면, 표시되는 메시지가 훨씬 구체적입니다.

특정 오류 잡기
모든 오류를 처리하는 일반적인 접근 방식이 항상 가장 적절하지는 않습니다. 아마도 스크립트가 발견한 오류 유형에 따라 동작을 수행하려는 경우일 수 있습니다.
오류 유형을 어떻게 결정할까요? 마지막 오류의 Exception
속성의 TypeName
값을 확인하여 확인할 수 있습니다. 이전 예제에서 오류 유형을 찾으려면 다음 명령을 사용하십시오:
위의 코드의 결과는 아래 스크린샷과 같이 표시됩니다. 보시다시피, TypeName
값이 표시됩니다 – System.Management.Automation.ItemNotFoundException
.

이제 인터셉트해야하는 오류 유형을 알았으므로 코드를 특정하게 캐치하도록 수정합니다. 아래 수정된 코드에서 보시다시피, 이제 두 개의 Catch
블록이 있습니다. 첫 번째 Catch
블록은 특정 유형의 오류(System.Management.Automation.ItemNotFoundException
)를 인터셉트합니다. 반면에 두 번째 Catch
블록에는 일반적인 캐치-올 에러 메시지가 포함되어 있습니다.
아래 스크린샷은 위에서 수정된 코드의 출력을 보여줍니다.

결론
이 문서에서는 PowerShell의 오류에 대해, 그 속성에 대해, 그리고 오류의 특정 유형을 어떻게 확인할 수 있는지에 대해 배웠습니다. 또한 PowerShell의 $ErrorActionPreference
변수와 PowerShell ErrorAction
매개변수가 비종료 오류를 처리하는 방식에 대한 차이도 배웠습니다.
또한 PowerShell의 Try Catch Finally
블록을 사용하여 특정 오류나 캐치-올 접근 방식에 대한 오류 처리를 수행하는 방법도 배웠습니다.
이 문서에서 소개된 예제는 Try Catch Finally
블록의 기본 동작 방식을 보여주는 것에 불과합니다. 이 문서에서 얻은 지식은 스크립트에서 오류 처리를 적용하기 위한 기초를 제공할 것입니다.