about_Experimental_Features

about_Experimental_Features

실험 기능(Experimental Feature)은 완성되지 않은 기능이에요. PowerShell이나 PowerShell 모듈 안에서, 아직 안정 버전이 확정되지 않은 기능도 기존 안정 기능과 나란히 공존할 수 있게 해주는 장치예요.

출처: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_experimental_features

본문

실험 기능은 설계가 확정되지 않은 기능이에요. 사용자가 직접 테스트해 보고 피드백을 줄 수 있도록 공개되어 있죠. 실험 기능이 최종 확정되는 순간, 그 설계 변경은 호환성을 깨는 변화(breaking change)로 취급돼요. 언제든 바뀔 수 있기 때문에 실험 기능은 프로덕션 환경에서 쓰라고 만든 게 아니에요.

실험 기능은 기본적으로 비활성화되어 있어요. 시스템 사용자나 관리자가 직접 켜 줘야 합니다.

켜 둔 실험 기능은 powershell.config.json 파일에 기록돼요. 모든 사용자에게 적용하려면 $PSHOME에 있는 시스템 설정 파일에 넣고, 특정 사용자에게만 적용하려면 해당 사용자 전용 설정 파일에 넣으면 됩니다.

Note 사용자 설정 파일에 적어 둔 실험 기능이 시스템 설정 파일에 적어 둔 것보다 우선 적용돼요.

Experimental 특성(attribute)

코드 일부가 실험 기능임을 선언하려면 Experimental 특성을 사용해요.

다음 문법으로 Experimental 특성을 선언하는데, 실험 기능의 이름과 해당 기능이 활성화됐을 때 어떤 동작을 할지를 지정해 줍니다.

[Experimental(NameOfExperimentalFeature, ExperimentAction)]

모듈의 경우 NameOfExperimentalFeature는 반드시 <modulename>.<experimentname> 형식이어야 해요. ExperimentAction 파라미터는 꼭 지정해야 하며, 유효한 값은 두 가지입니다.

  • Show — 실험 기능이 활성화되어 있으면 그 기능을 보여줘요.
  • Hide — 실험 기능이 활성화되어 있으면 그 기능을 숨겨줘요.

C#으로 작성한 모듈에서 실험 기능 선언하기

실험 기능 플래그를 쓰고 싶은 모듈 작성자는 Experimental 특성으로 cmdlet을 실험 기능으로 선언할 수 있어요.

[Experimental("MyWebCmdlets.PSWebCmdletV2", ExperimentAction.Show)]
[Cmdlet(Verbs.Invoke, "WebRequest")]
public class InvokeWebRequestCommandV2 : WebCmdletBaseV2 { ... }

PowerShell로 작성한 모듈에서 실험 기능 선언하기

PowerShell로 작성한 모듈도 Experimental 특성으로 실험 cmdlet을 선언할 수 있어요.

function Enable-SSHRemoting {
    [Experimental("MyRemoting.PSSSHRemoting", "Show")]
    [CmdletBinding()]
    param()
    ...
}

실험 기능에 대한 메타데이터는 모듈 매니페스트에 보관돼요. 모듈 매니페스트의 PrivateData.PSData.ExperimentalFeatures 속성을 이용해서 모듈의 실험 기능을 노출하면 됩니다. ExperimentalFeatures 속성은 기능의 이름과 설명을 담는 해시테이블 배열이에요.

예를 들면 이렇게요.

PrivateData = @{
  PSData = @{
    ExperimentalFeatures = @(
      @{
          Name = "PSWebCmdletV2"
          Description = "Rewrite the web cmdlets for better performance"
      },
      @{
          Name = "PSRestCmdletV2"
          Description = "Rewrite the REST API cmdlets for better performance"
      }
    )
  }
}

서로 배타적인 실험 기능

실험 기능이 기존 기능이나 다른 실험 기능과 나란히 공존할 수 없는 경우가 있어요.

예를 들어 어떤 실험 cmdlet이 기존 cmdlet을 덮어쓴다고 해볼게요. 두 버전은 동시에 공존할 수 없어요. ExperimentAction.Hide 설정을 쓰면 두 cmdlet 중 하나만 활성화되도록 제한할 수 있습니다.

이 예제에서는 새로운 실험용 Invoke-WebRequest cmdlet을 만들어요. InvokeWebRequestCommand에는 실험이 아닌 기존 구현이 들어 있고, InvokeWebRequestCommandV2에는 실험 버전이 들어 있어요.

ExperimentAction.Hide를 사용하면 두 기능 중 하나만 한 번에 켤 수 있게 됩니다.

[Experimental("MyWebCmdlets.PSWebCmdletV2", ExperimentAction.Show)]
[Cmdlet(Verbs.Invoke, "WebRequest")]
public class InvokeWebRequestCommandV2 : WebCmdletBaseV2 { ... }

[Experimental("MyWebCmdlets.PSWebCmdletV2", ExperimentAction.Hide)]
[Cmdlet(Verbs.Invoke, "WebRequest")]
public class InvokeWebRequestCommand : WebCmdletBase { ... }

MyWebCmdlets.PSWebCmdletV2 실험 기능이 켜지면 기존 InvokeWebRequestCommand 구현은 숨겨지고, InvokeWebRequestCommandV2Invoke-WebRequest의 구현을 담당해요.

이렇게 하면 사용자가 새 cmdlet을 먼저 써 보고 피드백을 준 다음, 필요할 때 다시 실험 전 버전으로 되돌릴 수 있어요.

cmdlet 안의 실험 파라미터

Experimental 특성은 개별 파라미터에도 적용할 수 있어요. 이러면 완전히 새로운 cmdlet을 만들지 않고도, 기존 cmdlet에 실험용 파라미터 묶음을 추가할 수 있죠.

C# 예제는 이렇습니다.

[Experimental("MyModule.PSNewAddTypeCompilation", ExperimentAction.Show)]
[Parameter(ParameterSet = "NewCompilation")]
public CompilationParameters CompileParameters { ... }

[Experimental("MyModule.PSNewAddTypeCompilation", ExperimentAction.Hide)]
[Parameter()]
public CodeDom CodeDom { ... }

PowerShell 스크립트에서는 조금 다른 모양으로 작성해요.

param(
    [Experimental("MyModule.PSNewFeature", "Show")]
    [string] $NewName,

    [Experimental("MyModule.PSNewFeature", "Hide")]
    [string] $OldName
)

실험 기능이 켜져 있는지 확인하기

코드에서 적절한 동작을 취하기 전에 실험 기능이 활성화되어 있는지 확인해야 할 때가 있어요. System.Management.Automation.ExperimentalFeature 클래스의 정적 IsEnabled() 메서드로 확인할 수 있습니다.

C# 예제요.

if (ExperimentalFeature.IsEnabled("MyModule.MyExperimentalFeature"))
{
   // code specific to the experimental feature
}

PowerShell 스크립트 예제입니다.

if ([ExperimentalFeature]::IsEnabled("MyModule.MyExperimentalFeature"))
{
  # code specific to the experimental feature
}

더 알아보기