about_Format.ps1xml

about_Format.ps1xml

PowerShell에서 객체를 어떻게 화면에 보여줄지는 기본적으로 소스 코드에 정의되어 있어요. 하지만 직접 Format.ps1xml 파일을 만들어서 표시 방식을 바꾸거나, 새로 만든 객체 타입의 기본 표시를 정해줄 수도 있답니다.

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

본문

짧은 설명 (Short description)

PowerShell 6부터는 객체의 기본 보기가 PowerShell 소스 코드 안에 정의되어 있어요.

직접 만든 Format.ps1xml 파일을 활용하면 객체가 보여지는 방식을 바꾸거나, PowerShell에서 새로 만든 객체 타입의 기본 표시를 정의할 수 있습니다.

자세한 설명 (Long description)

PowerShell 6부터는 기본 보기가 PowerShell 소스 코드에 정의되어 있어요. PowerShell 5.1 이하에 있던 Format.ps1xml 파일들은 PowerShell 6 이상에는 존재하지 않아요.

PowerShell 소스 코드는 PowerShell 콘솔에서 객체가 기본으로 어떻게 표시될지를 정의합니다. 여러분은 직접 Format.ps1xml 파일을 만들어 객체의 표시 방식을 바꾸거나, PowerShell에서 새로 만든 객체 타입의 기본 표시를 정의할 수 있어요.

PowerShell이 객체를 화면에 표시할 때, 구조화된 서식 파일에 담긴 데이터를 사용해서 기본 표시를 결정해요. 서식 파일의 데이터는 객체를 표(table)로 보여줄지 목록(list)으로 보여줄지를 결정하고, 기본적으로 어떤 속성을 보여줄지도 결정합니다.

이런 서식은 표시에만 영향을 줘요. 파이프라인으로 어떤 객체 속성이 내려가고 어떻게 전달되는지는 바꾸지 않아요. 그리고 Format.ps1xml 파일로 해시 테이블(hash table)의 출력 형식을 지정할 수는 없어요.

.ps1xml 서식 파일은 객체마다 네 가지 보기를 정의할 수 있어요.

  • Table
  • List
  • Wide
  • Custom

예를 들어 Get-ChildItem 명령의 출력을 Format-List 명령으로 파이프하면, Format-List는 소스 코드에 정의된 목록 보기를 사용해서 파일과 폴더 객체를 목록으로 보여줄지 결정해요.

서식 파일에 객체의 보기가 두 개 이상 있으면, PowerShell은 가장 먼저 찾은 보기를 적용합니다.

직접 만든 Format.ps1xml 파일에서 보기는 XML 태그들의 모음으로 정의돼요. 이 태그들은 보기의 이름, 적용할 객체 타입, 열 머리글, 그리고 보기 본문에 표시할 속성을 설명해요. Format.ps1xml 파일의 서식은 데이터가 사용자에게 보여지기 직전에 적용됩니다.

새 Format.ps1xml 파일 만들기

기존 객체 보기의 표시 형식을 바꾸거나, 새 객체에 보기를 추가하려면 직접 Format.ps1xml 파일을 만들어서 PowerShell 세션에 추가하면 돼요.

사용자 지정 보기를 정의하는 Format.ps1xml 파일을 만들려면 Get-FormatData cmdlet과 Export-FormatData cmdlet을 사용해요. 파일은 텍스트 편집기로 편집할 수 있고, PowerShell이 접근할 수 있는 아무 디렉터리(예: $HOME의 하위 디렉터리)에 저장하면 됩니다.

현재 보기의 서식을 바꾸려면 서식 파일에서 해당 보기를 찾아서 태그로 보기를 수정해요. 새 객체 타입의 보기를 만들 때는 새 보기를 만들거나 기존 보기를 모델로 삼아요. 태그에 대한 설명은 다음 절에 나와 있어요. 파일을 살펴보는 사람이 변경 사항을 바로 알 수 있도록 파일 안의 다른 보기들은 삭제해도 좋아요.

변경 내용을 저장한 다음에는 Update-FormatData로 새 파일을 PowerShell 세션에 추가해요. 내장 파일에 정의된 보기보다 여러분의 보기가 우선하길 원하면 PrependPath 매개 변수를 사용하면 됩니다. Update-FormatData는 현재 세션에만 영향을 줘요. 모든 이후 세션에 변경을 적용하려면 PowerShell 프로필에 Update-FormatData 명령을 추가해 두세요.

예제: culture 객체에 달력(calendar) 데이터 추가하기

이 예제는 현재 PowerShell 세션에서 Get-Culture cmdlet이 생성하는 System.Globalization.CultureInfo culture 객체의 서식을 바꾸는 방법을 보여줘요. 예제의 명령들은 culture 객체의 기본 표 보기에 Calendar 속성을 추가합니다.

먼저 소스 코드 파일에서 서식 데이터를 가져와서 culture 객체의 현재 보기가 담긴 Format.ps1xml 파일을 만들어요.

New-Item -Path $HOME\Format -ItemType Directory -Force

Get-FormatData -TypeName System.Globalization.CultureInfo |
  Export-FormatData -LiteralPath $HOME\Format\CultureInfo.Format.ps1xml

CultureInfo.Format.ps1xml 파일을 Visual Studio Code 같은 XML이나 텍스트 편집기로 열어요. 다음 XML이 CultureInfo 객체의 보기를 정의합니다.

CultureInfo.Format.ps1xml 파일은 다음과 같은 샘플과 비슷해야 해요.

<?xml version="1.0" encoding="utf-8"?>
<Configuration>
  <ViewDefinitions>
    <View>
      <Name>System.Globalization.CultureInfo</Name>
      <ViewSelectedBy>
        <TypeName>System.Globalization.CultureInfo</TypeName>
      </ViewSelectedBy>
      <TableControl>
        <TableHeaders>
          <TableColumnHeader>
            <Width>16</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>16</Width>
          </TableColumnHeader>
          <TableColumnHeader />
        </TableHeaders>
        <TableRowEntries>
          <TableRowEntry>
            <TableColumnItems>
              <TableColumnItem>
                <PropertyName>LCID</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Name</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>DisplayName</PropertyName>
              </TableColumnItem>
            </TableColumnItems>
          </TableRowEntry>
        </TableRowEntries>
      </TableControl>
    </View>
  </ViewDefinitions>
</Configuration>

Calendar 속성용 새 열을 만들려면 <TableColumnHeader> 태그를 새로 추가해요. Calendar 속성의 값은 길어질 수 있으니 <Width> 값으로 45자를 지정해요.

<TableHeaders>
  <TableColumnHeader>
    <Width>16</Width>
  </TableColumnHeader>
  <TableColumnHeader>
    <Width>16</Width>
  </TableColumnHeader>
  <TableColumnHeader>
    <Width>45</Width>
  </TableColumnHeader>
  <TableColumnHeader/>
</TableHeaders>

<TableColumnItem><PropertyName 태그를 사용해서 표 행에 Calendar용 열 항목을 새로 추가해요.

<TableRowEntries>
  <TableRowEntry>
    <TableColumnItems>
      <TableColumnItem>
        <PropertyName>LCID</PropertyName>
      </TableColumnItem>
      <TableColumnItem>
        <PropertyName>Name</PropertyName>
      </TableColumnItem>
      <TableColumnItem>
        <PropertyName>Calendar</PropertyName>
      </TableColumnItem>
      <TableColumnItem>
        <PropertyName>DisplayName</PropertyName>
      </TableColumnItem>
    </TableColumnItems>
  </TableRowEntry>
</TableRowEntries>

파일을 저장하고 닫아요. Update-FormatData로 새 서식 파일을 현재 PowerShell 세션에 추가해요.

이 예제는 PrependPath 매개 변수로 새 파일을 원래 파일보다 우선 순위가 높은 위치에 두고 있어요. 자세한 내용은 Update-FormatData를 참고하세요.

Update-FormatData -PrependPath $HOME\Format\CultureInfo.Format.ps1xml

변경 사항을 확인하려면 Get-Culture를 입력해서 Calendar 속성이 포함된 출력을 살펴봐요.

Get-Culture
LCID  Name   Calendar                                DisplayName
----  ----   --------                                -----------
1033  en-US  System.Globalization.GregorianCalendar  English (United States)

Format.ps1xml 파일의 XML

전체 스키마 정의는 GitHub의 PowerShell 소스 코드 저장소에 있는 Format.xsd에서 확인할 수 있어요.

Format.ps1xml 파일의 ViewDefinitions 섹션에는 각 보기를 정의하는 <View> 태그가 들어 있어요. 일반적인 <View> 태그는 다음과 같은 태그들을 포함합니다.

  • <Name> — 보기의 이름을 식별해요.
  • <ViewSelectedBy> — 보기가 적용되는 객체 타입을 지정해요.
  • <GroupBy> — 보기의 항목들을 그룹으로 묶는 방식을 지정해요.
  • <TableControl>, <ListControl>, <WideControl>, <CustomControl> — 각 항목을 어떻게 표시할지 지정하는 태그들을 담아요.

ViewSelectedBy 태그

<ViewSelectedBy> 태그는 보기가 적용되는 각 객체 타입마다 <TypeName> 태그를 포함할 수 있어요. 또는 <SelectionSetName> 태그를 포함해서 다른 곳에서 <SelectionSet> 태그로 정의한 선택 집합(selection set)을 참조할 수도 있어요.

GroupBy 태그

<GroupBy> 태그는 항목을 어떤 객체 속성으로 묶을지 지정하는 <PropertyName> 태그를 포함해요. 각 그룹의 라벨로 쓸 문자열을 지정하는 <Label> 태그나, 다른 곳에서 <Control> 태그로 정의한 사용자 지정 컨트롤을 참조하는 <CustomControlName> 태그도 함께 포함할 수 있어요. <Control> 태그는 <Name> 태그와 <CustomControl> 태그를 포함합니다.

TableControl 태그

<TableControl> 태그는 보통 표의 머리와 행 서식을 정의하는 <TableHeaders><TableRowEntries> 태그를 포함해요. <TableHeaders> 태그는 보통 <Label>, <Width>, <Alignment> 태그를 담은 <TableColumnHeader> 태그들을 포함합니다. <TableRowEntries> 태그는 표의 각 행마다 <TableRowEntry> 태그를 포함해요. <TableRowEntry> 태그는 해당 행의 각 열마다 <TableColumnItem> 태그를 담은 <TableColumnItem> 태그를 포함합니다. 보통 <TableColumnItem> 태그는 정해진 위치에 표시할 객체 속성을 식별하는 <PropertyName> 태그나, 그 위치에 표시할 결과를 계산하는 스크립트 코드를 담은 <ScriptBlock> 태그를 포함해요.

참고 계산된 결과가 유용한 다른 위치에서도 스크립트 블록을 쓸 수 있어요.

<TableColumnItem> 태그에는 속성이나 계산 결과를 어떻게 표시할지 지정하는 <FormatString> 태그도 포함할 수 있어요.

ListControl 태그

<ListControl> 태그는 보통 <ListEntries> 태그를 포함해요. <ListEntries> 태그는 <ListEntry> 태그를 포함하고, <ListEntry> 태그는 <ListItems> 태그를 포함해요. <ListItems> 태그는 <PropertyName> 태그를 담은 <ListItem> 태그들을 포함합니다. <PropertyName> 태그는 목록의 지정된 위치에 표시할 객체 속성을 지정해요. 보기 선택이 선택 집합으로 정의되면, <ListControl><ListEntry> 태그는 하나 이상의 <TypeName> 태그를 담은 <EntrySelectedBy> 태그도 포함할 수 있어요. 이런 <TypeName> 태그는 <ListControl> 태그가 표시하려는 객체 타입을 지정합니다.

WideControl 태그

<WideControl> 태그는 보통 <WideEntries> 태그를 포함해요. <WideEntries> 태그는 하나 이상의 <WideEntry> 태그를 포함하고, <WideEntry> 태그는 <WideItem> 태그 하나를 포함합니다.

<WideItem> 태그는 반드시 <PropertyName> 태그나 <ScriptBlock> 태그를 포함해야 해요. <PropertyName> 태그는 보기에서 지정된 위치에 표시할 속성을 지정하고, <ScriptBlock> 태그는 보기에서 지정된 위치에 평가해서 표시할 스크립트를 지정해요.

<WideItem> 태그에는 속성을 어떻게 표시할지 지정하는 <FormatString> 태그를 포함할 수 있어요.

CustomControl 태그

<CustomControl> 태그를 쓰면 스크립트 블록으로 서식을 정의할 수 있어요. <CustomControl> 태그는 보통 여러 <CustomEntry> 태그를 담은 <CustomEntries> 태그를 포함합니다. 각 <CustomEntry> 태그는 <CustomItem> 태그를 포함하는데, 여기에는 보기에서 지정된 위치의 내용과 서식을 지정하는 여러 태그(<Text>, <Indentation>, <ExpressionBinding>, <NewLine> 태그 등)를 담을 수 있어요.

Format.ps1xml 파일 사용 추적하기

Format.ps1xml 파일을 불러오거나 적용할 때 생기는 오류를 찾으려면, Trace-Command cmdlet을 사용하고 Name 매개 변수 값으로 다음 서식 구성 요소 중 하나를 지정해요.

  • FormatFileLoading
  • FormatViewBinding

자세한 내용은 Trace-CommandGet-TraceSource를 참고하세요.

Format.ps1xml 파일 서명하기

Format.ps1xml 파일을 사용하는 사람들을 보호하려면 디지털 서명으로 파일에 서명해야 해요. 자세한 내용은 about_Signing을 참고하세요.

Format-Table 사용자 지정 보기의 샘플 XML

다음 XML 샘플은 Get-ChildItem이 만드는 System.IO.DirectoryInfoSystem.IO.FileInfo 객체용 Format-Table 사용자 지정 보기를 만들어요. 이 사용자 지정 보기의 이름은 MyGciView이고, 표에 CreationTime 열을 추가합니다.

사용자 지정 보기를 만들려면 Get-FormatDataExport-FormatData cmdlet으로 .ps1xml 파일을 생성해요. 그런 다음 .ps1xml 파일을 편집해서 사용자 지정 보기 코드를 만들어요. .ps1xml 파일은 PowerShell이 접근할 수 있는 아무 디렉터리(예: $HOME의 하위 디렉터리)에 저장할 수 있어요.

.ps1xml 파일을 만든 후에는 Update-FormatData cmdlet으로 보기를 현재 PowerShell 세션에 포함시켜요. 또는 모든 PowerShell 세션에서 보기를 써야 한다면 업데이트 명령을 PowerShell 프로필에 추가해 두세요.

이 예제에서 사용자 지정 보기는 반드시 표(table) 형식을 사용해야 해요. 그렇지 않으면 Format-Table이 실패합니다.

Format-TableView 매개 변수와 함께 사용해서 사용자 지정 보기 이름인 MyGciView를 지정하고, CreationTime 열로 표의 출력을 서식화해요. 명령을 실행하는 예제는 Format-Table을 참고하세요.

참고 소스 코드에서 서식 XML을 가져와서 사용자 지정 보기를 만들 수는 있지만, 원하는 결과를 얻으려면 개발 작업이 더 필요할 수 있어요.

다음 Get-FormatData 명령에는 모든 로컬 서식 정보가 반환되도록 하는 PowerShellVersion 매개 변수의 대안이 있어요. 특정 PowerShell 버전 대신 -PowerShellVersion $PSVersionTable.PSVersion을 사용해요.

Get-FormatData -PowerShellVersion 5.1 -TypeName System.IO.DirectoryInfo |
   Export-FormatData -LiteralPath $HOME\Format\MyGciView.Format.ps1xml

Update-FormatData -AppendPath $HOME\Format\MyGciView.Format.ps1xml
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
  <ViewDefinitions>
    <View>
      <Name>MyGciView</Name>
      <ViewSelectedBy>
        <TypeName>System.IO.DirectoryInfo</TypeName>
        <TypeName>System.IO.FileInfo</TypeName>
      </ViewSelectedBy>
      <GroupBy>
        <PropertyName>PSParentPath</PropertyName>
      </GroupBy>
      <TableControl>
        <TableHeaders>
          <TableColumnHeader>
            <Label>Mode</Label>
            <Width>7</Width>
            <Alignment>Left</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>LastWriteTime</Label>
            <Width>26</Width>
            <Alignment>Right</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>CreationTime</Label>
            <Width>26</Width>
            <Alignment>Right</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>Length</Label>
            <Width>14</Width>
            <Alignment>Right</Alignment>
          </TableColumnHeader>
          <TableColumnHeader>
            <Label>Name</Label>
            <Alignment>Left</Alignment>
          </TableColumnHeader>
        </TableHeaders>
        <TableRowEntries>
          <TableRowEntry>
            <Wrap />
            <TableColumnItems>
              <TableColumnItem>
                <PropertyName>ModeWithoutHardLink</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>LastWriteTime</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>CreationTime</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Length</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Name</PropertyName>
              </TableColumnItem>
            </TableColumnItems>
          </TableRowEntry>
        </TableRowEntries>
      </TableControl>
    </View>
  </ViewDefinitions>
</Configuration>

더 알아보기