타입 연산자

타입 연산자 (about_Type_Operators)

PowerShell에서 객체가 어떤 .NET 타입인지 확인하거나, 객체를 원하는 .NET 타입으로 바꾸고 싶을 때 쓰는 연산자가 있어요. 객체의 타입을 묻는 -is/-isnot, 그리고 변환을 시도하는 -as가 어떻게 다른지, 예시를 따라가며 하나씩 살펴볼게요.

출처: about_Type_Operators - PowerShell

본문

짧게 설명하면

이 문서는 Microsoft .NET 타입과 함께 동작하는 타입 연산자를 설명해요.

자세히 살펴보기

불리언 타입 연산자(-is, -isnot)는 객체가 지정한 .NET 타입의 인스턴스인지 알려줘요. -is는 타입이 일치하면 TRUE를, 일치하지 않으면 FALSE를 돌려주죠. -isnot은 그 반대로, 타입이 일치하면 FALSE를, 일치하지 않으면 TRUE를 돌려줘요.

-as 연산자는 입력 객체를 지정한 .NET 타입으로 변환하려고 시도해요. 성공하면 변환된 객체를 돌려주고, 실패하면 $null을 돌려줘요. 오류를 만들지는 않아요.

PowerShell이 지원하는 타입 연산자는 다음과 같아요.

  • -is | 입력이 지정한 .NET 타입의 인스턴스일 때 TRUE를 돌려줘요. (Get-Date) -is [datetime] # Result is True
  • -isnot | 입력이 지정한 .NET 타입의 인스턴스가 아닐 때 TRUE를 돌려줘요. (Get-Date) -isnot [datetime] # Result is False
  • -as | 입력을 지정한 .NET 타입으로 변환해요. "5/7/07" -as [datetime] # Result is Monday, May 7, 2007 12:00:00 AM

타입 연산자의 구문은 다음과 같아요.

<input> <operator> [.NET type]

다음과 같은 구문도 쓸 수 있어요.

<input> <operator> ".NET type"

.NET 타입은 대괄호로 감싼 타입 이름이나 문자열로 적어도 돼요. 예를 들어 System.DateTime을 나타낼 때 [datetime] 또는 "DateTime"처럼요. 타입이 시스템 네임스페이스의 루트에 있지 않으면 객체 타입의 전체 이름을 지정해야 해요. 단, System. 부분은 생략할 수 있어요. 예를 들어 System.Diagnostics.Process를 지정하려면 [System.Diagnostics.Process][Diagnostics.Process], 또는 "Diagnostics.Process"를 입력하면 돼요.

타입 연산자는 항상 입력 객체를 하나의 덩어리로 취급해요. 다시 말해 입력 객체가 컬렉션이라면, 컬렉션 요소들의 타입이 아니라 컬렉션 자체의 타입을 검사해요.

-is/isnot 연산자

불리언 타입 연산자(-is, -isnot)는 입력이 객체 컬렉션이어도 항상 불리언 값을 돌려줘요.

<input>이 지정한 .NET 타입과 같거나, 그 타입에서 파생된 타입이라면 -is 연산자는 $true를 돌려줘요.

예를 들어 DirectoryInfo 타입은 FileSystemInfo 타입에서 파생돼요. 그래서 아래 두 예시는 모두 True를 돌려줘요.

PS> (Get-Item /) -is [System.IO.DirectoryInfo]
True
PS> (Get-Item /) -is [System.IO.FileSystemInfo]
True

<input>이 비교 대상 인터페이스를 구현하고 있다면 -is 연산자는 인터페이스도 매칭할 수 있어요. 아래 예시에서 입력은 배열인데, 배열은 System.Collections.IList 인터페이스를 구현하죠.

PS> 1, 2 -is [System.Collections.IList]
True

-as 연산자

-as 연산자는 입력 객체를 지정한 .NET 타입으로 변환하려고 시도해요. 성공하면 변환된 객체를 돌려주고, 실패하면 $null을 돌려줘요. 오류를 만들지는 않아요.

<input>이 그 .NET 타입에서 파생된 타입이라면 -as는 입력 객체를 바꾸지 않고 그대로 통과시켜 돌려줘요. 예를 들어 DirectoryInfo 타입은 FileSystemInfo 타입에서 파생되므로, 아래 예시에서는 객체 타입이 그대로 남아요.

PS> $fsroot = (Get-Item /) -as [System.IO.FileSystemInfo]
PS> $fsroot.GetType().FullName
System.IO.DirectoryInfo

DateTime 타입 변환은 문화권에 민감해요

타입 캐스팅과 달리 -as 연산자로 [datetime] 타입으로 변환하는 건 현재 문화권의 규칙에 맞게 형식화된 문자열에서만 동작해요.

PS> [cultureinfo]::CurrentCulture = 'fr-FR'
PS> '13/5/20' -as [datetime]

mercredi 13 mai 2020 00:00:00

PS> '05/13/20' -as [datetime]
PS> [datetime]'05/13/20'

mercredi 13 mai 2020 00:00:00

PS> [datetime]'13/05/20'
InvalidArgument: Cannot convert value "13/05/20" to type "System.DateTime".
Error: "String '13/05/20' was not recognized as a valid DateTime."

객체의 .NET 타입을 찾으려면 Get-Member cmdlet을 쓰거나, 객체의 GetType 메서드를 FullName 속성과 함께 쓰면 돼요. 예를 들어 다음 문장은 Get-Culture 명령의 반환 값 타입을 가져와요.

PS> (Get-Culture).GetType().FullName
System.Globalization.CultureInfo

예시

다음 예시들은 타입 연산자의 몇 가지 쓰임을 보여줘요.

PS> 32 -is [float]
False

PS> 32 -is "int"
True

PS> (Get-Date) -is [datetime]
True

PS> "12/31/2007" -is [datetime]
False

PS> "12/31/2007" -is [string]
True

PS> (Get-Process powershell)[0] -is [System.Diagnostics.Process]
True

PS> (Get-Command Get-Member) -is [System.Management.Automation.CmdletInfo]
True

다음 예시는 입력이 객체 컬렉션일 때 매칭되는 타입이 컬렉션 안 개별 객체의 타입이 아니라, 컬렉션 자체의 .NET 타입이라는 걸 보여줘요.

이 예시에서 Get-Culture와 Get-UICulture cmdlet은 모두 System.Globalization.CultureInfo 객체를 돌려주는데, 이 객체들을 모은 컬렉션은 System.Object 배열이에요.

PS> (Get-Culture) -is [System.Globalization.CultureInfo]
True

PS> (Get-UICulture) -is [System.Globalization.CultureInfo]
True

PS> (Get-Culture), (Get-UICulture) -is [System.Globalization.CultureInfo]
False

PS> (Get-Culture), (Get-UICulture) -is [array]
True

PS> (Get-Culture), (Get-UICulture) | foreach {
  $_ -is [System.Globalization.CultureInfo])
}
True
True

PS> (Get-Culture), (Get-UICulture) -is [Object]
True

다음 예시들은 -as 연산자의 사용법을 보여줘요.

PS> "12/31/07" -is [datetime]
False

PS> "12/31/07" -as [datetime]
Monday, December 31, 2007 12:00:00 AM

PS> $date = "12/31/07" -as [datetime]

C:\PS>$a -is [datetime]
True

PS> 1031 -as [System.Globalization.CultureInfo]

LCID      Name      DisplayName
----      ----      -----------
1031      de-DE     German (Germany)

다음 예시는 -as 연산자가 입력 객체를 .NET 타입으로 변환하지 못할 때 $null을 돌려준다는 걸 보여줘요.

PS> 1031 -as [System.Diagnostics.Process]
PS>

더 알아보기

Microsoft Learn — about_Type_Operators