PowerShell은 객체 지향 언어입니다. 명령을 실행할 때 화면에 출력되는 것들은 객체입니다. 객체는 공중에서 생성되는 것이 아닙니다. 개발자가 이들을 생성하거나, 보다 구체적으로는 클래스를 사용하여 인스턴스화합니다. PowerShell 클래스는 이러한 객체의 정의 또는 스키마를 나타냅니다.
아마도 New-Object
와 같은 명령을 사용하여 객체를 생성하고 pscustomobject
유형 가속기를 사용하는 것에 익숙할 수 있습니다. 그러나 이러한 객체들은 “새로운” 객체가 아닙니다. 이러한 방법으로 생성되는 객체 유형은 특정한 유형입니다. PowerShell 클래스는 이러한 유형을 정의합니다.
이 튜토리얼에서는 PowerShell 클래스를 시작하는 방법을 배우게 될 것입니다. 생성자를 사용하여 첫 번째 클래스를 만들고, 클래스에서 객체를 생성하고, 속성과 메서드를 추가할 것입니다.
객체, 속성 및 메서드와 같은 용어에 대한 배경 지식은 블로그 글 기본 개념: PowerShell 객체 이해하기를 확인하십시오.
사전 준비 사항
첫 번째 클래스 및 객체 생성
PowerShell 클래스의 모든 내용을 배우기 전에, 먼저 간단한 클래스를 생성해 보아야 합니다. 더 고급 주제에 대해서는 나중에 배우게 될 것입니다.
첫 번째 클래스를 만드는 것은 함수를 만드는 것과 약간 비슷한 느낌이 있을 것입니다. 기본 구문은 동일합니다. 클래스는 함수와 같은 정의에서 생성됩니다. 그러나 함수와는 달리 첫 번째 줄은 함수 이름 앞에 function
이 아니라 객체 유형의 이름 뒤에 class
로 시작합니다.
아래에서는 student라는 클래스의 기본 구조만을 보여줍니다.
클래스에는 그 클래스를 설명하는 속성으로 보이는 매개변수가 있습니다. 아래 예제는 student라는 클래스를 보여주며, 두 개의 속성인 FirstName
과 LastName
이 있습니다.
속성을 정의할 때 속성 값이 어떤 “스키마”를 따를 수 있도록 특정 유형을 정의하는 것이 좋습니다. 아래 예제에서 두 속성은 모두 문자열로 정의되어 있습니다.
항상 속성 유형을 정의하는 것이 좋습니다. 나중에 그 이유를 알게 될 것입니다.
클래스를 정의한 후에는 해당 클래스에서 객체를 생성하거나 인스턴스화해야 합니다. 클래스에서 객체를 인스턴스화하는 여러 가지 방법이 있습니다. 그 중 일반적인 방법 중 하나는 [student]
와 같은 유형 가속기를 사용하는 것입니다. 이는 클래스를 나타내며, 이어서 모든 클래스에 기본적으로 제공되는 new()
라는 기본 메서드를 사용합니다.
유형 가속기를 사용하는 것은 New-Object
명령을 사용하여 객체를 생성하는 것과 동일합니다.
해당 클래스에서 개체를 만든 후에 속성에 값을 할당합니다. 아래 예시는 Tyler
와 Muir
값을 FirstName
과 LastName
속성에 할당하는 것입니다.
객체를 생성하고 속성에 값을 할당한 후에는 아래와 같이 객체를 할당한 변수를 호출하여 객체를 검사합니다.

클래스에서 객체를 생성했으므로, 해당 객체를 PowerShell에서 다른 객체처럼 파이핑하여 검사하기 위해 Get-Member
cmdlet을 사용할 수 있습니다. 아래 예시에서는 $student1
변수에 저장된 객체가 student 타입임을 확인할 수 있습니다.
클래스 이름은 항상 객체 유형과 일치합니다.
Get-Member
를 실행하면 네 개의 메서드와 두 개의 속성이 반환됩니다. 속성은 아마 익숙할 것이지만, 메서드는 익숙하지 않을 것입니다. PowerShell은 기본적으로 일부 메서드를 추가하지만, 직접 메서드를 추가하거나 기본 메서드를 수정할 수도 있습니다.

메서드 생성
위 예시에서는 객체에 기본 메서드 몇 개를 볼 수 있었지만, 아마도 직접 만들고 싶을 것입니다. 이를 위해 클래스 정의 내부에 하나 이상의 메서드를 정의해야 합니다.
A method definition looks like below with an output type that defines what type of object is returned from this method, the name of the method, and the code to execute inside of a scriptblock.
이름 뒤에 있는 괄호 ()
는 메서드 매개변수를 정의할 수 있는 위치입니다(나중에 다룰 예정입니다). 메서드 매개변수를 사용하면 함수 매개변수와 마찬가지로 메서드의 기능을 변경할 수 있습니다.
이전에 PowerShell 함수를 작성하고 실행한 적이 있다면 메서드 스크립트블록이 익숙할 것입니다. 그러나 메서드에는 알아야 할 몇 가지 특별한 규칙이 있습니다.
return
은 필수입니다
PowerShell 함수는 아래 예시처럼 함수 내의 어느 곳에든 객체를 배치함으로써 객체를 반환합니다.
그러나 함수와 달리 메서드가 객체를 반환하는 경우 아래와 같이 return
구문을 사용해야 합니다.
$this
변수 사용
메서드와 함수의 다른 점 중 하나는 $this
변수입니다. 메서드 내에서 정의된 $this
변수는 현재 객체의 속성이나 다른 메서드를 참조합니다.
아래는 FirstName
과 LastName
속성의 값을 연결하고 반환하는 GetName()
메서드가 student
클래스에 추가된 예시입니다.
이제 아래와 같이 점 표기법을 사용하여 GetName()
메서드를 호출할 수 있습니다. 이전에 FirstName
과 LastName
에 값을 할당한 경우, GetName()
은 그 값을 반환할 것입니다.

메서드에 매개변수 추가
위의 예시에서 $student1.GetName()
을 실행했을 때, GetName()
메서드를 그대로 호출한 것입니다. 괄호 내에서 함수와 마찬가지로 매개변수를 정의할 수 있습니다.
GetName()
메서드는 단지 FirstName
과 LastName
속성에 설정된 값들을 반환합니다. 그러나 만약 GetName()
이 사용하여 값을 가져올 수 있는 메서드를 설정하고 싶다면 어떨까요? 그런 경우에는 메서드 매개변수를 정의해야 합니다.
메서드의 매개변수 괄호 안에 쉼표로 구분된 하나 이상의 매개변수를 포함하여 메서드 매개변수를 정의합니다. 아래에 표시된 것처럼요.
[void]
출력 유형에 유의하세요. 메서드가 아무것도 출력하지 않을 때는return
구문이 필요하지 않으며, 메서드가 아무것도 반환하지 않음을 PowerShell에 알려주기 위해 출력 유형을[void]
로 정의해야 합니다.
예를 들어, SetName()
메서드가 전체 이름(이름과 성)을 받아들인다면, 스크립트 블록에서 이 문자열을 분할하여 이름과 성을 할당할 수 있습니다.
SetName()
메서드를 student
클래스에 삽입한 결과는 다음과 같습니다.
이제 전체 이름을 SetName()
메서드의 매개변수로 전달하여 현재 객체의 FirstName
과 LastName
속성을 설정할 수 있습니다.

메서드 오버로딩
아마도 메서드에 대해 다른 매개변수 세트를 정의하고 싶을 수 있습니다. 함수와 cmdlet에서 작동하는 것과 유사하게, 다른 매개변수 “컨텍스트” 또는 메서드 시그니처를 정의할 수 있습니다.
어쩌면 FirstName
과 LastName
매개변수를 SetName()
메소드에 전체 이름을 전달하거나, 이름과 성을 따로 전달하여 설정하고 싶을 수도 있습니다. 선택해야 할 필요는 없습니다. 메소드 시그니처를 사용하여 둘 다 정의할 수 있습니다.
클래스에서 여러 메소드 시그니처를 정의하는 것을 오버로딩이라고 합니다.
이전 섹션의 예제를 재사용하여, SetName()
메소드를 오버로딩하여 하나 대신 두 개의 문자열을 받도록 만들 수 있습니다. 하나 대신 두 개의 문자열을 전달하면, SetName()
메소드는 첫 번째 문자열을 FirstName
으로, 두 번째 문자열을 LastName
으로 가정합니다. 이 오버로드를 사용하면 아래와 같은 클래스가 됩니다.

클래스 생성자
new()
메소드나 다른 방법으로 객체를 인스턴스화할 때마다 PowerShell에게 생성자라는 사용자 정의 코드를 실행하도록 지시할 수 있습니다. 생성자는 메소드와 비슷하지만, PowerShell이 객체를 인스턴스화할 때 자동으로 실행됩니다.
모든 클래스에는 기본 생성자가 있습니다. 이 기본 생성자는 많은 일을 하지 않습니다. 객체를 인스턴스화하는 역할만 수행합니다. New
메소드의 출력을 확인하여 기본 생성자를 볼 수 있습니다. 아래의 예제에서는 하나의 new()
메소드를 반환합니다.

생성자 오버로딩
아마도 객체를 생성하는 즉시 FirstName
과 LastName
속성에 값을 설정하려는 것 같습니다. 일반적인 점 표기법이 아닌 매개변수를 사용하여 생성자를 만들고, 그 안에서 SetName()
을 호출할 수 있습니다.
아래는 student
클래스를 위한 생성자의 예입니다. 생성자는 특정한 이름이나 출력 유형을 가지지 않습니다. 생성자는 항상 클래스와 동일한 이름을 사용합니다.
생성자에서 기존 메서드를 호출함으로써, 이미 작성한 변수 설정을 재사용할 수 있습니다.
그리고 아래에서는 student
클래스에 생성자를 추가한 것을 볼 수 있습니다.
새로운 student
객체를 인스턴스화하고 문자열 매개변수를 전달하면, 객체 속성은 즉시 원하는 값으로 설정됩니다.

이제 [student]::New
와 함께 다시 오버로딩된 생성자를 볼 수 있습니다. 이제 Name
매개변수로 정의된 새로운 오버로딩된 생성자임에 유의하십시오.

기본 생성자와 오버로딩된 생성자 정의하기
이제 student
클래스에 오버로딩된 생성자가 있으므로, PowerShell은 기본 생성자를 덮어씁니다. 그러나 매개변수가 없는 기본 생성자를 수동으로 생성함으로써 다시 가져올 수 있습니다.
아래의 student
클래스에서 그 모습을 볼 수 있습니다.
이제 생성자를 다시 확인해보십시오. 이제 두 생성자가 모두 표시됩니다.

클래스 상속
모든 다른 객체지향 언어와 마찬가지로, PowerShell 클래스를 계층적으로 구성하여 여러 클래스를 만들 수 있습니다. 각 클래스는 “부모” 및 “자식” 클래스를 가질 수 있으며, 이는 더 구체적이고 일반적인 목적에서 시작하여 특수성을 높입니다.
예를 들어, 우리의 student
클래스는 대학생(자식/구체적)을 나타냅니다. 이 대학생은 사람(부모/일반적)입니다. 이 두 가지 개념은 관련이 있으며 계층을 형성합니다.
A child class can inherit a parent class which means it can hold all properties and methods (members) defined via a parent class. We know that a person
class may have properties like eye_color
, height
, and weight
and perhaps a method called SetHeight()
.
대학생이 사람이라면, 그 학생은 여전히 해당 속성과 메서드를 가지고 있습니다. student
클래스에 이미 person
클래스에 있는 동일한 멤버를 구현하는 것은 노력의 중복입니다. 클래스 상속을 정의하여 person
클래스의 모든 멤버를 자동으로 student
클래스에 정의할 수 있습니다.
지금은 이해되지 않더라도 데모를 진행하면 이해가 될 것입니다.
클래스 상속 데모
먼저, 이전에 생성한 student
클래스의 사본을 만들고, 생성자를 제거한 후, person
클래스로 이름을 변경합니다. 아래와 같이 person
클래스를 만듭니다.
A student, of course, has a first name and last name, but the class can be described more accurately by labeling it as a person. When creating a more “generic” class like this, you can create more specific “child” classes from it.
이제 더 구체적인 역할을 가진 사람을 나타내는 클래스 몇 개를 만듭니다. 예를 들어, 아래 코드 스니펫에서는 teacher
및 student
클래스를 가지게 됩니다.
현재로서는, teacher
및 student
클래스는 person
클래스와 상호 배타적입니다. 이들은 관계가 없으며, person
클래스의 어떠한 클래스 멤버도 상속받을 수 없습니다. 이를 변경해 보겠습니다.
이제 상속을 사용하여 ‘teacher’ 및 ‘student’ 클래스를 ‘person’ 클래스의 “child” 클래스로 정의하여 계층 구조를 정의하십시오. 아래와 같이 클래스 이름 뒤에 콜론(:)을 추가하고 상위 클래스의 이름을 붙여서 상속을 정의할 수 있습니다.
전체 클래스 스크립트는 다음과 같아야 합니다:
이 시점에서 ‘teacher’ 또는 ‘student’ 클래스에서 객체를 인스턴스화하면 ‘person’ 클래스와 동일한 멤버를 가지게 됩니다.

생성자를 상속받는 것
위에서 보았듯이 클래스 메서드는 클래스 상속을 통해 상속됩니다. 이 동작으로 인해 생성자도 동일한 로직을 따를 것으로 생각할 수 있지만, 그렇지 않습니다. 생성자는 상속되지 않으며, 모든 하위 클래스의 생성자는 각 하위 클래스에서 별도로 정의되어야 합니다.
예를 들어, ‘person’ 클래스에 오버로드된 생성자를 정의했지만 ‘teacher’ 클래스에는 생성자를 정의하지 않은 경우를 생각해 보겠습니다.
그런 다음 ‘teacher’와 같은 하위 클래스를 정의한 후, 아래와 같이 매개변수 없이 객체를 생성하려고 시도합니다. PowerShell은 ‘teacher’ 클래스 내에서 매개변수 없는 생성자가 정의되지 않았기 때문에 오류를 반환합니다.

A constructor is not necessary in a child class if you’re only using it as a template. Alternatively, if you want to use the parent class as its own standalone class and as a parent class you can include constructors. But you have to make sure that the parent class has a constructor that matches the ones in the child classes.
클래스 멤버 속성
PowerShell 명령 매개변수처럼 클래스에도 멤버 속성을 가질 수 있습니다. 이러한 속성은 각 멤버의 동작을 수정합니다.
숨겨진 멤버
클래스 멤버를 내부적인 용도로만 사용하고 사용자가 읽거나 쓸 수 없도록 하려면 멤버를 숨길 수 있습니다. 예를 들어, 다른 메서드에서만 사용되는 메서드가 있다면 해당 메서드를 사용자에게 노출할 필요가 없습니다.
숨겨진 멤버를 정의하려면 아래에 표시된대로 hidden
속성을 사용하십시오.
이제 Get-Member
를 사용하여 모든 객체 멤버를 검사할 때 해당 속성이 나타나지 않습니다.

클래스 멤버를 숨기면 값에 대한 접근이 제한되지 않습니다. 단지 값을 숨기는 것뿐입니다. 민감한 데이터를 저장하기 위해 속성을 숨기지 말아야 합니다.
정적 멤버
이 튜토리얼에서는 클래스에서 객체를 생성하는 것을 “인스턴스화”라고 설명했습니다. 객체를 인스턴스화하면 해당 객체는 클래스에서 정의한 모든 속성과 메서드를 가져옵니다. 그러나 항상 그렇지는 않습니다.
때로는 전체 객체를 인스턴스화하는 데 필요한 오버헤드가 필요하지 않을 수 있습니다. 대신에 단일 클래스 멤버를 빠르게 참조해야 하는 경우가 있습니다. 이 경우 클래스 멤버를 정적(static)으로 설정할 수 있습니다.
hidden
속성과 마찬가지로 아래에 표시된대로 static
키워드를 사용하여 클래스 멤버를 정적으로 정의하십시오.
일반적인 클래스 멤버와 달리 PowerShell은 정적 클래스 멤버에서 속성과 메서드를 생성하지 않습니다. 클래스 멤버를 정적으로 정의하면 숨겨진 멤버와 마찬가지로 Get-Member
를 사용할 때 나타나지 않습니다.

예를 들어, 대학 수업 이름을 student
클래스와 연결하고 학생이 참여할 수 있는 최대 대학 수업 수를 정의하고 싶을 수 있습니다. 이를 위해 Classes
배열 멤버와 MaxClassCount
멤버를 생성합니다.
사용자는 거의 MaxClassCount
멤버를 변경할 필요가 없으므로 정적으로 정의하기로 결정합니다.
마지막으로, AddClass()
메서드를 생성하여 학생의 일정에 수업을 추가하지만, MaxClassCount
보다 작을 경우에만 추가합니다.
이제 새로운 student
객체를 생성하고 그에게 너무 많은 대학 수업을 할당하려고 시도할 때, PowerShell은 최대 갯수인 7개만 할당합니다.

정적 멤버 값을 언제든지 변경할 수 있습니다. 예를 들어, 이 예제에서 제한을 초과하는 수업을 삭제하지 않고
MaxClassCount
멤버를 5로 변경하려면,[student]::MaxClassCount = 5
를 사용하여 값을 변경합니다.
결론
PowerShell 클래스는 스크립팅 언어와 프로그래밍 언어 사이의 경계를 흐리게 합니다. 클래스는 객체 간의 관계를 정의하고, 일반적으로 특수 함수를 작성해야만 가능한 객체와의 상호 작용 및 서식 지정 방법을 추가하는 데에 좋은 방법입니다.